@ggui-ai/cli 0.23.0 → 0.24.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.
@@ -33,6 +33,16 @@
33
33
  * deployments swap in a different `ProviderKeyStore` binding at
34
34
  * composition time and bypass this resolver entirely.
35
35
  *
36
+ * 3. **The local CLI login** (`ggui serve --local-cli-login`, ggui#1185) —
37
+ * opt-in, anthropic only, and consulted LAST, so any real key above
38
+ * always wins. It returns no key at all: the credential is the
39
+ * {@link CLAUDE_CODE_LOGIN_CREDENTIAL} sentinel, which routes
40
+ * generation through Claude Code as the Agent SDK ships it, signed in
41
+ * with the Claude login already on this machine (the one the `claude`
42
+ * command uses). ggui never stores that login; a
43
+ * `CLAUDE_CODE_OAUTH_TOKEN` set in the environment is passed to Claude
44
+ * Code unchanged.
45
+ *
36
46
  * **Explicitly NOT a source:** `ggui.json#secrets` or any other
37
47
  * project-file location. Plaintext secrets in a project file that
38
48
  * gets committed is a footgun, called out in the OSS-split plan
@@ -70,7 +80,7 @@ export declare const PROVIDER_ENV_NAMES: Readonly<Record<Exclude<LlmProvider, 'b
70
80
  */
71
81
  export interface ByokKeyResolution {
72
82
  readonly key: string;
73
- readonly source: 'env' | 'credentials-file';
83
+ readonly source: 'env' | 'credentials-file' | 'claude-code-login';
74
84
  readonly provider: LlmProvider;
75
85
  /**
76
86
  * Which env-var name produced the key (for `source: 'env'`). Lets
@@ -105,6 +115,15 @@ export interface ByokResolverOptions {
105
115
  * lookup. `undefined` triggers the default-store construction.
106
116
  */
107
117
  readonly fileStore?: ProviderKeyStore | null;
118
+ /**
119
+ * ggui#1185 — the operator opted in to generating with the Claude login
120
+ * already on this machine, the one the `claude` command uses (`ggui serve
121
+ * --local-cli-login`). When true, an anthropic lookup that finds no key
122
+ * resolves to {@link CLAUDE_CODE_LOGIN_CREDENTIAL} instead of `null`.
123
+ * Every other provider is unaffected, and a real anthropic key always
124
+ * wins. Default `false`: nothing changes for anyone who does not opt in.
125
+ */
126
+ readonly localCliLogin?: boolean;
108
127
  }
109
128
  /**
110
129
  * Per-call resolver options. Threaded through the request → handler →
@@ -1 +1 @@
1
- {"version":3,"file":"byok-resolver.d.ts","sourceRoot":"","sources":["../src/byok-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,OAAO,KAAK,EACV,WAAW,EAEX,gBAAgB,EACjB,MAAM,0BAA0B,CAAC;AAIlC;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAEnE,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CACvC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC,CAM3D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,kBAAkB,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;;;OASG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC9C;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,CACL,QAAQ,EAAE,WAAW,EACrB,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACtC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,GAAE,mBAAwB,GAC7B,YAAY,CAoFd"}
1
+ {"version":3,"file":"byok-resolver.d.ts","sourceRoot":"","sources":["../src/byok-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,OAAO,KAAK,EACV,WAAW,EAEX,gBAAgB,EACjB,MAAM,0BAA0B,CAAC;AAKlC;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAEnE,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,WAAW,CAAC;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CACvC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC,CAM3D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;IAClE,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;;;OASG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC7C;;;;;;;OAOG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,CACL,QAAQ,EAAE,WAAW,EACrB,IAAI,CAAC,EAAE,kBAAkB,GACxB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACtC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,GAAE,mBAAwB,GAC7B,YAAY,CA8Fd"}
@@ -1,4 +1,5 @@
1
1
  import { PlaintextFileProviderKeyStore } from '@ggui-ai/mcp-server-core/plaintext';
2
+ import { CLAUDE_CODE_LOGIN_CREDENTIAL } from '@ggui-ai/ui-gen';
2
3
  import { getCredentialsFile } from './paths.js';
3
4
  /** App-scope key under which the resolver reads + writes the store. */
4
5
  export const BYOK_GLOBAL_APP_SCOPE = 'global';
@@ -92,6 +93,15 @@ export function createByokResolver(opts = {}) {
92
93
  if (userHit)
93
94
  return userHit;
94
95
  }
96
+ // Last (opt-in, anthropic only): the local CLI login, after every
97
+ // real-key step above, so a real key always wins.
98
+ if (opts.localCliLogin === true && provider === 'anthropic') {
99
+ return {
100
+ key: CLAUDE_CODE_LOGIN_CREDENTIAL,
101
+ source: 'claude-code-login',
102
+ provider,
103
+ };
104
+ }
95
105
  return null;
96
106
  },
