@ggui-ai/cli 0.1.0-rc.1
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/LICENSE +201 -0
- package/README.md +96 -0
- package/dist/agent-resolution.d.ts +41 -0
- package/dist/agent-resolution.d.ts.map +1 -0
- package/dist/agent-resolution.js +80 -0
- package/dist/api-client.d.ts +59 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +145 -0
- package/dist/auth-keys.d.ts +10 -0
- package/dist/auth-keys.d.ts.map +1 -0
- package/dist/auth-keys.js +382 -0
- package/dist/auth-login.d.ts +11 -0
- package/dist/auth-login.d.ts.map +1 -0
- package/dist/auth-login.js +231 -0
- package/dist/auth-logout.d.ts +3 -0
- package/dist/auth-logout.d.ts.map +1 -0
- package/dist/auth-logout.js +32 -0
- package/dist/auth-store.d.ts +67 -0
- package/dist/auth-store.d.ts.map +1 -0
- package/dist/auth-store.js +150 -0
- package/dist/auth-whoami.d.ts +3 -0
- package/dist/auth-whoami.d.ts.map +1 -0
- package/dist/auth-whoami.js +52 -0
- package/dist/blueprint-command.d.ts +3 -0
- package/dist/blueprint-command.d.ts.map +1 -0
- package/dist/blueprint-command.js +203 -0
- package/dist/blueprint-create.d.ts +71 -0
- package/dist/blueprint-create.d.ts.map +1 -0
- package/dist/blueprint-create.js +377 -0
- package/dist/byok-resolver.d.ts +141 -0
- package/dist/byok-resolver.d.ts.map +1 -0
- package/dist/byok-resolver.js +89 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1066 -0
- package/dist/dev-command.d.ts +169 -0
- package/dist/dev-command.d.ts.map +1 -0
- package/dist/dev-command.js +222 -0
- package/dist/gadget-command.d.ts +3 -0
- package/dist/gadget-command.d.ts.map +1 -0
- package/dist/gadget-command.js +181 -0
- package/dist/gadget-create.d.ts +106 -0
- package/dist/gadget-create.d.ts.map +1 -0
- package/dist/gadget-create.js +492 -0
- package/dist/generation-probe.d.ts +135 -0
- package/dist/generation-probe.d.ts.map +1 -0
- package/dist/generation-probe.js +132 -0
- package/dist/internal/artifact-install.d.ts +150 -0
- package/dist/internal/artifact-install.d.ts.map +1 -0
- package/dist/internal/artifact-install.js +1019 -0
- package/dist/internal/artifact-publish.d.ts +204 -0
- package/dist/internal/artifact-publish.d.ts.map +1 -0
- package/dist/internal/artifact-publish.js +1141 -0
- package/dist/internal/artifact-search.d.ts +155 -0
- package/dist/internal/artifact-search.d.ts.map +1 -0
- package/dist/internal/artifact-search.js +539 -0
- package/dist/internal/artifact-uninstall.d.ts +30 -0
- package/dist/internal/artifact-uninstall.d.ts.map +1 -0
- package/dist/internal/artifact-uninstall.js +205 -0
- package/dist/internal/auth-cache.d.ts +40 -0
- package/dist/internal/auth-cache.d.ts.map +1 -0
- package/dist/internal/auth-cache.js +133 -0
- package/dist/internal/auth-strategy.d.ts +89 -0
- package/dist/internal/auth-strategy.d.ts.map +1 -0
- package/dist/internal/auth-strategy.js +132 -0
- package/dist/internal/ggui-json.d.ts +53 -0
- package/dist/internal/ggui-json.d.ts.map +1 -0
- package/dist/internal/ggui-json.js +92 -0
- package/dist/internal/key-store.d.ts +43 -0
- package/dist/internal/key-store.d.ts.map +1 -0
- package/dist/internal/key-store.js +128 -0
- package/dist/internal/oidc-token.d.ts +52 -0
- package/dist/internal/oidc-token.d.ts.map +1 -0
- package/dist/internal/oidc-token.js +351 -0
- package/dist/internal/register-author-key.d.ts +44 -0
- package/dist/internal/register-author-key.d.ts.map +1 -0
- package/dist/internal/register-author-key.js +212 -0
- package/dist/local-keys.d.ts +47 -0
- package/dist/local-keys.d.ts.map +1 -0
- package/dist/local-keys.js +115 -0
- package/dist/mcp-backend.d.ts +356 -0
- package/dist/mcp-backend.d.ts.map +1 -0
- package/dist/mcp-backend.js +668 -0
- package/dist/paths.d.ts +77 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +119 -0
- package/dist/persistent-secrets.d.ts +28 -0
- package/dist/persistent-secrets.d.ts.map +1 -0
- package/dist/persistent-secrets.js +94 -0
- package/dist/persistent-short-code-index.d.ts +14 -0
- package/dist/persistent-short-code-index.d.ts.map +1 -0
- package/dist/persistent-short-code-index.js +39 -0
- package/dist/persistent-stores.d.ts +12 -0
- package/dist/persistent-stores.d.ts.map +1 -0
- package/dist/persistent-stores.js +42 -0
- package/dist/serve-command.d.ts +500 -0
- package/dist/serve-command.d.ts.map +1 -0
- package/dist/serve-command.js +616 -0
- package/dist/serve-fallback.d.ts +64 -0
- package/dist/serve-fallback.d.ts.map +1 -0
- package/dist/serve-fallback.js +122 -0
- package/dist/spawn-cloudflared.d.ts +61 -0
- package/dist/spawn-cloudflared.d.ts.map +1 -0
- package/dist/spawn-cloudflared.js +167 -0
- package/dist/theme-command.d.ts +4 -0
- package/dist/theme-command.d.ts.map +1 -0
- package/dist/theme-command.js +154 -0
- package/dist/theme-file-uploader.d.ts +8 -0
- package/dist/theme-file-uploader.d.ts.map +1 -0
- package/dist/theme-file-uploader.js +58 -0
- package/dist/theme-writer.d.ts +8 -0
- package/dist/theme-writer.d.ts.map +1 -0
- package/dist/theme-writer.js +103 -0
- package/dist/tunnel-provider.d.ts +273 -0
- package/dist/tunnel-provider.d.ts.map +1 -0
- package/dist/tunnel-provider.js +142 -0
- package/package.json +81 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BYOK probe helper — boot-time scan + per-request resolver for
|
|
3
|
+
* `ggui serve`.
|
|
4
|
+
*
|
|
5
|
+
* Two layers, both expressed through a single
|
|
6
|
+
* {@link GenerationBinding}:
|
|
7
|
+
*
|
|
8
|
+
* 1. **Boot scan** — walk providers in a fixed priority
|
|
9
|
+
* (`anthropic` → `openai` → `google` → `openrouter`). First
|
|
10
|
+
* hit at the operator's `'global'` scope (env or
|
|
11
|
+
* `~/.ggui/credentials.json`) names the "default provider"
|
|
12
|
+
* surfaced on the banner. Misses are fine — see (3).
|
|
13
|
+
* 2. **Per-request resolver** — the returned `resolveLlm(ctx)`
|
|
14
|
+
* re-runs the resolver for the chosen provider with
|
|
15
|
+
* `userScope: ctx.appId`, so per-end-user keys stored at the
|
|
16
|
+
* caller's identity scope flip in at request time without a
|
|
17
|
+
* server restart. Multi-tenant `ggui serve` lives off this
|
|
18
|
+
* seam: each authenticated user manages their OWN provider
|
|
19
|
+
* key via `/settings`, the resolver picks it up on the next
|
|
20
|
+
* `ggui_push`.
|
|
21
|
+
* 3. **No-key default** — when the boot scan finds nothing, we
|
|
22
|
+
* STILL return a binding (provider=`anthropic`, model=
|
|
23
|
+
* `claude-haiku-4-5`). Generation stays wired; the
|
|
24
|
+
* no-credentials path now produces a Connect-Claude card
|
|
25
|
+
* stack item via {@link GenerationDeps.onNoCredentials}
|
|
26
|
+
* instead of the broken `codeReady:false` placeholder.
|
|
27
|
+
* Caller-supplied `onNoCredentials` is threaded through
|
|
28
|
+
* verbatim.
|
|
29
|
+
*
|
|
30
|
+
* **Overrides:** `probeGenerationBinding({ resolver, blueprints,
|
|
31
|
+
* onNoCredentials? })` takes the resolver + blueprint provider as
|
|
32
|
+
* inputs so tests can supply fakes without mutating `process.env` /
|
|
33
|
+
* touching the home directory.
|
|
34
|
+
*
|
|
35
|
+
* **Explicit non-scope:** provider override via env / config /
|
|
36
|
+
* flag. The fixed priority is fine for current usage; a follow-up
|
|
37
|
+
* can add `GGUI_GENERATION_PROVIDER` / `ggui.json#generation.model`
|
|
38
|
+
* without re-shaping this seam.
|
|
39
|
+
*/
|
|
40
|
+
import type { BlueprintProvider, GenerationDeps, HandlerContext, LlmProvider, SessionStackEntry } from '@ggui-ai/mcp-server';
|
|
41
|
+
import type { ByokKeyResolution, ByokResolver } from './byok-resolver.js';
|
|
42
|
+
/**
|
|
43
|
+
* Locked default model per provider for the OSS first-run path.
|
|
44
|
+
*
|
|
45
|
+
* These are the "sensible default for an operator who exported
|
|
46
|
+
* `ANTHROPIC_API_KEY` without thinking about which model" — NOT
|
|
47
|
+
* benchmark-tuned recommendations. A later slice wires
|
|
48
|
+
* `ggui.json#generation.model` so operators can pick explicitly;
|
|
49
|
+
* until then these keep the zero-config path honest.
|
|
50
|
+
*
|
|
51
|
+
* Notably absent: `bedrock`. AWS credentials flow through the SDK
|
|
52
|
+
* chain, which the OSS BYOK resolver doesn't cover — the hosted runtime
|
|
53
|
+
* binds Bedrock through its own `GenerationDeps` at the hosted
|
|
54
|
+
* surface.
|
|
55
|
+
*/
|
|
56
|
+
export declare const DEFAULT_MODEL_BY_PROVIDER: Readonly<Record<Exclude<LlmProvider, 'bedrock'>, string>>;
|
|
57
|
+
/**
|
|
58
|
+
* Priority order for BYOK provider probing. The first provider
|
|
59
|
+
* whose credentials resolve wins. Anthropic first is deliberate —
|
|
60
|
+
* the OSS ecosystem defaults to Claude, and most operators export
|
|
61
|
+
* `ANTHROPIC_API_KEY` by default.
|
|
62
|
+
*/
|
|
63
|
+
export declare const PROVIDER_PROBE_ORDER: readonly Exclude<LlmProvider, 'bedrock'>[];
|
|
64
|
+
export interface ProbeGenerationBindingOptions {
|
|
65
|
+
readonly resolver: ByokResolver;
|
|
66
|
+
readonly blueprints: BlueprintProvider;
|
|
67
|
+
/** Override the probe order. Tests use this to pin the winner. */
|
|
68
|
+
readonly providerOrder?: readonly Exclude<LlmProvider, 'bedrock'>[];
|
|
69
|
+
/**
|
|
70
|
+
* Optional no-credentials fallback hook threaded straight onto
|
|
71
|
+
* {@link GenerationDeps.onNoCredentials}. The CLI builds this
|
|
72
|
+
* from the operator's resolved settings URL so the
|
|
73
|
+
* Connect-Claude card points at THIS server's `/settings`.
|
|
74
|
+
* Tests + programmatic embedders that want the legacy error
|
|
75
|
+
* envelope leave it absent.
|
|
76
|
+
*/
|
|
77
|
+
readonly onNoCredentials?: (ctx: HandlerContext, story: {
|
|
78
|
+
readonly intent: string;
|
|
79
|
+
readonly stackItemId: string;
|
|
80
|
+
readonly nowIso: string;
|
|
81
|
+
}) => SessionStackEntry | null | Promise<SessionStackEntry | null>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Outcome of the boot probe. Always returned (no `null` shape) —
|
|
85
|
+
* the per-request `resolveLlm` walks the provider order with
|
|
86
|
+
* `userScope: ctx.appId` so end-user keys can flip in even when
|
|
87
|
+
* the operator's boot scan came up empty.
|
|
88
|
+
*
|
|
89
|
+
* `bootResolved: false` is the operator-facing "no platform key"
|
|
90
|
+
* signal: banner copy + the no-credentials fallback path are
|
|
91
|
+
* conditioned on it.
|
|
92
|
+
*/
|
|
93
|
+
export interface GenerationBinding {
|
|
94
|
+
readonly generation: GenerationDeps;
|
|
95
|
+
readonly provider: LlmProvider;
|
|
96
|
+
readonly model: string;
|
|
97
|
+
/**
|
|
98
|
+
* `true` when the boot scan resolved a key at the operator's
|
|
99
|
+
* `'global'` scope (env or credentials-file). `false` means
|
|
100
|
+
* generation will fall back to either the per-end-user key
|
|
101
|
+
* (multi-tenant) or the {@link GenerationDeps.onNoCredentials}
|
|
102
|
+
* card on first call.
|
|
103
|
+
*/
|
|
104
|
+
readonly bootResolved: boolean;
|
|
105
|
+
/** Boot-scan key source — only meaningful when `bootResolved`. */
|
|
106
|
+
readonly keySource?: ByokKeyResolution['source'];
|
|
107
|
+
/** Env-var name that produced the boot-scan hit, when applicable. */
|
|
108
|
+
readonly keyEnvName?: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Build a `GenerationBinding` whose `resolveLlm` does live BYOK
|
|
112
|
+
* lookup at request time (env + global → user-scope), threading
|
|
113
|
+
* `ctx.appId` into the resolver as `userScope`.
|
|
114
|
+
*
|
|
115
|
+
* Always returns a binding — even when no provider resolved at
|
|
116
|
+
* boot. The caller supplies `onNoCredentials` to render a
|
|
117
|
+
* Connect-Claude card on misses; absent that hook, misses surface
|
|
118
|
+
* the legacy "no-credentials" error envelope.
|
|
119
|
+
*/
|
|
120
|
+
export declare function probeGenerationBinding(opts: ProbeGenerationBindingOptions): Promise<GenerationBinding>;
|
|
121
|
+
/**
|
|
122
|
+
* Render a single operator-facing banner line describing the
|
|
123
|
+
* generation binding. Always returns a string — when boot didn't
|
|
124
|
+
* resolve a key, the line still names the default provider/model
|
|
125
|
+
* the per-request resolver will try first, so the operator
|
|
126
|
+
* understands which provider's key the user-facing
|
|
127
|
+
* `/settings` page is steering toward.
|
|
128
|
+
*
|
|
129
|
+
* Format:
|
|
130
|
+
* `generation: anthropic / claude-haiku-4-5 (env: ANTHROPIC_API_KEY)`
|
|
131
|
+
* `generation: openai / gpt-4o (credentials-file)`
|
|
132
|
+
* `generation: anthropic / claude-haiku-4-5 (no boot key — per-user fallback)`
|
|
133
|
+
*/
|
|
134
|
+
export declare function describeGenerationBinding(binding: GenerationBinding): string;
|
|
135
|
+
//# sourceMappingURL=generation-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation-probe.d.ts","sourceRoot":"","sources":["../src/generation-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,WAAW,EAGX,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACb,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAC9C,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,CAUhD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,EAC1B,CAAC;AAElD,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,kEAAkE;IAClE,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,CAAC;IACpE;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE;QACL,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,KACE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;CACnE;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACjD,qEAAqE;IACrE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,6BAA6B,GAClC,OAAO,CAAC,iBAAiB,CAAC,CA0E5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,iBAAiB,GACzB,MAAM,CAWR"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createUiGenerator } from '@ggui-ai/ui-gen';
|
|
2
|
+
/**
|
|
3
|
+
* Locked default model per provider for the OSS first-run path.
|
|
4
|
+
*
|
|
5
|
+
* These are the "sensible default for an operator who exported
|
|
6
|
+
* `ANTHROPIC_API_KEY` without thinking about which model" — NOT
|
|
7
|
+
* benchmark-tuned recommendations. A later slice wires
|
|
8
|
+
* `ggui.json#generation.model` so operators can pick explicitly;
|
|
9
|
+
* until then these keep the zero-config path honest.
|
|
10
|
+
*
|
|
11
|
+
* Notably absent: `bedrock`. AWS credentials flow through the SDK
|
|
12
|
+
* chain, which the OSS BYOK resolver doesn't cover — the hosted runtime
|
|
13
|
+
* binds Bedrock through its own `GenerationDeps` at the hosted
|
|
14
|
+
* surface.
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_MODEL_BY_PROVIDER = {
|
|
17
|
+
// Slash-prefixed `<provider>/<model>` form — `getProviderForModel`
|
|
18
|
+
// expects it; bare names trip the "Unrecognized model format" warning
|
|
19
|
+
// and silently default to anthropic. Pre-matrix the openai/google
|
|
20
|
+
// defaults were also bare; this fixes them as part of the model bump.
|
|
21
|
+
anthropic: 'anthropic/claude-haiku-4-5',
|
|
22
|
+
openai: 'openai/gpt-5.5-2026-04-23',
|
|
23
|
+
google: 'google/gemini-3.5-flash',
|
|
24
|
+
openrouter: 'anthropic/claude-haiku-4.5',
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Priority order for BYOK provider probing. The first provider
|
|
28
|
+
* whose credentials resolve wins. Anthropic first is deliberate —
|
|
29
|
+
* the OSS ecosystem defaults to Claude, and most operators export
|
|
30
|
+
* `ANTHROPIC_API_KEY` by default.
|
|
31
|
+
*/
|
|
32
|
+
export const PROVIDER_PROBE_ORDER = ['anthropic', 'openai', 'google', 'openrouter'];
|
|
33
|
+
/**
|
|
34
|
+
* Build a `GenerationBinding` whose `resolveLlm` does live BYOK
|
|
35
|
+
* lookup at request time (env + global → user-scope), threading
|
|
36
|
+
* `ctx.appId` into the resolver as `userScope`.
|
|
37
|
+
*
|
|
38
|
+
* Always returns a binding — even when no provider resolved at
|
|
39
|
+
* boot. The caller supplies `onNoCredentials` to render a
|
|
40
|
+
* Connect-Claude card on misses; absent that hook, misses surface
|
|
41
|
+
* the legacy "no-credentials" error envelope.
|
|
42
|
+
*/
|
|
43
|
+
export async function probeGenerationBinding(opts) {
|
|
44
|
+
const order = opts.providerOrder ?? PROVIDER_PROBE_ORDER;
|
|
45
|
+
// Boot scan — surfaces the banner-line provider/source. If
|
|
46
|
+
// multiple providers have boot-time keys, the first in priority
|
|
47
|
+
// order wins (matches pre-H2 behavior).
|
|
48
|
+
let bootHit = null;
|
|
49
|
+
for (const provider of order) {
|
|
50
|
+
const resolution = await opts.resolver.resolve(provider);
|
|
51
|
+
if (resolution) {
|
|
52
|
+
bootHit = { ...resolution, provider };
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Default provider locks to anthropic on boot-miss — matches the
|
|
57
|
+
// OSS "Claude first" posture. The Connect-Claude card flow steers
|
|
58
|
+
// misses toward an Anthropic key (env/file/OAuth); nothing in the
|
|
59
|
+
// contract prevents users from pasting an OpenAI/Google key
|
|
60
|
+
// instead, but the boot-time provider for THIS server stays
|
|
61
|
+
// anthropic until the operator restarts with a different boot
|
|
62
|
+
// hit.
|
|
63
|
+
const defaultProvider = bootHit?.provider ?? 'anthropic';
|
|
64
|
+
const defaultModel = DEFAULT_MODEL_BY_PROVIDER[defaultProvider];
|
|
65
|
+
// Full-harness wire-up: `createUiGenerator` runs the same
|
|
66
|
+
// multi-turn coding agent + self-check loop the bench validates;
|
|
67
|
+
// `dispatchGeneration` returns compiled JS on `componentCode`.
|
|
68
|
+
const uiGenerator = createUiGenerator();
|
|
69
|
+
const resolveLlm = async (ctx) => {
|
|
70
|
+
// Per-call BYOK with `userScope: ctx.appId` — env + global
|
|
71
|
+
// (operator) checked first, then the caller's identity scope
|
|
72
|
+
// (end-user). Multi-tenant + Anthropic-OAuth flows store
|
|
73
|
+
// user-supplied bundles under `userId` here.
|
|
74
|
+
const resolution = await opts.resolver.resolve(defaultProvider, {
|
|
75
|
+
userScope: ctx.appId,
|
|
76
|
+
});
|
|
77
|
+
if (!resolution)
|
|
78
|
+
return null;
|
|
79
|
+
return {
|
|
80
|
+
selection: { provider: defaultProvider, model: defaultModel },
|
|
81
|
+
providerKey: { provider: defaultProvider, key: resolution.key },
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
const generation = {
|
|
85
|
+
uiGenerator,
|
|
86
|
+
resolveLlm,
|
|
87
|
+
blueprints: opts.blueprints,
|
|
88
|
+
...(opts.onNoCredentials ? { onNoCredentials: opts.onNoCredentials } : {}),
|
|
89
|
+
};
|
|
90
|
+
const result = bootHit
|
|
91
|
+
? {
|
|
92
|
+
generation,
|
|
93
|
+
provider: defaultProvider,
|
|
94
|
+
model: defaultModel,
|
|
95
|
+
bootResolved: true,
|
|
96
|
+
keySource: bootHit.source,
|
|
97
|
+
...(bootHit.envName !== undefined
|
|
98
|
+
? { keyEnvName: bootHit.envName }
|
|
99
|
+
: {}),
|
|
100
|
+
}
|
|
101
|
+
: {
|
|
102
|
+
generation,
|
|
103
|
+
provider: defaultProvider,
|
|
104
|
+
model: defaultModel,
|
|
105
|
+
bootResolved: false,
|
|
106
|
+
};
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Render a single operator-facing banner line describing the
|
|
111
|
+
* generation binding. Always returns a string — when boot didn't
|
|
112
|
+
* resolve a key, the line still names the default provider/model
|
|
113
|
+
* the per-request resolver will try first, so the operator
|
|
114
|
+
* understands which provider's key the user-facing
|
|
115
|
+
* `/settings` page is steering toward.
|
|
116
|
+
*
|
|
117
|
+
* Format:
|
|
118
|
+
* `generation: anthropic / claude-haiku-4-5 (env: ANTHROPIC_API_KEY)`
|
|
119
|
+
* `generation: openai / gpt-4o (credentials-file)`
|
|
120
|
+
* `generation: anthropic / claude-haiku-4-5 (no boot key — per-user fallback)`
|
|
121
|
+
*/
|
|
122
|
+
export function describeGenerationBinding(binding) {
|
|
123
|
+
if (!binding.bootResolved) {
|
|
124
|
+
return `generation: ${binding.provider} / ${binding.model} (no boot key — per-user fallback)`;
|
|
125
|
+
}
|
|
126
|
+
const src = binding.keySource === 'env'
|
|
127
|
+
? binding.keyEnvName
|
|
128
|
+
? `env: ${binding.keyEnvName}`
|
|
129
|
+
: 'env'
|
|
130
|
+
: 'credentials-file';
|
|
131
|
+
return `generation: ${binding.provider} / ${binding.model} (${src})`;
|
|
132
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/** Artifact-kind discriminator — the verb the operator typed
|
|
2
|
+
* (`gadget` vs `blueprint`). Enforced against the registry-served
|
|
3
|
+
* manifest's `kind` discriminator. */
|
|
4
|
+
export type ArtifactKind = 'gadget' | 'blueprint';
|
|
5
|
+
/**
|
|
6
|
+
* Resolved flags accepted by {@link runArtifactInstall}. Built by
|
|
7
|
+
* {@link parseArtifactInstallFlags} from argv or constructed directly
|
|
8
|
+
* from object literals in tests.
|
|
9
|
+
*/
|
|
10
|
+
export interface InstallFlags {
|
|
11
|
+
/** CLI verb the operator typed — enforced against the manifest kind. */
|
|
12
|
+
readonly kind: ArtifactKind;
|
|
13
|
+
/** `@scope/name` form, e.g. `@my-org/weather-card`. */
|
|
14
|
+
readonly artifactId: string;
|
|
15
|
+
/** SemVer string the user typed after `@`. Required. */
|
|
16
|
+
readonly version: string;
|
|
17
|
+
/** Override the registry URL — highest precedence. */
|
|
18
|
+
readonly registry?: string;
|
|
19
|
+
/** Skip interactive `publicEnv` prompts; missing required keys → warning + exit 0. */
|
|
20
|
+
readonly noPrompt: boolean;
|
|
21
|
+
/** Fail-hard on skipped signature verification (vs. warn + continue). */
|
|
22
|
+
readonly strict: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Optional OIDC-identity assertion for sigstore-signed gadgets.
|
|
25
|
+
* When set, install demands the bundle's Fulcio leaf-cert subject
|
|
26
|
+
* matches the supplied pattern. Pass as a literal subject string
|
|
27
|
+
* (e.g. `alice@example.com`); the signature-verify implementation
|
|
28
|
+
* decides literal-vs-regex semantics. No effect on Ed25519-signed
|
|
29
|
+
* gadgets — those root in the registry-pinned `authorPublicKey`.
|
|
30
|
+
*/
|
|
31
|
+
readonly verifyIdentity?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* `{ error: '__help__' }` carries the help-requested case so the CLI
|
|
35
|
+
* driver can write {@link GADGET_INSTALL_HELP} to stdout without
|
|
36
|
+
* misclassifying it as a usage error. All other `error` strings are
|
|
37
|
+
* stderr-bound diagnostics.
|
|
38
|
+
*/
|
|
39
|
+
export type ParsedInstallFlags = InstallFlags | {
|
|
40
|
+
error: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Build verb-specific help text. Takes the `kind` so the rendered
|
|
44
|
+
* lines say `ggui gadget install` / `ggui blueprint install` rather
|
|
45
|
+
* than a generic placeholder.
|
|
46
|
+
*/
|
|
47
|
+
export declare function buildInstallHelp(kind: ArtifactKind): string;
|
|
48
|
+
/**
|
|
49
|
+
* Parse `args` (the argv tail after `ggui {gadget,blueprint} install`)
|
|
50
|
+
* into {@link InstallFlags}. The `kind` parameter is the verb the
|
|
51
|
+
* operator typed — it's stamped onto the returned flags so the
|
|
52
|
+
* downstream {@link runArtifactInstall} can enforce manifest-kind
|
|
53
|
+
* alignment without re-parsing argv.
|
|
54
|
+
*
|
|
55
|
+
* Returns an `{ error }` object on usage failure so the CLI driver
|
|
56
|
+
* branches without try/catch. `'__help__'` is the sentinel for
|
|
57
|
+
* `--help`; every other `error` is stderr-bound copy.
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseArtifactInstallFlags(kind: ArtifactKind, args: readonly string[]): ParsedInstallFlags;
|
|
60
|
+
/**
|
|
61
|
+
* Dependency seams for {@link runArtifactInstall}. All IO threads through
|
|
62
|
+
* here so tests stub `fetch`, `cwd`, env access, and stdout/stderr
|
|
63
|
+
* writers without touching globals.
|
|
64
|
+
*/
|
|
65
|
+
export interface RunArtifactInstallDeps {
|
|
66
|
+
/** Resolved working directory. */
|
|
67
|
+
readonly cwd?: string;
|
|
68
|
+
/** Environment view — defaults to `process.env`. */
|
|
69
|
+
readonly env?: Readonly<Partial<Record<string, string | undefined>>>;
|
|
70
|
+
/** HTTP fetch implementation. Defaults to `globalThis.fetch`. */
|
|
71
|
+
readonly fetch?: typeof fetch;
|
|
72
|
+
/** stdout sink. Defaults to `process.stdout.write`. */
|
|
73
|
+
readonly stdout?: (line: string) => void;
|
|
74
|
+
/** stderr sink. Defaults to `process.stderr.write`. */
|
|
75
|
+
readonly stderr?: (line: string) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Public-env prompter. Returns the value the operator typed for the
|
|
78
|
+
* given key, or `null` if they declined. Defaults to a stdin TTY
|
|
79
|
+
* reader in production. Tests stub the function.
|
|
80
|
+
*
|
|
81
|
+
* Skipped entirely when {@link InstallFlags.noPrompt} is true —
|
|
82
|
+
* missing required keys surface as warnings instead.
|
|
83
|
+
*/
|
|
84
|
+
readonly promptForEnv?: (key: string) => Promise<string | null>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Run the install flow end-to-end. Returns a numeric exit code so the
|
|
88
|
+
* router writes it directly to `process.exit`.
|
|
89
|
+
*
|
|
90
|
+
* Exit codes:
|
|
91
|
+
* - 0 — success (gadget installed, ggui.json updated) OR blueprint
|
|
92
|
+
* fetched + verified (no write target yet, see step 10).
|
|
93
|
+
* - 1 — operational failure (registry 404 / 410, manifest invalid,
|
|
94
|
+
* signature mismatch, SRI mismatch, etc.).
|
|
95
|
+
* - 2 — usage error (bad flags, no ggui.json found).
|
|
96
|
+
*/
|
|
97
|
+
export declare function runArtifactInstall(flags: InstallFlags, deps?: RunArtifactInstallDeps): Promise<number>;
|
|
98
|
+
/**
|
|
99
|
+
* Destination subdirectory under the project root for marketplace-
|
|
100
|
+
* installed blueprints. Chosen so the existing `blueprints.include`
|
|
101
|
+
* glob loader picks them up without any code change — `discoverLocalUis`
|
|
102
|
+
* walks every glob, parses every matched `ggui.ui.json`, and emits
|
|
103
|
+
* `DiscoveredUi` entries. The "registry-installed" subtree is just
|
|
104
|
+
* one more glob root.
|
|
105
|
+
*/
|
|
106
|
+
export declare const INSTALLED_BLUEPRINTS_SUBDIR = ".ggui/installed-blueprints";
|
|
107
|
+
/**
|
|
108
|
+
* Glob pattern auto-appended to `ggui.json#blueprints.include` so the
|
|
109
|
+
* OSS server discovers materialized blueprints alongside hand-authored
|
|
110
|
+
* ones. Idempotent — install only adds the entry once.
|
|
111
|
+
*/
|
|
112
|
+
export declare const INSTALLED_BLUEPRINTS_GLOB: ".ggui/installed-blueprints/**/ggui.ui.json";
|
|
113
|
+
/**
|
|
114
|
+
* Predicate: "is this discovered-UI manifest path inside
|
|
115
|
+
* `.ggui/installed-blueprints/`?".
|
|
116
|
+
*
|
|
117
|
+
* Cross-platform — matches both Unix (`/.ggui/installed-blueprints/`)
|
|
118
|
+
* and Windows (`\.ggui\installed-blueprints\`) separators. A
|
|
119
|
+
* Unix-only `includes('/.ggui/installed-blueprints/')` check would
|
|
120
|
+
* silently match zero entries on Windows, where `tinyglobby` returns
|
|
121
|
+
* `\`-separated absolute paths.
|
|
122
|
+
*
|
|
123
|
+
* Defined once here, next to the constant it is derived from. Both
|
|
124
|
+
* `cli.ts` (filter discovered UIs) and `mcp-backend.ts` (project to
|
|
125
|
+
* bridge entries) consume it, so the two filter sites cannot drift.
|
|
126
|
+
*/
|
|
127
|
+
export declare function isInstalledBlueprintPath(manifestPath: string): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Compute the directory leaf for a given blueprint manifest. Safe for
|
|
130
|
+
* filesystem paths — `<scope-without-@>__<name>__<version>`, no slashes
|
|
131
|
+
* or colons (the version's `.` is fine on every supported FS). The
|
|
132
|
+
* `__` separator avoids confusion with scope names that contain `-`.
|
|
133
|
+
*/
|
|
134
|
+
export declare function blueprintInstallSubdir(args: {
|
|
135
|
+
scope: string;
|
|
136
|
+
name: string;
|
|
137
|
+
version: string;
|
|
138
|
+
}): string;
|
|
139
|
+
/**
|
|
140
|
+
* UI manifest `id` for a marketplace-installed blueprint. Must satisfy
|
|
141
|
+
* `UiManifestV1#id` (`^[A-Za-z0-9][A-Za-z0-9._:-]*$`). We use
|
|
142
|
+
* `<scope-bare>:<name>:<version>` — colons + dots + hyphens + alphanum
|
|
143
|
+
* are all admitted.
|
|
144
|
+
*/
|
|
145
|
+
export declare function blueprintUiManifestId(args: {
|
|
146
|
+
scope: string;
|
|
147
|
+
name: string;
|
|
148
|
+
version: string;
|
|
149
|
+
}): string;
|
|
150
|
+
//# sourceMappingURL=artifact-install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifact-install.d.ts","sourceRoot":"","sources":["../../src/internal/artifact-install.ts"],"names":[],"mappings":"AAqFA;;sCAEsC;AACtC,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;AAoBlD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAgD3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,kBAAkB,CAsGpB;AA6DD;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACrE,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACjE;AAmMD;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,YAAY,EACnB,IAAI,GAAE,sBAA2B,GAChC,OAAO,CAAC,MAAM,CAAC,CA8XjB;AAmID;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,+BAA+B,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,8CACqB,CAAC;AAE5D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAOtE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAGT;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAGT"}
|