workerdeck 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cli.mjs +18 -2
- package/build/cli.mjs.map +1 -1
- package/build/index.d.mts +3 -0
- package/build/index.mjs +1 -1
- package/build/{instance-DZ2r1RGc.mjs → instance-DyBeVgsK.mjs} +28 -3
- package/build/instance-DyBeVgsK.mjs.map +1 -0
- package/build/{reload-command-CnTDXayN.mjs → reload-command-BB_HdGxV.mjs} +2 -2
- package/build/{reload-command-CnTDXayN.mjs.map → reload-command-BB_HdGxV.mjs.map} +1 -1
- package/package.json +5 -5
- package/build/instance-DZ2r1RGc.mjs.map +0 -1
package/build/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as ConfigError, d as parseArgs, f as resolveInstanceConfig, r as startInstance, u as loadConfigFile } from "./instance-
|
|
2
|
+
import { a as ConfigError, d as parseArgs, f as resolveInstanceConfig, r as startInstance, u as loadConfigFile } from "./instance-DyBeVgsK.mjs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -105,6 +105,22 @@ Options
|
|
|
105
105
|
config: approvalTimeoutMs). Default 'none' - a prompt
|
|
106
106
|
waits as long as the session lives. A session may
|
|
107
107
|
override it per request.
|
|
108
|
+
--engine-sleep-after <d>
|
|
109
|
+
stop an idle session's engine process once no client
|
|
110
|
+
has watched it for this long (30m, 2h; config:
|
|
111
|
+
engineSleepAfterMs). The session stays listed and
|
|
112
|
+
wakes on its next message. Default 'never'.
|
|
113
|
+
--effort-default <model>=<effort>
|
|
114
|
+
reasoning effort a session starts at, or switches to,
|
|
115
|
+
on this model (opus=high, gpt-6-sol=xhigh; repeatable;
|
|
116
|
+
config: effortDefaults). A profile's defaults.efforts
|
|
117
|
+
wins per model. Default: the engine's own.
|
|
118
|
+
--agent-context-reset <on|off|never>
|
|
119
|
+
whether sessions get the context_reset tool, which
|
|
120
|
+
lets an agent clear its own conversation between turns
|
|
121
|
+
and continue from a prompt it wrote (config:
|
|
122
|
+
agentContextReset). A request or profile may turn it
|
|
123
|
+
on per session; 'never' forbids it. Default 'off'.
|
|
108
124
|
--state-dir <path> where parked sessions are persisted
|
|
109
125
|
(default: beside the config file, else ~/.workerdeck)
|
|
110
126
|
--no-parking-store keep parked sessions in memory only; a restart drops them
|
|
@@ -178,7 +194,7 @@ function line(text) {
|
|
|
178
194
|
}
|
|
179
195
|
async function main(argv) {
|
|
180
196
|
if (argv[0] === "reload") {
|
|
181
|
-
const { runReload } = await import("./reload-command-
|
|
197
|
+
const { runReload } = await import("./reload-command-BB_HdGxV.mjs");
|
|
182
198
|
return await runReload(argv.slice(1));
|
|
183
199
|
}
|
|
184
200
|
if (argv[0] === "relay") {
|
package/build/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/lib/shutdown.ts","../src/cli.ts"],"sourcesContent":["import type { Instance } from './instance.ts'\n\nexport type ShutdownOptions = {\n // A getter, not an instance: under --hot-reload the instance is replaced on every reload, and a captured one\n // would drain a server that stopped listening several generations ago.\n current: () => Instance\n // Runners this process holds outside any instance, which under --hot-reload is what a failed generation leaves\n // behind: no registry holds them, so `close()` cannot reach them and nothing else ends their engine children.\n alsoClose?: () => { close: (reason?: 'client' | 'server' | 'error') => void }[]\n log?: (text: string) => void\n}\n\nexport function installShutdown({\n current,\n alsoClose,\n log = (text) => void process.stdout.write(`${text}\\n`),\n}: ShutdownOptions): (signal: string) => void {\n // A second signal must always be able to kill a shutdown that is taking too long. That used to work only by\n // accident - the second call re-entered `instance.close()` and got an immediate callback out of an already-closed\n // http server - so it evaporated the moment close stopped being idempotent-by-luck. Make it a real path.\n let shuttingDown = false\n const shutdown = (signal: string): void => {\n if (shuttingDown) {\n process.stdout.write(`\\n[workerdeck] ${signal} again - terminating now\\n`)\n // Shell children are detached group leaders, so a plain exit orphans every one of them.\n current().server.shells?.killAllSync()\n process.exit(130)\n }\n shuttingDown = true\n log(`\\n[workerdeck] ${signal} - shutting down (press again to stop now)`)\n const instance = current()\n const running = instance.server.shells?.running() ?? []\n if (running.length > 0) {\n const named = running.map((shell) => `#${shell.ordinal} ${shell.label} (session ${shell.sessionId.slice(0, 8)})`).join(', ')\n log(`[workerdeck] ${running.length} shell(s) still running and will be stopped: ${named}`)\n }\n instance\n .drain({\n onProgress: (report) => {\n if (report.working.length > 0) {\n log(`[workerdeck] waiting for ${report.working.length} session(s) to finish the current turn`)\n }\n // Named, not waited for: nothing about shutting down answers a permission prompt.\n for (const id of report.awaitingHuman) {\n log(`[workerdeck] session ${id} is waiting on an approval - not waiting for it`)\n }\n if (report.timedOut) {\n log(`[workerdeck] ${report.working.length} session(s) still running - stopping anyway`)\n } else if (report.working.length === 0) {\n log('[workerdeck] all turns finished')\n }\n },\n })\n .catch(() => undefined)\n .then(() => instance.close())\n .then(() => {\n for (const runner of alsoClose?.() ?? []) {\n runner.close('server')\n }\n })\n .then(() => process.exit(0))\n .catch(() => process.exit(1))\n }\n process.on('SIGINT', () => shutdown('SIGINT'))\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n // Returned for the one caller that cannot rely on the signal: a raw-mode TTY delivers ctrl-c as a byte, not SIGINT.\n return shutdown\n}\n","#!/usr/bin/env node\nimport { spawn } from 'node:child_process'\nimport { readFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { ConfigError, loadConfigFile, parseArgs, resolveInstanceConfig } from './config.ts'\nimport { startInstance } from './lib/instance.ts'\nimport { installShutdown } from './lib/shutdown.ts'\n\nconst HELP = `workerdeck - run a workerdeck instance: session gateway + dashboard, one port.\n\nUsage\n workerdeck [options]\n workerdeck guard [options] check whether it is safe to restart an instance\n workerdeck reload [options] hot-reload a gateway started with --hot-reload\n workerdeck relay <command> run or manage a cross-gateway peer relay (relay --help)\n\nOptions\n -p, --port <n> port to listen on (default 8787, WORKERDECK_PORT)\n --host <addr> interface to bind (default 127.0.0.1, WORKERDECK_HOST)\n --auth-key <secret> shared secret, min 12 chars; browsers log in with it,\n services send it as x-workerdeck-key\n (WORKERDECK_AUTH_KEY). Unset = no auth on loopback;\n on any other interface a key is generated instead,\n printed once, and stored in <state-dir>/auth-key for\n later starts to reuse.\n --trust-proxy trust x-forwarded-proto/-host/-for from one reverse\n proxy. Required behind TLS termination, or the session\n cookie loses its Secure flag and the origin check\n computes http:// where the browser says https://.\n --allowed-origin <o> extra origin accepted on browser requests, for when a\n proxy rewrites Host (repeatable)\n --allowed-host <name> extra Host header accepted when running without auth\n (repeatable; loopback names are always accepted)\n --insecure-host <name>\n bind host that may serve without auth - no key demanded,\n none generated - and, while unauthenticated, also\n accepted as a Host header (repeatable; config:\n insecureHosts). Names the host alone, no port.\n --profile <name=dir> Claude config dir a session may run under (repeatable). Declared\n this way a profile is fixed: it cannot be changed over the API.\n --profile-root <path> directory a profile created at runtime may point its config dir at\n (repeatable; default: your home directory). Narrow this to pin\n exactly which credential stores the dashboard may reach for.\n --no-profile-store refuse runtime profile management entirely - /v1/profiles stays\n read-only and profiles come from --profile and the config file\n alone. Profiles created at runtime are stored in\n <state-dir>/profiles.json, so --no-parking-store implies this.\n --cwd-root <path> restrict session cwds to this root (repeatable,\n WORKERDECK_CWD_ROOTS as a ':'-separated list)\n --fs-root <path> narrow which host directories /v1/fs serves\n (repeatable, WORKERDECK_FS_ROOTS as a ':'-separated\n list). Reading otherwise follows --cwd-root: a caller\n who may start a session in a tree can already read it\n through the agent. With neither, the routes 404.\n --fs-write also accept writes over /v1/fs. Its own switch because\n an agent's writes go through the permission flow and a\n PUT does not. Every write is still conditional on the\n hash the client last read.\n --shell let an operator run '$' shell commands on the host from\n the composer, in the session's cwd. Every one is a PTY\n with a tracked record. Off by default and its own switch:\n unlike an agent's Bash tool, a '$' command goes through\n no permission prompt at all. Never offered to a scoped\n principal. The agent gets shell_list and shell_read.\n --shell-agent-write <mode>\n what the agent may do to shells of its own with --shell:\n read-only (default: it only reads), gated (shell_run,\n shell_write and shell_kill behind a permission card,\n payload shown; config: shell.agentWrite) or allow (no\n card beyond the engine's own mode). Never a shell the\n user started, never a session a scoped principal made.\n --approval-timeout <d>\n how long a permission prompt or a question may wait for\n an answer before the engine denies it (300000, 30s, 5m;\n config: approvalTimeoutMs). Default 'none' - a prompt\n waits as long as the session lives. A session may\n override it per request.\n --state-dir <path> where parked sessions are persisted\n (default: beside the config file, else ~/.workerdeck)\n --no-parking-store keep parked sessions in memory only; a restart drops them\n -c, --config <path> config file (default: ./workerdeck.config.mjs)\n --insecure allow no-auth on a non-loopback address. Only when\n something in front is doing the authenticating.\n --cors-origin <o> browser origin allowed to call /v1 cross-origin, for a\n dashboard served elsewhere (repeatable, exact origin, no\n wildcard; config: corsOrigins). Refused without auth. The\n key is still required - this only permits the call.\n --no-keep-awake don't hold the machine awake while a session is waiting\n on it (config: keepAwake: false). By default a turn in\n flight, or a session blocked on an approval, blocks idle\n sleep - a laptop sleeping mid-turn drops the socket and\n burns the turn. The screen is never kept on, and the\n lock releases the moment nothing is waiting.\n --no-web don't serve the web dashboard (config: web: false).\n /v1 and the auth routes are unchanged; everything else\n 404s. For a gateway reached only from the VS Code\n extension, the phone, or another host's dashboard.\n --open open the dashboard in a browser once it is up\n --hot-reload dev only: re-evaluate the gateway's own source in place on\n ctrl-r, SIGUSR2 or \\`workerdeck reload\\`, carrying live\n sessions and their engine child processes across the swap.\n Needs a source checkout; the published CLI is one bundled\n file with nothing to swap.\n -h, --help show this\n -v, --version print the version\n\nConfig file\n Options that cannot fit on a command line - \\`authenticate\\`, \\`buildRunnerConfig\\`,\n \\`createEngineRunner\\` are functions - live in workerdeck.config.mjs, which\n default-exports the createWorkerServer options (or a function returning them).\n Flags and env override it. Supplying your own \\`authenticate\\` turns the built-in\n shared-secret auth off entirely.\n\nCredentials\n workerdeck implements no Anthropic auth of its own: the official SDK/CLI\n resolves credentials from the environment, per profile. --auth-key protects this\n gateway, nothing else.\n`\n\nasync function readVersion(): Promise<string> {\n // src/cli.ts and build/cli.mjs are both one level under the package root.\n const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json')\n try {\n const raw = await readFile(pkgPath, 'utf8')\n return (JSON.parse(raw) as { version?: string }).version ?? 'unknown'\n } catch {\n return 'unknown'\n }\n}\n\nfunction openInBrowser(url: string): void {\n const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n try {\n const child = spawn(command, [url], {\n stdio: 'ignore',\n detached: true,\n shell: process.platform === 'win32',\n })\n child.on('error', () => {})\n child.unref()\n } catch {}\n}\n\n// Read once and removed: every process this one spawns (engines, shells, the browser opener) inherits `process.env`.\nfunction takeGatewayEnv(): NodeJS.ProcessEnv {\n const env = { ...process.env }\n delete process.env.WORKERDECK_AUTH_KEY\n delete process.env.WORKERDECK_RELAY_KEY\n return env\n}\n\nfunction line(text: string): void {\n process.stdout.write(`${text}\\n`)\n}\n\nasync function main(argv: string[]): Promise<number> {\n if (argv[0] === 'reload') {\n const { runReload } = await import('./dev/reload-command.ts')\n return await runReload(argv.slice(1))\n }\n\n if (argv[0] === 'relay') {\n const { runRelayCli } = await import('@workerdeck/relay')\n return await runRelayCli(argv.slice(1))\n }\n\n if (argv[0] === 'guard') {\n const { runGuard } = await import('./lib/guard.ts')\n return await runGuard(argv.slice(1))\n }\n\n const env = takeGatewayEnv()\n const flags = parseArgs(argv)\n if (flags.help) {\n process.stdout.write(HELP)\n return 0\n }\n if (flags.version) {\n process.stdout.write(`${await readVersion()}\\n`)\n return 0\n }\n\n if (flags.hotReload) {\n const { runHotReload } = await import('./dev/hot-reload.ts')\n const result = await runHotReload(flags, env)\n if (result !== 'unsupported') {\n return result\n }\n }\n\n const loaded = await loadConfigFile(flags.config)\n const config = resolveInstanceConfig(flags, loaded, env)\n const instance = await startInstance(config)\n\n if (config.open) {\n openInBrowser(instance.url)\n }\n\n installShutdown({ current: () => instance, log: line })\n\n // Resolves only on close: until then the process stays up, serving.\n await instance.closed\n return 0\n}\n\nmain(process.argv.slice(2))\n .then((code) => {\n if (code !== 0) {\n process.exit(code)\n }\n })\n .catch((error: unknown) => {\n if (error instanceof ConfigError) {\n process.stderr.write(`[workerdeck] ${error.message}\\n`)\n process.exit(2)\n }\n process.stderr.write(`[workerdeck] ${error instanceof Error ? (error.stack ?? error.message) : String(error)}\\n`)\n process.exit(1)\n })\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/lib/shutdown.ts","../src/cli.ts"],"sourcesContent":["import type { Instance } from './instance.ts'\n\nexport type ShutdownOptions = {\n // A getter, not an instance: under --hot-reload the instance is replaced on every reload, and a captured one\n // would drain a server that stopped listening several generations ago.\n current: () => Instance\n // Runners this process holds outside any instance, which under --hot-reload is what a failed generation leaves\n // behind: no registry holds them, so `close()` cannot reach them and nothing else ends their engine children.\n alsoClose?: () => { close: (reason?: 'client' | 'server' | 'error') => void }[]\n log?: (text: string) => void\n}\n\nexport function installShutdown({\n current,\n alsoClose,\n log = (text) => void process.stdout.write(`${text}\\n`),\n}: ShutdownOptions): (signal: string) => void {\n // A second signal must always be able to kill a shutdown that is taking too long. That used to work only by\n // accident - the second call re-entered `instance.close()` and got an immediate callback out of an already-closed\n // http server - so it evaporated the moment close stopped being idempotent-by-luck. Make it a real path.\n let shuttingDown = false\n const shutdown = (signal: string): void => {\n if (shuttingDown) {\n process.stdout.write(`\\n[workerdeck] ${signal} again - terminating now\\n`)\n // Shell children are detached group leaders, so a plain exit orphans every one of them.\n current().server.shells?.killAllSync()\n process.exit(130)\n }\n shuttingDown = true\n log(`\\n[workerdeck] ${signal} - shutting down (press again to stop now)`)\n const instance = current()\n const running = instance.server.shells?.running() ?? []\n if (running.length > 0) {\n const named = running.map((shell) => `#${shell.ordinal} ${shell.label} (session ${shell.sessionId.slice(0, 8)})`).join(', ')\n log(`[workerdeck] ${running.length} shell(s) still running and will be stopped: ${named}`)\n }\n instance\n .drain({\n onProgress: (report) => {\n if (report.working.length > 0) {\n log(`[workerdeck] waiting for ${report.working.length} session(s) to finish the current turn`)\n }\n // Named, not waited for: nothing about shutting down answers a permission prompt.\n for (const id of report.awaitingHuman) {\n log(`[workerdeck] session ${id} is waiting on an approval - not waiting for it`)\n }\n if (report.timedOut) {\n log(`[workerdeck] ${report.working.length} session(s) still running - stopping anyway`)\n } else if (report.working.length === 0) {\n log('[workerdeck] all turns finished')\n }\n },\n })\n .catch(() => undefined)\n .then(() => instance.close())\n .then(() => {\n for (const runner of alsoClose?.() ?? []) {\n runner.close('server')\n }\n })\n .then(() => process.exit(0))\n .catch(() => process.exit(1))\n }\n process.on('SIGINT', () => shutdown('SIGINT'))\n process.on('SIGTERM', () => shutdown('SIGTERM'))\n // Returned for the one caller that cannot rely on the signal: a raw-mode TTY delivers ctrl-c as a byte, not SIGINT.\n return shutdown\n}\n","#!/usr/bin/env node\nimport { spawn } from 'node:child_process'\nimport { readFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { ConfigError, loadConfigFile, parseArgs, resolveInstanceConfig } from './config.ts'\nimport { startInstance } from './lib/instance.ts'\nimport { installShutdown } from './lib/shutdown.ts'\n\nconst HELP = `workerdeck - run a workerdeck instance: session gateway + dashboard, one port.\n\nUsage\n workerdeck [options]\n workerdeck guard [options] check whether it is safe to restart an instance\n workerdeck reload [options] hot-reload a gateway started with --hot-reload\n workerdeck relay <command> run or manage a cross-gateway peer relay (relay --help)\n\nOptions\n -p, --port <n> port to listen on (default 8787, WORKERDECK_PORT)\n --host <addr> interface to bind (default 127.0.0.1, WORKERDECK_HOST)\n --auth-key <secret> shared secret, min 12 chars; browsers log in with it,\n services send it as x-workerdeck-key\n (WORKERDECK_AUTH_KEY). Unset = no auth on loopback;\n on any other interface a key is generated instead,\n printed once, and stored in <state-dir>/auth-key for\n later starts to reuse.\n --trust-proxy trust x-forwarded-proto/-host/-for from one reverse\n proxy. Required behind TLS termination, or the session\n cookie loses its Secure flag and the origin check\n computes http:// where the browser says https://.\n --allowed-origin <o> extra origin accepted on browser requests, for when a\n proxy rewrites Host (repeatable)\n --allowed-host <name> extra Host header accepted when running without auth\n (repeatable; loopback names are always accepted)\n --insecure-host <name>\n bind host that may serve without auth - no key demanded,\n none generated - and, while unauthenticated, also\n accepted as a Host header (repeatable; config:\n insecureHosts). Names the host alone, no port.\n --profile <name=dir> Claude config dir a session may run under (repeatable). Declared\n this way a profile is fixed: it cannot be changed over the API.\n --profile-root <path> directory a profile created at runtime may point its config dir at\n (repeatable; default: your home directory). Narrow this to pin\n exactly which credential stores the dashboard may reach for.\n --no-profile-store refuse runtime profile management entirely - /v1/profiles stays\n read-only and profiles come from --profile and the config file\n alone. Profiles created at runtime are stored in\n <state-dir>/profiles.json, so --no-parking-store implies this.\n --cwd-root <path> restrict session cwds to this root (repeatable,\n WORKERDECK_CWD_ROOTS as a ':'-separated list)\n --fs-root <path> narrow which host directories /v1/fs serves\n (repeatable, WORKERDECK_FS_ROOTS as a ':'-separated\n list). Reading otherwise follows --cwd-root: a caller\n who may start a session in a tree can already read it\n through the agent. With neither, the routes 404.\n --fs-write also accept writes over /v1/fs. Its own switch because\n an agent's writes go through the permission flow and a\n PUT does not. Every write is still conditional on the\n hash the client last read.\n --shell let an operator run '$' shell commands on the host from\n the composer, in the session's cwd. Every one is a PTY\n with a tracked record. Off by default and its own switch:\n unlike an agent's Bash tool, a '$' command goes through\n no permission prompt at all. Never offered to a scoped\n principal. The agent gets shell_list and shell_read.\n --shell-agent-write <mode>\n what the agent may do to shells of its own with --shell:\n read-only (default: it only reads), gated (shell_run,\n shell_write and shell_kill behind a permission card,\n payload shown; config: shell.agentWrite) or allow (no\n card beyond the engine's own mode). Never a shell the\n user started, never a session a scoped principal made.\n --approval-timeout <d>\n how long a permission prompt or a question may wait for\n an answer before the engine denies it (300000, 30s, 5m;\n config: approvalTimeoutMs). Default 'none' - a prompt\n waits as long as the session lives. A session may\n override it per request.\n --engine-sleep-after <d>\n stop an idle session's engine process once no client\n has watched it for this long (30m, 2h; config:\n engineSleepAfterMs). The session stays listed and\n wakes on its next message. Default 'never'.\n --effort-default <model>=<effort>\n reasoning effort a session starts at, or switches to,\n on this model (opus=high, gpt-6-sol=xhigh; repeatable;\n config: effortDefaults). A profile's defaults.efforts\n wins per model. Default: the engine's own.\n --agent-context-reset <on|off|never>\n whether sessions get the context_reset tool, which\n lets an agent clear its own conversation between turns\n and continue from a prompt it wrote (config:\n agentContextReset). A request or profile may turn it\n on per session; 'never' forbids it. Default 'off'.\n --state-dir <path> where parked sessions are persisted\n (default: beside the config file, else ~/.workerdeck)\n --no-parking-store keep parked sessions in memory only; a restart drops them\n -c, --config <path> config file (default: ./workerdeck.config.mjs)\n --insecure allow no-auth on a non-loopback address. Only when\n something in front is doing the authenticating.\n --cors-origin <o> browser origin allowed to call /v1 cross-origin, for a\n dashboard served elsewhere (repeatable, exact origin, no\n wildcard; config: corsOrigins). Refused without auth. The\n key is still required - this only permits the call.\n --no-keep-awake don't hold the machine awake while a session is waiting\n on it (config: keepAwake: false). By default a turn in\n flight, or a session blocked on an approval, blocks idle\n sleep - a laptop sleeping mid-turn drops the socket and\n burns the turn. The screen is never kept on, and the\n lock releases the moment nothing is waiting.\n --no-web don't serve the web dashboard (config: web: false).\n /v1 and the auth routes are unchanged; everything else\n 404s. For a gateway reached only from the VS Code\n extension, the phone, or another host's dashboard.\n --open open the dashboard in a browser once it is up\n --hot-reload dev only: re-evaluate the gateway's own source in place on\n ctrl-r, SIGUSR2 or \\`workerdeck reload\\`, carrying live\n sessions and their engine child processes across the swap.\n Needs a source checkout; the published CLI is one bundled\n file with nothing to swap.\n -h, --help show this\n -v, --version print the version\n\nConfig file\n Options that cannot fit on a command line - \\`authenticate\\`, \\`buildRunnerConfig\\`,\n \\`createEngineRunner\\` are functions - live in workerdeck.config.mjs, which\n default-exports the createWorkerServer options (or a function returning them).\n Flags and env override it. Supplying your own \\`authenticate\\` turns the built-in\n shared-secret auth off entirely.\n\nCredentials\n workerdeck implements no Anthropic auth of its own: the official SDK/CLI\n resolves credentials from the environment, per profile. --auth-key protects this\n gateway, nothing else.\n`\n\nasync function readVersion(): Promise<string> {\n // src/cli.ts and build/cli.mjs are both one level under the package root.\n const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json')\n try {\n const raw = await readFile(pkgPath, 'utf8')\n return (JSON.parse(raw) as { version?: string }).version ?? 'unknown'\n } catch {\n return 'unknown'\n }\n}\n\nfunction openInBrowser(url: string): void {\n const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'\n try {\n const child = spawn(command, [url], {\n stdio: 'ignore',\n detached: true,\n shell: process.platform === 'win32',\n })\n child.on('error', () => {})\n child.unref()\n } catch {}\n}\n\n// Read once and removed: every process this one spawns (engines, shells, the browser opener) inherits `process.env`.\nfunction takeGatewayEnv(): NodeJS.ProcessEnv {\n const env = { ...process.env }\n delete process.env.WORKERDECK_AUTH_KEY\n delete process.env.WORKERDECK_RELAY_KEY\n return env\n}\n\nfunction line(text: string): void {\n process.stdout.write(`${text}\\n`)\n}\n\nasync function main(argv: string[]): Promise<number> {\n if (argv[0] === 'reload') {\n const { runReload } = await import('./dev/reload-command.ts')\n return await runReload(argv.slice(1))\n }\n\n if (argv[0] === 'relay') {\n const { runRelayCli } = await import('@workerdeck/relay')\n return await runRelayCli(argv.slice(1))\n }\n\n if (argv[0] === 'guard') {\n const { runGuard } = await import('./lib/guard.ts')\n return await runGuard(argv.slice(1))\n }\n\n const env = takeGatewayEnv()\n const flags = parseArgs(argv)\n if (flags.help) {\n process.stdout.write(HELP)\n return 0\n }\n if (flags.version) {\n process.stdout.write(`${await readVersion()}\\n`)\n return 0\n }\n\n if (flags.hotReload) {\n const { runHotReload } = await import('./dev/hot-reload.ts')\n const result = await runHotReload(flags, env)\n if (result !== 'unsupported') {\n return result\n }\n }\n\n const loaded = await loadConfigFile(flags.config)\n const config = resolveInstanceConfig(flags, loaded, env)\n const instance = await startInstance(config)\n\n if (config.open) {\n openInBrowser(instance.url)\n }\n\n installShutdown({ current: () => instance, log: line })\n\n // Resolves only on close: until then the process stays up, serving.\n await instance.closed\n return 0\n}\n\nmain(process.argv.slice(2))\n .then((code) => {\n if (code !== 0) {\n process.exit(code)\n }\n })\n .catch((error: unknown) => {\n if (error instanceof ConfigError) {\n process.stderr.write(`[workerdeck] ${error.message}\\n`)\n process.exit(2)\n }\n process.stderr.write(`[workerdeck] ${error instanceof Error ? (error.stack ?? error.message) : String(error)}\\n`)\n process.exit(1)\n })\n"],"mappings":"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"}
|
package/build/index.d.mts
CHANGED
|
@@ -123,6 +123,9 @@ type CliFlags = {
|
|
|
123
123
|
insecureHosts: string[];
|
|
124
124
|
trustProxy?: boolean;
|
|
125
125
|
approvalTimeoutMs?: number | null;
|
|
126
|
+
engineSleepAfterMs?: number;
|
|
127
|
+
effortDefaults?: Record<string, string>;
|
|
128
|
+
agentContextReset?: 'on' | 'off' | 'never';
|
|
126
129
|
stateDir?: string;
|
|
127
130
|
parking?: boolean;
|
|
128
131
|
insecure?: boolean;
|
package/build/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { n as runGuard } from "./guard-C4ybpzbt.mjs";
|
|
2
|
-
import { C as createActivityRegistry, S as createDeviceRoute, _ as createApnsForwarder, a as ConfigError, b as createApnsRoute, c as isLoopback, d as parseArgs, f as resolveInstanceConfig, g as buildPush, h as materializeAuthKey, i as renderLoginPage, l as isLoopbackHostname, m as createAuthSessionStore, n as resolveWebRoot, o as defaultStateDir, p as createCliAuth, r as startInstance, s as hostnameOf, t as createHostGuard, u as loadConfigFile, v as createApnsClient, w as createActivityRoute, x as createDeviceRegistry, y as loadApnsKey } from "./instance-
|
|
2
|
+
import { C as createActivityRegistry, S as createDeviceRoute, _ as createApnsForwarder, a as ConfigError, b as createApnsRoute, c as isLoopback, d as parseArgs, f as resolveInstanceConfig, g as buildPush, h as materializeAuthKey, i as renderLoginPage, l as isLoopbackHostname, m as createAuthSessionStore, n as resolveWebRoot, o as defaultStateDir, p as createCliAuth, r as startInstance, s as hostnameOf, t as createHostGuard, u as loadConfigFile, v as createApnsClient, w as createActivityRoute, x as createDeviceRegistry, y as loadApnsKey } from "./instance-DyBeVgsK.mjs";
|
|
3
3
|
export { ConfigError, buildPush, createActivityRegistry, createActivityRoute, createApnsClient, createApnsForwarder, createApnsRoute, createAuthSessionStore, createCliAuth, createDeviceRegistry, createDeviceRoute, createHostGuard, defaultStateDir, hostnameOf, isLoopback, isLoopbackHostname, loadApnsKey, loadConfigFile, materializeAuthKey, parseArgs, renderLoginPage, resolveInstanceConfig, resolveWebRoot, runGuard, startInstance };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createReadStream, existsSync } from "node:fs";
|
|
1
|
+
import { createReadStream, existsSync, statSync } from "node:fs";
|
|
2
2
|
import { dirname, isAbsolute, join, resolve, sep } from "node:path";
|
|
3
3
|
import { createFileProfileStore, createFileSessionStore, createFileSpendStore, createWorkerServer, readJsonOr, writeJsonAtomic } from "@workerdeck/server";
|
|
4
4
|
import { dashboardDir } from "@workerdeck/web";
|
|
@@ -1767,6 +1767,12 @@ const VALUED = /* @__PURE__ */ new Map([
|
|
|
1767
1767
|
["--allowed-host", (f, v) => f.allowedHosts.push(v)],
|
|
1768
1768
|
["--insecure-host", (f, v) => f.insecureHosts.push(v)],
|
|
1769
1769
|
["--approval-timeout", (f, v, name) => f.approvalTimeoutMs = parseDuration(v, name)],
|
|
1770
|
+
["--engine-sleep-after", (f, v, name) => f.engineSleepAfterMs = parseDuration(v, name) ?? 0],
|
|
1771
|
+
["--effort-default", (f, v, name) => f.effortDefaults = {
|
|
1772
|
+
...f.effortDefaults,
|
|
1773
|
+
...parseEffortDefault(v, name)
|
|
1774
|
+
}],
|
|
1775
|
+
["--agent-context-reset", (f, v, name) => f.agentContextReset = parseAgentContextReset(v, name)],
|
|
1770
1776
|
["--state-dir", (f, v) => f.stateDir = resolve(v)],
|
|
1771
1777
|
["--cors-origin", (f, v) => f.corsOrigins.push(v)]
|
|
1772
1778
|
]);
|
|
@@ -1783,6 +1789,15 @@ function parseDuration(raw, source) {
|
|
|
1783
1789
|
const ms = Number(match[1]) * scale;
|
|
1784
1790
|
return ms > 0 ? ms : null;
|
|
1785
1791
|
}
|
|
1792
|
+
function parseEffortDefault(raw, source) {
|
|
1793
|
+
const match = /^([^=\s]+)=([^=\s]+)$/.exec(raw);
|
|
1794
|
+
if (!match) throw new ConfigError(`${source}: expected <model>=<effort>, like opus=high; got: ${raw}`);
|
|
1795
|
+
return { [match[1]]: match[2] };
|
|
1796
|
+
}
|
|
1797
|
+
function parseAgentContextReset(raw, source) {
|
|
1798
|
+
if (raw === "on" || raw === "off" || raw === "never") return raw;
|
|
1799
|
+
throw new ConfigError(`${source}: expected on, off or never; got: ${raw}`);
|
|
1800
|
+
}
|
|
1786
1801
|
function parseShellAgentWrite(value, name) {
|
|
1787
1802
|
if (value === "read-only" || value === "gated" || value === "allow") return value;
|
|
1788
1803
|
throw new ConfigError(`${name} must be read-only, gated or allow (got '${value}')`);
|
|
@@ -1842,7 +1857,7 @@ async function loadConfigFile(explicit, cwd = process.cwd()) {
|
|
|
1842
1857
|
};
|
|
1843
1858
|
let mod;
|
|
1844
1859
|
try {
|
|
1845
|
-
mod = await import(pathToFileURL(path).href);
|
|
1860
|
+
mod = await import(`${pathToFileURL(path).href}?mtime=${statSync(path).mtimeMs}`);
|
|
1846
1861
|
} catch (error) {
|
|
1847
1862
|
throw new ConfigError(`failed to load ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1848
1863
|
}
|
|
@@ -1949,6 +1964,16 @@ function resolveInstanceConfig(flags, loaded, env = process.env, cwd = process.c
|
|
|
1949
1964
|
};
|
|
1950
1965
|
if (flags.profiles.length) options.profiles = flags.profiles;
|
|
1951
1966
|
if (flags.approvalTimeoutMs !== void 0) options.approvalTimeoutMs = flags.approvalTimeoutMs;
|
|
1967
|
+
if (flags.engineSleepAfterMs !== void 0) options.engineSleepAfterMs = flags.engineSleepAfterMs;
|
|
1968
|
+
if (flags.agentContextReset === "never") options.agentContextReset = false;
|
|
1969
|
+
else if (flags.agentContextReset !== void 0) options.agentContextReset = {
|
|
1970
|
+
...loaded.options.agentContextReset,
|
|
1971
|
+
default: flags.agentContextReset === "on"
|
|
1972
|
+
};
|
|
1973
|
+
if (flags.effortDefaults) options.effortDefaults = {
|
|
1974
|
+
...loaded.options.effortDefaults,
|
|
1975
|
+
...flags.effortDefaults
|
|
1976
|
+
};
|
|
1952
1977
|
if (flags.profileStore === false) delete options.profileStore;
|
|
1953
1978
|
const manageProfiles = flags.profileStore !== false;
|
|
1954
1979
|
if (manageProfiles && !options.allowedConfigDirRoots) options.allowedConfigDirRoots = flags.profileRoots.length ? flags.profileRoots : [homedir()];
|
|
@@ -2492,4 +2517,4 @@ function bannerLines({ url, config, generated, authEnabled, push }) {
|
|
|
2492
2517
|
//#endregion
|
|
2493
2518
|
export { createActivityRegistry as C, createDeviceRoute as S, createApnsForwarder as _, ConfigError as a, createApnsRoute as b, isLoopback as c, parseArgs as d, resolveInstanceConfig as f, buildPush as g, materializeAuthKey as h, renderLoginPage as i, isLoopbackHostname as l, createAuthSessionStore as m, resolveWebRoot as n, defaultStateDir as o, createCliAuth as p, startInstance as r, hostnameOf as s, createHostGuard as t, loadConfigFile as u, createApnsClient as v, createActivityRoute as w, createDeviceRegistry as x, loadApnsKey as y };
|
|
2494
2519
|
|
|
2495
|
-
//# sourceMappingURL=instance-
|
|
2520
|
+
//# sourceMappingURL=instance-DyBeVgsK.mjs.map
|