97
107
  };
package/dist/cli.js CHANGED
@@ -545,7 +545,7 @@ async function runServeCommand(args) {
545
545
  // `blueprints` dep regardless of manifest state.
546
546
  const blueprintsForGen = blueprintProvider ?? new InMemoryBlueprintProvider();
547
547
  generationBinding = await probeGenerationBinding({
548
- resolver: createByokResolver(),
548
+ resolver: createByokResolver({ localCliLogin: parsed.localCliLogin }),
549
549
  blueprints: blueprintsForGen,
550
550
  ...(configuredRoute ? { configuredRoute } : {}),
551
551
  onNoCredentials: (ctx, story) => {
@@ -570,7 +570,7 @@ async function runServeCommand(args) {
570
570
  process.stderr.write(`ggui serve: generation probe failed: ${err instanceof Error ? err.message : String(err)}\n`);
571
571
  const blueprintsForGen = blueprintProvider ?? new InMemoryBlueprintProvider();
572
572
  generationBinding = await probeGenerationBinding({
573
- resolver: createByokResolver(),
573
+ resolver: createByokResolver({ localCliLogin: parsed.localCliLogin }),
574
574
  blueprints: blueprintsForGen,
575
575
  ...(configuredRoute ? { configuredRoute } : {}),
576
576
  });
@@ -602,6 +602,11 @@ async function runServeCommand(args) {
602
602
  return 1;
603
603
  }
604
604
  process.stdout.write(`${describeGenerationBinding(generationBinding)}\n`);
605
+ // ggui#1185: the flag covers anthropic routes only. Say so rather than
606
+ // let it sit silently unused when this server generates elsewhere.
607
+ if (parsed.localCliLogin && generationBinding.provider !== 'anthropic') {
608
+ process.stderr.write(`ggui serve: --local-cli-login covers anthropic routes only; this server generates on ${generationBinding.provider}, so the flag has no effect.\n`);
609
+ }
605
610
  // Build seed pools from --seed-pool flags BEFORE composing the backend
606
611
  // factory. `buildSeedPool` is async (reads + indexes the directory
607
612
  // artifact) so it must run here in the async outer scope rather than
@@ -200,6 +200,7 @@ export declare function probeGenerationBinding(opts: ProbeGenerationBindingOptio
200
200
  * `generation: anthropic / claude-haiku-4-5 (env: ANTHROPIC_API_KEY)`
201
201
  * `generation: openai / gpt-4o (credentials-file)`
202
202
  * `generation: anthropic / claude-haiku-4-5 (no boot key — per-user fallback)`
203
+ * `generation: anthropic / claude-haiku-4-5 (the claude command's login on this machine — …)` (ggui#1185)
203
204
  */
204
205
  export declare function describeGenerationBinding(binding: GenerationBinding): string;
205
206
  //# sourceMappingURL=generation-probe.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"generation-probe.d.ts","sourceRoot":"","sources":["../src/generation-probe.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generation-probe.d.ts","sourceRoot":"","sources":["../src/generation-probe.ts"],"names":[],"mappings":"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"}
@@ -162,6 +162,20 @@ export async function probeGenerationBinding(opts) {
162
162
  };
163
163
  return result;
164
164
  }
165
+ /** The banner's words for where the boot credential came from. */
166
+ function keySourceLabel(binding) {
167
+ switch (binding.keySource) {
168
+ case 'env':
169
+ return binding.keyEnvName ? `env: ${binding.keyEnvName}` : 'env';
170
+ case 'credentials-file':
171
+ return 'credentials-file';
172
+ // ggui#1185: no key at all. Say what runs and whose terms apply.
173
+ case 'claude-code-login':
174
+ return "the claude command's login on this machine — your Claude plan's terms and usage limits apply";
175
+ case undefined:
176
+ return 'credentials-file';
177
+ }
178
+ }
165
179
  /**
166
180
  * Render a single operator-facing banner line describing the
167
181
  * generation binding. Always returns a string — when boot didn't
@@ -174,16 +188,13 @@ export async function probeGenerationBinding(opts) {
174
188
  * `generation: anthropic / claude-haiku-4-5 (env: ANTHROPIC_API_KEY)`
175
189
  * `generation: openai / gpt-4o (credentials-file)`
176
190
  * `generation: anthropic / claude-haiku-4-5 (no boot key — per-user fallback)`
191
+ * `generation: anthropic / claude-haiku-4-5 (the claude command's login on this machine — …)` (ggui#1185)
177
192
  */
178
193
  export function describeGenerationBinding(binding) {
179
194
  if (!binding.bootResolved) {
180
195
  return `generation: ${binding.provider} / ${binding.model} (no boot key — per-user fallback)`;
181
196
  }
182
- const src = binding.keySource === 'env'
183
- ? binding.keyEnvName
184
- ? `env: ${binding.keyEnvName}`
185
- : 'env'
186
- : 'credentials-file';
197
+ const src = keySourceLabel(binding);
187
198
  const conflict = binding.keyShadowedEnvNames !== undefined && binding.keyEnvName !== undefined
188
199
  ? ` — ${binding.keyEnvName} won; ${binding.keyShadowedEnvNames.join(', ')} also set and differs (rotate both or unset one, ggui#1132)`
189
200
  : '';
@@ -137,6 +137,17 @@ export interface ParsedServeFlags {
137
137
  * own LLM key via /settings using their paired bearer.
138
138
  */
139
139
  multiUser: boolean;
140
+ /**
141
+ * ggui#1185 — generate with the Claude login already on this machine
142
+ * (the one the `claude` command uses), when no Anthropic API key is set.
143
+ * Claude Code runs as the Agent SDK ships it, unmodified. Opt-in; default
144
+ * `false`, so nothing changes for anyone who does not pass it. A real
145
+ * `ANTHROPIC_API_KEY` (env or credentials file) always wins, and only
146
+ * anthropic routes are covered. It is for the operator's own use:
147
+ * one person's Claude plan never serves other users, so it is refused
148
+ * with {@link multiUser} and {@link publicDemo}.
149
+ */
150
+ localCliLogin: boolean;
140
151
  /**
141
152
  * Server-level MCP instructions preset (the string injected into
142
153
  * the LLM's system prompt above the tool catalog). Operator-tunable
@@ -476,9 +487,10 @@ export interface RunServeOptions {
476
487
  * Parsed flags. The `error` field must already be handled upstream.
477
488
  * `seedPools` is omitted too — it's parse output the CLI consumes to
478
489
  * build the shared `BlueprintPool[]` (fed straight into the backend
479
- * factory), NOT a `runServe` lifecycle input.
490
+ * factory), NOT a `runServe` lifecycle input. `localCliLogin` likewise
491
+ * (ggui#1185): the CLI hands it to the key resolver before `runServe`.
480
492
  */
481
- readonly flags: Readonly<Omit<ParsedServeFlags, 'error' | 'seedPools'>>;
493
+ readonly flags: Readonly<Omit<ParsedServeFlags, 'error' | 'seedPools' | 'localCliLogin'>>;
482
494
  /** Build the backend. Called once, after flag parsing. */
483
495
  readonly backendFactory: ServeBackendFactory;
484
496
  /**
@@ -525,5 +537,5 @@ export interface RunServeOptions {
525
537
  * {@link describeServeBanner} / {@link describeAgentStatus}.
526
538
  */
527
539
  export declare function runServe(opts: RunServeOptions): Promise<number>;
528
- export declare const SERVE_HELP = "ggui serve \u2014 run the open self-hosted personal-mode app\n\nBoots the @ggui-ai/mcp-server binding with persistent defaults AND\n(by default) supervises your agent alongside it. The current MCP\nhandler surface is the blueprint-read family (search / list_featured\n/ render); more tools come online as @ggui-ai/mcp-server-handlers\ngrows.\n\nFirst-run bundle (all on by default):\n - Landing page at / \u2014 operator opens a browser and sees\n server identity + pair-code card.\n - Render viewer at /r/<code> \u2014 same-origin viewer for renders\n minted by ggui_render; same-origin\n HTTP-only cookie authenticates the\n live-channel /ws upgrade.\n - POST /pair + POST /admin/pair/init \u2014 pairing endpoint for MCP\n hosts and third-party clients.\n - Live-channel /ws \u2014 live render plane for MCP Apps\n iframes and the console.\n\nEmbedding hosts that want a different shape (no landing page, no\npairing, programmatic control) should compose createGguiServer()\ndirectly in code rather than invoking `ggui serve`.\n\nUsage:\n ggui serve [options]\n\nOptions:\n --port <n> Bind port (default: 6781, 0 = OS-assigned).\n --host <addr> Bind host (default: 127.0.0.1).\n --mcp-only Run just the MCP server; do not supervise an agent.\n --dev-allow-all Accept any non-empty bearer (incl. no bearer) as\n builder. Local-dev / tunnel smoke ONLY \u2014 never\n expose to the open internet.\n --public-demo Public-facing demo posture: same any-bearer auth\n as --dev-allow-all, plus per-IP rate limit on\n ggui_render (30 generations / 10 min) and a\n \"PUBLIC DEMO \u2014 operator pays\" banner. Mutually\n exclusive with --dev-allow-all.\n --multi-user Multi-user posture: switches the /settings LLM-\n keys gate from admin-token to auth-adapter so\n each authenticated end-user manages their OWN\n key plane (scope = userId/appId). kind:'builder'\n identities are rejected at the gate. Strict-auth\n only; mutually exclusive with --dev-allow-all\n and --public-demo. (Generation-time BYOK still\n resolves at the operator 'global' scope \u2014 a\n follow-up will thread per-user BYOK through\n ggui_render.)\n --public-base-url <u> Override the public base URL used to compose\n iframe-runtime + shortCode URLs. Set this to a\n tunnel URL (https://<random>.trycloudflare.com)\n when testing against a remote MCP host so URLs\n resolve from the host's perspective. Without\n this, URLs derive from --host:--port and only\n work from the same machine.\n --browser-origin <o> Allow pages at this origin past MCP-wire Origin\n validation (repeatable; env GGUI_BROWSER_ORIGINS,\n comma-separated). Pages on localhost need no\n entry. NOT authentication \u2014 /mcp still requires\n a bearer. Non-browser clients are unaffected.\n --oauth Mount OAuth 2.1 + PKCE + Dynamic Client\n Registration routes (.well-known/oauth-* +\n /oauth/{authorize,token,register}). Required\n for MCP custom-connector hosts (claude.ai,\n ChatGPT) whose Add Connector form has no field\n for a pre-shared bearer; OAuth lets them do\n a discovery \u2192 DCR \u2192 consent dance ending in\n the same paired bearer the strict-auth flow\n already mints. Pure-bearer clients (Claude\n Desktop with bearer in config) work without it.\n --admin-token <t> Pin the admin bearer that gates the console\n /keys plane (list / mint / revoke pairings +\n /admin-login route). Without this, the server\n mints a fresh ggui_admin_* token per boot and\n prints it on the banner. Pin a stable value\n when you want the bearer to survive restarts\n (e.g. paste once into a password manager).\n --ephemeral Disable cross-restart persistence. Without\n this flag, the HMAC secrets that sign MCP\n Apps bootstrap tokens and signed render URLs\n are read or minted under .ggui/persistent/\n (project-local if a ggui.json was resolved,\n else ~/.ggui/persistent/) so cached tokens\n survive a server restart. Pass this flag to\n keep restarts ephemeral (tests / CI / nuclear-\n revoke). Override the dir via GGUI_PERSISTENT_DIR.\n --seed-pool <dir> Load a read-only shared blueprint pool from a\n directory artifact (repeatable). Blueprints in it\n are reused by exact contract match, after your own.\n --help, -h Show this help.\n\nAgent runtime:\n The default boots your agent alongside MCP. The agent's entry file\n comes from ggui.json:\n\n { \"agent\": { \"entry\": \"./agent.ts\" } }\n\n Supported extensions: .js / .mjs / .cjs (node), .ts / .tsx / .mts\n (node --import=tsx). No ggui.json, or no agent.entry, falls back\n to MCP-only with a warning. Malformed ggui.json or a bad entry\n is a hard error.\n\n Agent crashes after startup are logged; the MCP server keeps\n running. No auto-restart \u2014 compose that with your own supervisor.\n\nPersistent storage (default-on; opt-out via --ephemeral):\n By default `ggui serve` writes a small bundle under .ggui/persistent/\n (project-local if a ggui.json was resolved, else ~/.ggui/persistent/)\n so cached MCP Apps tokens, signed render URLs, shortCodes, renders,\n vectors, and paired bearers survive a restart \u2014 claude.ai chat-history\n revisits keep working.\n\n Bundle layout:\n\n .ggui/persistent/\n \u251C\u2500\u2500 ws-token-secret.hex (HMAC, 0600)\n \u251C\u2500\u2500 render-signer-secret.hex (HMAC, 0600)\n \u251C\u2500\u2500 short-codes.sqlite (signed render-URL resolution)\n \u251C\u2500\u2500 sessions.sqlite (GguiSessionStore \u2014 renders + event history)\n \u251C\u2500\u2500 vectors.sqlite (RAG corpus)\n \u2514\u2500\u2500 keys.json (paired bearers)\n\n Override the dir with `GGUI_PERSISTENT_DIR`. Pass `--ephemeral` to\n skip the bundle entirely (tests, CI loops, nuclear-revoke).\n\n Explicit ggui.json#storage declarations always win \u2014 declare\n `{ \"renders\": { \"driver\": \"memory\" } }` to opt renders back to\n in-memory while keeping other surfaces persistent. Custom sqlite\n paths via ggui.json#storage are honored verbatim:\n\n {\n \"storage\": {\n \"renders\": { \"driver\": \"sqlite\", \"path\": \"./ggui-sessions.sqlite\" },\n \"vectors\": { \"driver\": \"sqlite\", \"path\": \"./ggui-vectors.sqlite\" },\n \"threads\": { \"driver\": \"sqlite\", \"path\": \"./ggui-threads.sqlite\" }\n }\n }\n\n Threads: the persistent-chat route family (/threads) is opt-in.\n Absent `storage.threads` leaves the routes unmounted \u2014 pairs\n with Portal's self-hosted origins only when declared. Driver\n semantics:\n - `driver: \"sqlite\"` \u2014 durable. Threads survive restart.\n /ggui/health reports `threads.durability: \"durable\"`;\n Portal hides its non-durable caveat.\n - `driver: \"memory\"` \u2014 routes mount but data is lost on\n restart. /ggui/health reports `threads.durability:\n \"ephemeral\"`; Portal shows its caveat.\n\n Paths resolve relative to the ggui.json directory. The sqlite\n driver needs `better-sqlite3` installed in your project.\n\nRecommended setups:\n\n Local-only smoke (no tunnel, no remote MCP host):\n ggui serve\n\n claude.ai custom connector (over a public tunnel):\n 1. Tunnel: cloudflared tunnel --url http://localhost:6781\n 2. ggui serve --oauth \\\n --public-base-url https://<tunnel>.trycloudflare.com\n 3. Note PAIR_CODE from boot. Visit the landing page (the public URL\n above), complete pairing, save the bearer.\n 4. claude.ai \u2192 Settings \u2192 Connectors \u2192 Add custom connector.\n URL: https://<tunnel>.trycloudflare.com/mcp\n Client ID / Secret: leave empty (server uses Dynamic Client\n Registration; no pre-shared secret needed).\n 5. Click Connect \u2192 claude.ai redirects you to a paste-key page.\n Paste the bearer from step 3. Done.\n\n Quick local-dev WITHOUT auth (NEVER over a public tunnel):\n ggui serve --dev-allow-all\n\nCurrent limits:\n - Strict-auth only: /mcp rejects any bearer that isn't pair-minted.\n The CLI pre-mints one pairing code on boot (printed as\n `PAIR_CODE <code>` and shown in the banner + on the landing\n page). Complete `POST /pair {code, deviceName}` to receive a\n bearer you can use with MCP. Embed @ggui-ai/mcp-server in your\n own entrypoint to inject a different AuthAdapter (OIDC, Cognito,\n etc.) for production.\n - Single-user: every request scopes to one `builder` app id.\n";
540
+ export declare const SERVE_HELP = "ggui serve \u2014 run the open self-hosted personal-mode app\n\nBoots the @ggui-ai/mcp-server binding with persistent defaults AND\n(by default) supervises your agent alongside it. The current MCP\nhandler surface is the blueprint-read family (search / list_featured\n/ render); more tools come online as @ggui-ai/mcp-server-handlers\ngrows.\n\nFirst-run bundle (all on by default):\n - Landing page at / \u2014 operator opens a browser and sees\n server identity + pair-code card.\n - Render viewer at /r/<code> \u2014 same-origin viewer for renders\n minted by ggui_render; same-origin\n HTTP-only cookie authenticates the\n live-channel /ws upgrade.\n - POST /pair + POST /admin/pair/init \u2014 pairing endpoint for MCP\n hosts and third-party clients.\n - Live-channel /ws \u2014 live render plane for MCP Apps\n iframes and the console.\n\nEmbedding hosts that want a different shape (no landing page, no\npairing, programmatic control) should compose createGguiServer()\ndirectly in code rather than invoking `ggui serve`.\n\nUsage:\n ggui serve [options]\n\nOptions:\n --port <n> Bind port (default: 6781, 0 = OS-assigned).\n --host <addr> Bind host (default: 127.0.0.1).\n --mcp-only Run just the MCP server; do not supervise an agent.\n --dev-allow-all Accept any non-empty bearer (incl. no bearer) as\n builder. Local-dev / tunnel smoke ONLY \u2014 never\n expose to the open internet.\n --public-demo Public-facing demo posture: same any-bearer auth\n as --dev-allow-all, plus per-IP rate limit on\n ggui_render (30 generations / 10 min) and a\n \"PUBLIC DEMO \u2014 operator pays\" banner. Mutually\n exclusive with --dev-allow-all.\n --multi-user Multi-user posture: switches the /settings LLM-\n keys gate from admin-token to auth-adapter so\n each authenticated end-user manages their OWN\n key plane (scope = userId/appId). kind:'builder'\n identities are rejected at the gate. Strict-auth\n only; mutually exclusive with --dev-allow-all\n and --public-demo. (Generation-time BYOK still\n resolves at the operator 'global' scope \u2014 a\n follow-up will thread per-user BYOK through\n ggui_render.)\n --local-cli-login Generate with the Claude login already on this\n machine (the one `claude` uses) when no\n ANTHROPIC_API_KEY is set, instead of an API key.\n Anthropic routes only; a real key always wins. Your\n Claude plan's terms and usage limits apply, and\n generation is about 2x slower (2.2x at the median)\n than with an API key. For your own use: refused with\n --multi-user and --public-demo.\n --public-base-url <u> Override the public base URL used to compose\n iframe-runtime + shortCode URLs. Set this to a\n tunnel URL (https://<random>.trycloudflare.com)\n when testing against a remote MCP host so URLs\n resolve from the host's perspective. Without\n this, URLs derive from --host:--port and only\n work from the same machine.\n --browser-origin <o> Allow pages at this origin past MCP-wire Origin\n validation (repeatable; env GGUI_BROWSER_ORIGINS,\n comma-separated). Pages on localhost need no\n entry. NOT authentication \u2014 /mcp still requires\n a bearer. Non-browser clients are unaffected.\n --oauth Mount OAuth 2.1 + PKCE + Dynamic Client\n Registration routes (.well-known/oauth-* +\n /oauth/{authorize,token,register}). Required\n for MCP custom-connector hosts (claude.ai,\n ChatGPT) whose Add Connector form has no field\n for a pre-shared bearer; OAuth lets them do\n a discovery \u2192 DCR \u2192 consent dance ending in\n the same paired bearer the strict-auth flow\n already mints. Pure-bearer clients (Claude\n Desktop with bearer in config) work without it.\n --admin-token <t> Pin the admin bearer that gates the console\n /keys plane (list / mint / revoke pairings +\n /admin-login route). Without this, the server\n mints a fresh ggui_admin_* token per boot and\n prints it on the banner. Pin a stable value\n when you want the bearer to survive restarts\n (e.g. paste once into a password manager).\n --ephemeral Disable cross-restart persistence. Without\n this flag, the HMAC secrets that sign MCP\n Apps bootstrap tokens and signed render URLs\n are read or minted under .ggui/persistent/\n (project-local if a ggui.json was resolved,\n else ~/.ggui/persistent/) so cached tokens\n survive a server restart. Pass this flag to\n keep restarts ephemeral (tests / CI / nuclear-\n revoke). Override the dir via GGUI_PERSISTENT_DIR.\n --seed-pool <dir> Load a read-only shared blueprint pool from a\n directory artifact (repeatable). Blueprints in it\n are reused by exact contract match, after your own.\n --help, -h Show this help.\n\nAgent runtime:\n The default boots your agent alongside MCP. The agent's entry file\n comes from ggui.json:\n\n { \"agent\": { \"entry\": \"./agent.ts\" } }\n\n Supported extensions: .js / .mjs / .cjs (node), .ts / .tsx / .mts\n (node --import=tsx). No ggui.json, or no agent.entry, falls back\n to MCP-only with a warning. Malformed ggui.json or a bad entry\n is a hard error.\n\n Agent crashes after startup are logged; the MCP server keeps\n running. No auto-restart \u2014 compose that with your own supervisor.\n\nPersistent storage (default-on; opt-out via --ephemeral):\n By default `ggui serve` writes a small bundle under .ggui/persistent/\n (project-local if a ggui.json was resolved, else ~/.ggui/persistent/)\n so cached MCP Apps tokens, signed render URLs, shortCodes, renders,\n vectors, and paired bearers survive a restart \u2014 claude.ai chat-history\n revisits keep working.\n\n Bundle layout:\n\n .ggui/persistent/\n \u251C\u2500\u2500 ws-token-secret.hex (HMAC, 0600)\n \u251C\u2500\u2500 render-signer-secret.hex (HMAC, 0600)\n \u251C\u2500\u2500 short-codes.sqlite (signed render-URL resolution)\n \u251C\u2500\u2500 sessions.sqlite (GguiSessionStore \u2014 renders + event history)\n \u251C\u2500\u2500 vectors.sqlite (RAG corpus)\n \u2514\u2500\u2500 keys.json (paired bearers)\n\n Override the dir with `GGUI_PERSISTENT_DIR`. Pass `--ephemeral` to\n skip the bundle entirely (tests, CI loops, nuclear-revoke).\n\n Explicit ggui.json#storage declarations always win \u2014 declare\n `{ \"renders\": { \"driver\": \"memory\" } }` to opt renders back to\n in-memory while keeping other surfaces persistent. Custom sqlite\n paths via ggui.json#storage are honored verbatim:\n\n {\n \"storage\": {\n \"renders\": { \"driver\": \"sqlite\", \"path\": \"./ggui-sessions.sqlite\" },\n \"vectors\": { \"driver\": \"sqlite\", \"path\": \"./ggui-vectors.sqlite\" },\n \"threads\": { \"driver\": \"sqlite\", \"path\": \"./ggui-threads.sqlite\" }\n }\n }\n\n Threads: the persistent-chat route family (/threads) is opt-in.\n Absent `storage.threads` leaves the routes unmounted \u2014 pairs\n with Portal's self-hosted origins only when declared. Driver\n semantics:\n - `driver: \"sqlite\"` \u2014 durable. Threads survive restart.\n /ggui/health reports `threads.durability: \"durable\"`;\n Portal hides its non-durable caveat.\n - `driver: \"memory\"` \u2014 routes mount but data is lost on\n restart. /ggui/health reports `threads.durability:\n \"ephemeral\"`; Portal shows its caveat.\n\n Paths resolve relative to the ggui.json directory. The sqlite\n driver needs `better-sqlite3` installed in your project.\n\nRecommended setups:\n\n Local-only smoke (no tunnel, no remote MCP host):\n ggui serve\n\n claude.ai custom connector (over a public tunnel):\n 1. Tunnel: cloudflared tunnel --url http://localhost:6781\n 2. ggui serve --oauth \\\n --public-base-url https://<tunnel>.trycloudflare.com\n 3. Note PAIR_CODE from boot. Visit the landing page (the public URL\n above), complete pairing, save the bearer.\n 4. claude.ai \u2192 Settings \u2192 Connectors \u2192 Add custom connector.\n URL: https://<tunnel>.trycloudflare.com/mcp\n Client ID / Secret: leave empty (server uses Dynamic Client\n Registration; no pre-shared secret needed).\n 5. Click Connect \u2192 claude.ai redirects you to a paste-key page.\n Paste the bearer from step 3. Done.\n\n Quick local-dev WITHOUT auth (NEVER over a public tunnel):\n ggui serve --dev-allow-all\n\nCurrent limits:\n - Strict-auth only: /mcp rejects any bearer that isn't pair-minted.\n The CLI pre-mints one pairing code on boot (printed as\n `PAIR_CODE <code>` and shown in the banner + on the landing\n page). Complete `POST /pair {code, deviceName}` to receive a\n bearer you can use with MCP. Embed @ggui-ai/mcp-server in your\n own entrypoint to inject a different AuthAdapter (OIDC, Cognito,\n etc.) for production.\n - Single-user: every request scopes to one `builder` app id.\n";
529
541
  //# sourceMappingURL=serve-command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"serve-command.d.ts","sourceRoot":"","sources":["../src/serve-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EAEjB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;;;;;;OAUG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;IAC1E;;;;;;;;;;OAUG;IACH,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;OAWG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CAgLzE;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;CAChC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;CACtC,CAAC;AAEN,MAAM,MAAM,mBAAmB,GAC3B,YAAY,GACZ,cAAc,GACd,8BAA8B,CAAC;AAEnC;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACjD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAgItE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAa/D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,yCAAyC;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACpD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,YAAY,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACvD;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CACd,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,IAAI,EACnB,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GACxB,IAAI,CAAC;CACT;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC;IACxE,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,qBAAqB,CAAC;IACvC,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChD;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAyJrE;AAED,eAAO,MAAM,UAAU,4uTAuLtB,CAAC"}
1
+ {"version":3,"file":"serve-command.d.ts","sourceRoot":"","sources":["../src/serve-command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EAEjB,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAG1D;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;;;;;;OAUG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;OAWG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,KAAK,EAAE,OAAO,CAAC;IACf;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;;OASG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;;;;;;;;;;;;;OAeG;IACH,eAAe,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;IAC1E;;;;;;;;;;OAUG;IACH,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;;OAWG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,gBAAgB,CA+LzE;AAED;;;;GAIG;AACH,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,6DAA6D;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;CAChC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;CACtC,CAAC;AAEN,MAAM,MAAM,mBAAmB,GAC3B,YAAY,GACZ,cAAc,GACd,8BAA8B,CAAC;AAEnC;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sCAAsC;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACjD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAgItE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAa/D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,yCAAyC;IACzC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,uCAAuC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;OAMG;IACH,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACpD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,YAAY,CAAC;AAErD;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACvD;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CACd,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,IAAI,EACnB,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GACxB,IAAI,CAAC;CACT;AAED,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC;IAC1F,0DAA0D;IAC1D,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,qBAAqB,CAAC;IACvC,gFAAgF;IAChF,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE;QAAE,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChD;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAyJrE;AAED,eAAO,MAAM,UAAU,gzUA+LtB,CAAC"}
@@ -26,6 +26,7 @@ export function parseServeFlags(args) {
26
26
  withholdResultMeta: false,
27
27
  publicDemo: false,
28
28
  multiUser: false,
29
+ localCliLogin: false,
29
30
  oauth: false,
30
31
  seedPools: [],
31
32
  browserOrigins: [],
@@ -79,6 +80,10 @@ export function parseServeFlags(args) {
79
80
  out.oauth = true;
80
81
  continue;
81
82
  }
83
+ if (arg === '--local-cli-login') {
84
+ out.localCliLogin = true;
85
+ continue;
86
+ }
82
87
  if (arg === '--public-base-url') {
83
88
  const v = args[++i];
84
89
  if (v === undefined || v === '') {
@@ -188,6 +193,15 @@ export function parseServeFlags(args) {
188
193
  'multi-user gate rejects. Drop the other flag and pair with real bearers.',
189
194
  };
190
195
  }
196
+ if (out.localCliLogin && (out.multiUser || out.publicDemo)) {
197
+ return {
198
+ ...out,
199
+ error: '--local-cli-login is incompatible with --multi-user and --public-demo. ' +
200
+ 'It generates on the Claude plan the `claude` command on this machine is ' +
201
+ 'signed in to, which is for your own use: one person\'s plan never serves ' +
202
+ 'other users. Use provider API keys for a shared or public server.',
203
+ };
204
+ }
191
205
  return out;
192
206
  }
193
207
  export function describeServeBanner(input) {
@@ -500,6 +514,14 @@ Options:
500
514
  resolves at the operator 'global' scope — a
501
515
  follow-up will thread per-user BYOK through
502
516
  ggui_render.)
517
+ --local-cli-login Generate with the Claude login already on this
518
+ machine (the one \`claude\` uses) when no
519
+ ANTHROPIC_API_KEY is set, instead of an API key.
520
+ Anthropic routes only; a real key always wins. Your
521
+ Claude plan's terms and usage limits apply, and
522
+ generation is about 2x slower (2.2x at the median)
523
+ than with an API key. For your own use: refused with
524
+ --multi-user and --public-demo.
503
525
  --public-base-url <u> Override the public base URL used to compose
504
526
  iframe-runtime + shortCode URLs. Set this to a
505
527
  tunnel URL (https://<random>.trycloudflare.com)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/cli",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "The `ggui` CLI — run the ggui protocol locally: dev server, self-hosted MCP server, and gadget / blueprint authoring. End-to-end OSS and self-hosted workflows; no account required.",
5
5
  "keywords": [
6
6
  "ggui",
@@ -37,22 +37,22 @@
37
37
  "@noble/hashes": "^1.6.0",
38
38
  "esbuild": "^0.28.2",
39
39
  "zod": "^4.3.6",
40
- "@ggui-ai/agent-runtime": "0.23.0",
41
- "@ggui-ai/artifact-manifest": "0.23.0",
42
- "@ggui-ai/design": "0.23.0",
43
- "@ggui-ai/dev-stack": "0.23.0",
44
- "@ggui-ai/gadget-signing": "0.23.0",
45
- "@ggui-ai/embedding-local": "0.23.0",
46
- "@ggui-ai/mcp-server": "0.23.0",
47
- "@ggui-ai/mcp-server-handlers": "0.23.0",
48
- "@ggui-ai/preview-a2ui": "0.23.0",
49
- "@ggui-ai/project-config": "0.23.0",
50
- "@ggui-ai/protocol": "0.23.0",
51
- "@ggui-ai/iframe-runtime": "0.23.0",
52
- "@ggui-ai/ui-gen": "0.23.0",
53
- "@ggui-ai/mcp-server-core": "0.23.0",
54
- "@ggui-ai/registry-core": "0.23.0",
55
- "@ggui-ai/ui-registry": "0.23.0"
40
+ "@ggui-ai/artifact-manifest": "0.24.0",
41
+ "@ggui-ai/dev-stack": "0.24.0",
42
+ "@ggui-ai/gadget-signing": "0.24.0",
43
+ "@ggui-ai/agent-runtime": "0.24.0",
44
+ "@ggui-ai/design": "0.24.0",
45
+ "@ggui-ai/mcp-server-core": "0.24.0",
46
+ "@ggui-ai/mcp-server-handlers": "0.24.0",
47
+ "@ggui-ai/preview-a2ui": "0.24.0",
48
+ "@ggui-ai/project-config": "0.24.0",
49
+ "@ggui-ai/embedding-local": "0.24.0",
50
+ "@ggui-ai/mcp-server": "0.24.0",
51
+ "@ggui-ai/protocol": "0.24.0",
52
+ "@ggui-ai/registry-core": "0.24.0",
53
+ "@ggui-ai/ui-registry": "0.24.0",
54
+ "@ggui-ai/ui-gen": "0.24.0",
55
+ "@ggui-ai/iframe-runtime": "0.24.0"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/node": "^24.0.0",