@ggui-ai/cli 0.19.0 → 0.21.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/dist/byok-resolver.d.ts +8 -0
- package/dist/byok-resolver.d.ts.map +1 -1
- package/dist/byok-resolver.js +9 -0
- package/dist/generation-probe.d.ts +2 -0
- package/dist/generation-probe.d.ts.map +1 -1
- package/dist/generation-probe.js +7 -1
- package/dist/provider-key-command.d.ts +14 -2
- package/dist/provider-key-command.d.ts.map +1 -1
- package/dist/provider-key-command.js +27 -1
- package/package.json +17 -17
package/dist/byok-resolver.d.ts
CHANGED
|
@@ -78,6 +78,14 @@ export interface ByokKeyResolution {
|
|
|
78
78
|
* that's what fired, instead of a generic "google env".
|
|
79
79
|
*/
|
|
80
80
|
readonly envName?: string;
|
|
81
|
+
/**
|
|
82
|
+
* ggui#1132 — env names in this provider's alias list that were ALSO set,
|
|
83
|
+
* to a DIFFERENT value, and lost to `envName` under the locked precedence.
|
|
84
|
+
* Names only, never values. A stale key in a shadowed alias is exactly
|
|
85
|
+
* the silent failure this exists to make loud: a rotated `GEMINI_API_KEY`
|
|
86
|
+
* that a stale `GOOGLE_API_KEY` beats. Absent ⇒ no conflict.
|
|
87
|
+
*/
|
|
88
|
+
readonly shadowedEnvNames?: readonly string[];
|
|
81
89
|
}
|
|
82
90
|
export interface ByokResolverOptions {
|
|
83
91
|
/**
|
|
@@ -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;
|
|
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"}
|
package/dist/byok-resolver.js
CHANGED
|
@@ -59,11 +59,20 @@ export function createByokResolver(opts = {}) {
|
|
|
59
59
|
for (const name of envNames) {
|
|
60
60
|
const value = env[name];
|
|
61
61
|
if (value !== undefined && value.length > 0) {
|
|
62
|
+
// ggui#1132: name every OTHER alias that is set to a different
|
|
63
|
+
// value — it lost silently under the locked precedence.
|
|
64
|
+
const shadowed = envNames.filter((other) => {
|
|
65
|
+
if (other === name)
|
|
66
|
+
return false;
|
|
67
|
+
const v = env[other];
|
|
68
|
+
return v !== undefined && v.length > 0 && v !== value;
|
|
69
|
+
});
|
|
62
70
|
return {
|
|
63
71
|
key: value,
|
|
64
72
|
source: 'env',
|
|
65
73
|
provider,
|
|
66
74
|
envName: name,
|
|
75
|
+
...(shadowed.length > 0 ? { shadowedEnvNames: shadowed } : {}),
|
|
67
76
|
};
|
|
68
77
|
}
|
|
69
78
|
}
|
|
@@ -174,6 +174,8 @@ export interface GenerationBinding {
|
|
|
174
174
|
readonly keySource?: ByokKeyResolution['source'];
|
|
175
175
|
/** Env-var name that produced the boot-scan hit, when applicable. */
|
|
176
176
|
readonly keyEnvName?: string;
|
|
177
|
+
/** ggui#1132 — aliases set to a different value that lost to `keyEnvName`; names only. */
|
|
178
|
+
readonly keyShadowedEnvNames?: readonly string[];
|
|
177
179
|
}
|
|
178
180
|
/**
|
|
179
181
|
* Build a `GenerationBinding` whose `resolveLlm` does live BYOK
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generation-probe.d.ts","sourceRoot":"","sources":["../src/generation-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,WAAW,EACX,QAAQ,EAGR,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EACV,iBAAiB,EACjB,YAAY,EACb,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;GAaG;AACH;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAC9C,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,EAAE,QAAQ,CAAC,CAMlD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,EAC1B,CAAC;AAElD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,0BAA0B,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,MAAM,4BAA4B,GACpC;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,UAAU,CAAA;CAAE,GACzF;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,aAAa,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC9C,GAAG,4BAA4B,CAW/B;AAED,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;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC;IACpC;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,CACzB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE;QACL,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,KACE,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CACvD;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;
|
|
1
|
+
{"version":3,"file":"generation-probe.d.ts","sourceRoot":"","sources":["../src/generation-probe.ts"],"names":[],"mappings":"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"}
|
package/dist/generation-probe.js
CHANGED
|
@@ -150,6 +150,9 @@ export async function probeGenerationBinding(opts) {
|
|
|
150
150
|
...(bootHit.envName !== undefined
|
|
151
151
|
? { keyEnvName: bootHit.envName }
|
|
152
152
|
: {}),
|
|
153
|
+
...(bootHit.shadowedEnvNames !== undefined
|
|
154
|
+
? { keyShadowedEnvNames: bootHit.shadowedEnvNames }
|
|
155
|
+
: {}),
|
|
153
156
|
}
|
|
154
157
|
: {
|
|
155
158
|
generation,
|
|
@@ -181,5 +184,8 @@ export function describeGenerationBinding(binding) {
|
|
|
181
184
|
? `env: ${binding.keyEnvName}`
|
|
182
185
|
: 'env'
|
|
183
186
|
: 'credentials-file';
|
|
184
|
-
|
|
187
|
+
const conflict = binding.keyShadowedEnvNames !== undefined && binding.keyEnvName !== undefined
|
|
188
|
+
? ` — ${binding.keyEnvName} won; ${binding.keyShadowedEnvNames.join(', ')} also set and differs (rotate both or unset one, ggui#1132)`
|
|
189
|
+
: '';
|
|
190
|
+
return `generation: ${binding.provider} / ${binding.model} (${src})${conflict}`;
|
|
185
191
|
}
|
|
@@ -30,7 +30,13 @@ export declare function envVarForProvider(provider: ByokProvider): string;
|
|
|
30
30
|
*
|
|
31
31
|
* - `anthropic` → `ANTHROPIC_API_KEY`
|
|
32
32
|
* - `openai` → `OPENAI_API_KEY`
|
|
33
|
-
* - `google` → `GOOGLE_API_KEY` (primary), then `GEMINI_API_KEY` (fallback)
|
|
33
|
+
* - `google` → `GOOGLE_API_KEY` (primary), then `GEMINI_API_KEY` (fallback).
|
|
34
|
+
* The precedence is locked (Google's own SDKs prefer
|
|
35
|
+
* `GOOGLE_API_KEY` when both are set, and the hosted key
|
|
36
|
+
* routes mirror this order). When both are set to DIFFERENT
|
|
37
|
+
* values the loser is named — see {@link describeAliasConflict}
|
|
38
|
+
* — because a stale key in the shadowed alias is the failure
|
|
39
|
+
* that otherwise happens silently (ggui#1132).
|
|
34
40
|
* - `openrouter` → `OPENROUTER_API_KEY`
|
|
35
41
|
*
|
|
36
42
|
* Order matches `byok-resolver.ts` so that the key the cloud receives is
|
|
@@ -39,7 +45,13 @@ export declare function envVarForProvider(provider: ByokProvider): string;
|
|
|
39
45
|
* Returns `undefined` when no non-empty value is found.
|
|
40
46
|
*/
|
|
41
47
|
export declare function readKeyFromEnv(provider: ByokProvider, env?: Readonly<Record<string, string | undefined>>): string | undefined;
|
|
42
|
-
|
|
48
|
+
/**
|
|
49
|
+
* ggui#1132 — one line naming an alias conflict, or `undefined` when there is
|
|
50
|
+
* none. Only `google` has aliases. Names only, never values: the line is
|
|
51
|
+
* printed to stderr by `ggui provider-key set` and by the `ggui serve` banner.
|
|
52
|
+
*/
|
|
53
|
+
export declare function describeAliasConflict(provider: ByokProvider, env?: Readonly<Record<string, string | undefined>>): string | undefined;
|
|
54
|
+
export declare const PROVIDER_KEY_HELP = "ggui provider-key \u2014 manage cloud provider API keys for a ggui app\n\nUsage:\n ggui provider-key set --app <appId> [--provider <name>]\n\nSubcommands:\n set Push a provider API key from the appropriate env var to the cloud app.\n The provider is derived from ggui.json#generation.model unless\n --provider is given explicitly.\n\n Supported providers: anthropic, openai, google, openrouter.\n (bedrock is IAM-only \u2014 no plaintext key to push.)\n\n Reads the key from env:\n ANTHROPIC_API_KEY (anthropic)\n OPENAI_API_KEY (openai)\n GOOGLE_API_KEY (google, primary); GEMINI_API_KEY (fallback)\n \u2014 if both are set and differ, the shadowed one is named\n OPENROUTER_API_KEY (openrouter)\n\nOptions:\n --app <appId> Target app ID (required).\n --provider <name> Override provider (default: derived from ggui.json).\n --help, -h Show this help.\n";
|
|
43
55
|
/**
|
|
44
56
|
* Entry point for `ggui provider-key <subcommand> [options]`.
|
|
45
57
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-key-command.d.ts","sourceRoot":"","sources":["../src/provider-key-command.ts"],"names":[],"mappings":"AAqBA,+DAA+D;AAC/D,eAAO,MAAM,cAAc,0DAA2D,CAAC;AAEvF,+CAA+C;AAC/C,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAU3D;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,OAAO,EACjB,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA8ClC;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAWhE;AAED
|
|
1
|
+
{"version":3,"file":"provider-key-command.d.ts","sourceRoot":"","sources":["../src/provider-key-command.ts"],"names":[],"mappings":"AAqBA,+DAA+D;AAC/D,eAAO,MAAM,cAAc,0DAA2D,CAAC;AAEvF,+CAA+C;AAC/C,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAU3D;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,OAAO,EACjB,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,YAAY,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA8ClC;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAWhE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,YAAY,EACtB,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GAC9D,MAAM,GAAG,SAAS,CAWpB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,EACtB,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAe,GAC9D,MAAM,GAAG,SAAS,CAUpB;AAMD,eAAO,MAAM,iBAAiB,+9BAwB7B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,QAAQ,GAAE,MAAsB,GAC/B,OAAO,CAAC,MAAM,CAAC,CAiFjB"}
|
|
@@ -103,7 +103,13 @@ export function envVarForProvider(provider) {
|
|
|
103
103
|
*
|
|
104
104
|
* - `anthropic` → `ANTHROPIC_API_KEY`
|
|
105
105
|
* - `openai` → `OPENAI_API_KEY`
|
|
106
|
-
* - `google` → `GOOGLE_API_KEY` (primary), then `GEMINI_API_KEY` (fallback)
|
|
106
|
+
* - `google` → `GOOGLE_API_KEY` (primary), then `GEMINI_API_KEY` (fallback).
|
|
107
|
+
* The precedence is locked (Google's own SDKs prefer
|
|
108
|
+
* `GOOGLE_API_KEY` when both are set, and the hosted key
|
|
109
|
+
* routes mirror this order). When both are set to DIFFERENT
|
|
110
|
+
* values the loser is named — see {@link describeAliasConflict}
|
|
111
|
+
* — because a stale key in the shadowed alias is the failure
|
|
112
|
+
* that otherwise happens silently (ggui#1132).
|
|
107
113
|
* - `openrouter` → `OPENROUTER_API_KEY`
|
|
108
114
|
*
|
|
109
115
|
* Order matches `byok-resolver.ts` so that the key the cloud receives is
|
|
@@ -122,6 +128,22 @@ export function readKeyFromEnv(provider, env = process.env) {
|
|
|
122
128
|
}
|
|
123
129
|
return undefined;
|
|
124
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* ggui#1132 — one line naming an alias conflict, or `undefined` when there is
|
|
133
|
+
* none. Only `google` has aliases. Names only, never values: the line is
|
|
134
|
+
* printed to stderr by `ggui provider-key set` and by the `ggui serve` banner.
|
|
135
|
+
*/
|
|
136
|
+
export function describeAliasConflict(provider, env = process.env) {
|
|
137
|
+
if (provider !== 'google')
|
|
138
|
+
return undefined;
|
|
139
|
+
const [primary, fallback] = ['GOOGLE_API_KEY', 'GEMINI_API_KEY'];
|
|
140
|
+
const a = env[primary];
|
|
141
|
+
const b = env[fallback];
|
|
142
|
+
if (!a || !b || a === b)
|
|
143
|
+
return undefined;
|
|
144
|
+
return (`${primary} won; ${fallback} is also set and differs — ` +
|
|
145
|
+
`a stale key in the shadowed alias wins silently, so rotate both or unset one (ggui#1132).`);
|
|
146
|
+
}
|
|
125
147
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
126
148
|
// Command runner
|
|
127
149
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -142,6 +164,7 @@ Subcommands:
|
|
|
142
164
|
ANTHROPIC_API_KEY (anthropic)
|
|
143
165
|
OPENAI_API_KEY (openai)
|
|
144
166
|
GOOGLE_API_KEY (google, primary); GEMINI_API_KEY (fallback)
|
|
167
|
+
— if both are set and differ, the shadowed one is named
|
|
145
168
|
OPENROUTER_API_KEY (openrouter)
|
|
146
169
|
|
|
147
170
|
Options:
|
|
@@ -201,6 +224,9 @@ export async function runProviderKeyCommand(args, startDir = process.cwd()) {
|
|
|
201
224
|
const provider = providerResult;
|
|
202
225
|
// ── Read key from env ────────────────────────────────────────────────────
|
|
203
226
|
const key = readKeyFromEnv(provider);
|
|
227
|
+
const conflict = describeAliasConflict(provider);
|
|
228
|
+
if (conflict !== undefined)
|
|
229
|
+
process.stderr.write(`ggui provider-key set: ${conflict}\n`);
|
|
204
230
|
if (!key) {
|
|
205
231
|
const primaryVar = envVarForProvider(provider);
|
|
206
232
|
const hint = provider === 'google'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ggui-ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.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.
|
|
41
|
-
"@ggui-ai/artifact-manifest": "0.
|
|
42
|
-
"@ggui-ai/design": "0.
|
|
43
|
-
"@ggui-ai/dev-stack": "0.
|
|
44
|
-
"@ggui-ai/gadget-signing": "0.
|
|
45
|
-
"@ggui-ai/
|
|
46
|
-
"@ggui-ai/
|
|
47
|
-
"@ggui-ai/mcp-server
|
|
48
|
-
"@ggui-ai/
|
|
49
|
-
"@ggui-ai/
|
|
50
|
-
"@ggui-ai/project-config": "0.
|
|
51
|
-
"@ggui-ai/
|
|
52
|
-
"@ggui-ai/
|
|
53
|
-
"@ggui-ai/
|
|
54
|
-
"@ggui-ai/
|
|
55
|
-
"@ggui-ai/registry
|
|
40
|
+
"@ggui-ai/agent-runtime": "0.21.0",
|
|
41
|
+
"@ggui-ai/artifact-manifest": "0.21.0",
|
|
42
|
+
"@ggui-ai/design": "0.21.0",
|
|
43
|
+
"@ggui-ai/dev-stack": "0.21.0",
|
|
44
|
+
"@ggui-ai/gadget-signing": "0.21.0",
|
|
45
|
+
"@ggui-ai/embedding-local": "0.21.0",
|
|
46
|
+
"@ggui-ai/mcp-server-core": "0.21.0",
|
|
47
|
+
"@ggui-ai/mcp-server": "0.21.0",
|
|
48
|
+
"@ggui-ai/mcp-server-handlers": "0.21.0",
|
|
49
|
+
"@ggui-ai/preview-a2ui": "0.21.0",
|
|
50
|
+
"@ggui-ai/project-config": "0.21.0",
|
|
51
|
+
"@ggui-ai/protocol": "0.21.0",
|
|
52
|
+
"@ggui-ai/iframe-runtime": "0.21.0",
|
|
53
|
+
"@ggui-ai/registry-core": "0.21.0",
|
|
54
|
+
"@ggui-ai/ui-gen": "0.21.0",
|
|
55
|
+
"@ggui-ai/ui-registry": "0.21.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/node": "^24.0.0",
|