Skip to content

Commit 7ddb97b

Browse files
committed
feat: Add Claude Code launch option and dependencies
1 parent 8bce5dd commit 7ddb97b

File tree

3 files changed

+59
-4
lines changed

3 files changed

+59
-4
lines changed

bun.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@
4343
"fetch-event-stream": "^0.1.5",
4444
"gpt-tokenizer": "^3.0.1",
4545
"hono": "^4.8.1",
46-
"srvx": "^0.8.0"
46+
"srvx": "^0.8.0",
47+
"tiny-invariant": "^1.3.3",
48+
"tinyexec": "^1.0.1"
4749
},
4850
"devDependencies": {
4951
"@echristian/eslint-config": "^0.0.43",

src/main.ts

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import { defineCommand, runMain } from "citty"
44
import consola from "consola"
55
import { serve, type ServerHandler } from "srvx"
6+
import invariant from "tiny-invariant"
7+
import { x } from "tinyexec"
68

79
import { auth } from "./auth"
810
import { cacheModels } from "./lib/models"
@@ -20,8 +22,11 @@ interface RunServerOptions {
2022
rateLimit?: number
2123
rateLimitWait: boolean
2224
githubToken?: string
25+
launchClaudeCode: boolean
26+
launchClaudeCodeDelay: number
2327
}
2428

29+
// eslint-disable-next-line max-lines-per-function
2530
export async function runServer(options: RunServerOptions): Promise<void> {
2631
if (options.verbose) {
2732
consola.level = 5
@@ -53,6 +58,39 @@ export async function runServer(options: RunServerOptions): Promise<void> {
5358
const serverUrl = `http://localhost:${options.port}`
5459
consola.box(`Server started at ${serverUrl}`)
5560

61+
if (options.launchClaudeCode) {
62+
invariant(state.models, "Models should be loaded by now")
63+
64+
const selectedModel = await consola.prompt(
65+
"Select a model to use with Claude Code",
66+
{
67+
type: "select",
68+
options: state.models.data.map((model) => model.id),
69+
},
70+
)
71+
72+
const selectedSmallModel = await consola.prompt(
73+
"Select a small model to use with Claude Code (https://docs.anthropic.com/en/docs/claude-code/costs#background-token-usage)",
74+
{
75+
type: "select",
76+
options: state.models.data.map((model) => model.id),
77+
},
78+
)
79+
80+
setTimeout(() => {
81+
x("claude", [], {
82+
nodeOptions: {
83+
env: {
84+
ANTHROPIC_BASE_URL: serverUrl,
85+
ANTHROPIC_AUTH_TOKEN: "dummy",
86+
ANTHROPIC_MODEL: selectedModel,
87+
ANTHROPIC_SMALL_FAST_MODEL: selectedSmallModel,
88+
},
89+
},
90+
})
91+
}, options.launchClaudeCodeDelay)
92+
}
93+
5694
serve({
5795
fetch: server.fetch as ServerHandler,
5896
port: options.port,
@@ -106,23 +144,34 @@ const start = defineCommand({
106144
description:
107145
"Provide GitHub token directly (must be generated using the `auth` subcommand)",
108146
},
147+
"claude-code": {
148+
alias: "c",
149+
type: "boolean",
150+
default: false,
151+
description: "Run Claude Code directly after starting the server",
152+
},
153+
"claude-code-delay": {
154+
type: "string",
155+
default: "1000",
156+
description: "Delay in milliseconds before running Claude Code",
157+
},
109158
},
110159
run({ args }) {
111160
const rateLimitRaw = args["rate-limit"]
112161
const rateLimit =
113162
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
114163
rateLimitRaw === undefined ? undefined : Number.parseInt(rateLimitRaw, 10)
115164

116-
const port = Number.parseInt(args.port, 10)
117-
118165
return runServer({
119-
port,
166+
port: Number.parseInt(args.port, 10),
120167
verbose: args.verbose,
121168
accountType: args["account-type"],
122169
manual: args.manual,
123170
rateLimit,
124171
rateLimitWait: Boolean(args.wait),
125172
githubToken: args["github-token"],
173+
launchClaudeCode: args["claude-code"],
174+
launchClaudeCodeDelay: Number.parseInt(args["claude-code-delay"], 10),
126175
})
127176
},
128177
})

0 commit comments

Comments
 (0)