@guuey/config 0.1.2 → 0.2.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/agent.d.ts CHANGED
@@ -23,7 +23,7 @@
23
23
  *
24
24
  * Defaults applied by the pod runtime when fields are absent:
25
25
  * - `framework` → `'claude-agent-sdk'`
26
- * - `mcpServers` → `{ ggui: { url: 'https://mcp.ggui.ai' } }` (platform default; declaring `mcpServers` REPLACES this not merged)
26
+ * - `mcpServers` → `{ ggui: { url: 'https://mcp.ggui.ai' } }` (platform default; declaring `mcpServers` MERGES ON TOP of this (guuey#24 option A); opt out with `ggui: false`)
27
27
  * - `model` → framework-chosen default (Claude SDK → `claude-sonnet-5`)
28
28
  * - `systemPrompt`→ `GUUEY_DEFAULT_SYSTEM_PROMPT` from `./system-prompt`
29
29
  * - `auth` → `'anonymous'`
@@ -97,6 +97,40 @@ declare const McpServerSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
97
97
  "read-write": "read-write";
98
98
  }>>;
99
99
  }, z.core.$strict>], "kind">;
100
+ /**
101
+ * One declared `mcpServers` VALUE: a real server entry, or the literal `false`
102
+ * — the generative-UI opt-out, valid ONLY under the `ggui` key (enforced by
103
+ * the agent-level refine; the subtree schema stays lenient by design).
104
+ */
105
+ export declare const McpServerEntrySchema: z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
106
+ kind: z.ZodLiteral<"colocated">;
107
+ source: z.ZodString;
108
+ devPort: z.ZodOptional<z.ZodNumber>;
109
+ }, z.core.$strict>, z.ZodObject<{
110
+ kind: z.ZodLiteral<"hosted">;
111
+ server: z.ZodOptional<z.ZodString>;
112
+ source: z.ZodOptional<z.ZodString>;
113
+ devPort: z.ZodOptional<z.ZodNumber>;
114
+ }, z.core.$strict>, z.ZodObject<{
115
+ kind: z.ZodLiteral<"proxied">;
116
+ connection: z.ZodString;
117
+ }, z.core.$strict>, z.ZodObject<{
118
+ kind: z.ZodLiteral<"external">;
119
+ url: z.ZodURL;
120
+ transport: z.ZodOptional<z.ZodEnum<{
121
+ http: "http";
122
+ sse: "sse";
123
+ }>>;
124
+ federate: z.ZodOptional<z.ZodBoolean>;
125
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
126
+ devPort: z.ZodOptional<z.ZodNumber>;
127
+ mcpResourceUrl: z.ZodOptional<z.ZodURL>;
128
+ profileAccess: z.ZodOptional<z.ZodEnum<{
129
+ read: "read";
130
+ "read-write": "read-write";
131
+ }>>;
132
+ }, z.core.$strict>], "kind">, z.ZodLiteral<false>]>;
133
+ export type DeclaredMcpServers = Record<string, GuueyAgentMcpServer | false>;
100
134
  /**
101
135
  * Tool-gate block — allowlist applied first (intersect with what the MCP
102
136
  * server advertises), then denylist subtracts. Tool names are MCP-namespaced
@@ -171,7 +205,7 @@ declare const DeploySchema: z.ZodObject<{
171
205
  * resolve-mcp): whole-snapshot strictness made lowering fail open on any
172
206
  * schema field the running consumer predates.
173
207
  */
174
- export declare const McpServersSection: z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
208
+ export declare const McpServersSection: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
175
209
  kind: z.ZodLiteral<"colocated">;
176
210
  source: z.ZodString;
177
211
  devPort: z.ZodOptional<z.ZodNumber>;
@@ -198,7 +232,7 @@ export declare const McpServersSection: z.ZodRecord<z.ZodString, z.ZodDiscrimina
198
232
  read: "read";
199
233
  "read-write": "read-write";
200
234
  }>>;
201
- }, z.core.$strict>], "kind">>;
235
+ }, z.core.$strict>], "kind">, z.ZodLiteral<false>]>>;
202
236
  export declare const AgentSectionV1: z.ZodObject<{
203
237
  mode: z.ZodOptional<z.ZodEnum<{
204
238
  code: "code";
@@ -219,7 +253,7 @@ export declare const AgentSectionV1: z.ZodObject<{
219
253
  systemPrompt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
220
254
  file: z.ZodString;
221
255
  }, z.core.$strict>]>>;
222
- mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
256
+ mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
223
257
  kind: z.ZodLiteral<"colocated">;
224
258
  source: z.ZodString;
225
259
  devPort: z.ZodOptional<z.ZodNumber>;
@@ -246,7 +280,7 @@ export declare const AgentSectionV1: z.ZodObject<{
246
280
  read: "read";
247
281
  "read-write": "read-write";
248
282
  }>>;
249
- }, z.core.$strict>], "kind">>>;
283
+ }, z.core.$strict>], "kind">, z.ZodLiteral<false>]>>>;
250
284
  tools: z.ZodOptional<z.ZodObject<{
251
285
  allowlist: z.ZodOptional<z.ZodArray<z.ZodString>>;
252
286
  denylist: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -372,14 +406,25 @@ export declare const RESERVED_MCP_SERVER_NAMES: readonly string[];
372
406
  */
373
407
  export declare function validateReservedServerNames(agent: GuueyAgent | undefined): string[];
374
408
  /**
375
- * Platform default MCP server map. Applied by the pod when `agent.mcpServers`
376
- * is absent. Exposed here so non-pod consumers (CLI dry-run, lints) can show
377
- * the effective shape without duplicating the literal.
409
+ * Platform default MCP server map. Seeded under every declared map by
410
+ * {@link effectiveMcpServers} (opt out with `ggui: false`). Exposed here so
411
+ * non-pod consumers (CLI dry-run, lints) can show the effective shape without
412
+ * duplicating the literal.
378
413
  *
379
414
  * The ggui server is `kind: 'external'` — it is builder-declared when present
380
415
  * or injected by the platform at runtime. Federation still detects it by host
381
416
  * (via `isGguiUrl`) regardless of which key it's declared under.
382
417
  */
383
418
  export declare const DEFAULT_AGENT_MCP_SERVERS: Record<string, GuueyAgentMcpServer>;
419
+ /**
420
+ * The EFFECTIVE server map (guuey#24, option A): seed the platform default,
421
+ * layer the declared map on top (explicit wins), drop `ggui: false`. This is
422
+ * the ONE owner of default-application semantics — the resolution seams
423
+ * (credential broker, render-tool resolution) call this; declared-map
424
+ * ITERATION sites use {@link declaredServerEntries} instead.
425
+ */
426
+ export declare function effectiveMcpServers(declared: DeclaredMcpServers | undefined): Record<string, GuueyAgentMcpServer>;
427
+ /** The declared entries that are real servers (the `ggui: false` opt-out filtered out) — the narrowing every declared-map iteration site uses. */
428
+ export declare function declaredServerEntries(servers: DeclaredMcpServers | undefined): Array<[string, GuueyAgentMcpServer]>;
384
429
  export {};
385
430
  //# sourceMappingURL=agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,6EAKnB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAS/D;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;EAAiC,CAAC;AAClE,uEAAuE;AACvE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AA0FhE;;;;;;;;GAQG;AACH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAKnB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;mDAA+C,CAAC;AACjF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,GAAG,KAAK,CAAC,CAAC;AAE7E;;;;GAIG;AACH,QAAA,MAAM,eAAe;;;kBAGnB,CAAC;AAEH;;;;;;;;GAQG;AACH,QAAA,MAAM,mBAAmB;;;kBAGvB,CAAC;AAcH;;;;GAIG;AACH,QAAA,MAAM,kBAAkB;;oBAGtB,CAAC;AAEH;;;;;;GAMG;AACH,QAAA,MAAM,oBAAoB;;;kBAGxB,CAAC;AAEH;;;;;;;;;;GAUG;AACH,QAAA,MAAM,YAAY;;;;;;;;;kBAKhB,CAAC;AAsBH;;;;;GAKG;AACH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;oDAAoD,CAAC;AAEnF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4FzB,CAAC;AAEH,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAExD,oCAAoC;AACpC,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAElE,4BAA4B;AAC5B,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAElE,iCAAiC;AACjC,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEpE,kDAAkD;AAClD,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAExE,4BAA4B;AAC5B,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEtE,0BAA0B;AAC1B,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAuE5D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,GAAG,SAAS,GAC5B,MAAM,EAAE,CAiCV;AAeD;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,UAAU,GAAG,SAAS,GAC5B,MAAM,EAAE,CAaV;AAaD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,UAAU,GAAG,SAAS,GAC5B,MAAM,EAAE,CAaV;AAgBD;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,iBAAiB,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,kBAAkB,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,SAAS,MAAM,EAGtD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,UAAU,GAAG,SAAS,GAC5B,MAAM,EAAE,CAaV;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAEzE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,kBAAkB,GAAG,SAAS,GACvC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAOrC;AAED,kJAAkJ;AAClJ,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,kBAAkB,GAAG,SAAS,GACtC,KAAK,CAAC,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAItC"}
package/dist/agent.js CHANGED
@@ -23,7 +23,7 @@
23
23
  *
24
24
  * Defaults applied by the pod runtime when fields are absent:
25
25
  * - `framework` → `'claude-agent-sdk'`
26
- * - `mcpServers` → `{ ggui: { url: 'https://mcp.ggui.ai' } }` (platform default; declaring `mcpServers` REPLACES this not merged)
26
+ * - `mcpServers` → `{ ggui: { url: 'https://mcp.ggui.ai' } }` (platform default; declaring `mcpServers` MERGES ON TOP of this (guuey#24 option A); opt out with `ggui: false`)
27
27
  * - `model` → framework-chosen default (Claude SDK → `claude-sonnet-5`)
28
28
  * - `systemPrompt`→ `GUUEY_DEFAULT_SYSTEM_PROMPT` from `./system-prompt`
29
29
  * - `auth` → `'anonymous'`
@@ -166,6 +166,12 @@ const McpServerSchema = z.discriminatedUnion('kind', [
166
166
  ProxiedMcp,
167
167
  ExternalMcp,
168
168
  ]);
169
+ /**
170
+ * One declared `mcpServers` VALUE: a real server entry, or the literal `false`
171
+ * — the generative-UI opt-out, valid ONLY under the `ggui` key (enforced by
172
+ * the agent-level refine; the subtree schema stays lenient by design).
173
+ */
174
+ export const McpServerEntrySchema = z.union([McpServerSchema, z.literal(false)]);
169
175
  /**
170
176
  * Tool-gate block — allowlist applied first (intersect with what the MCP
171
177
  * server advertises), then denylist subtracts. Tool names are MCP-namespaced
@@ -264,7 +270,7 @@ const StorageScopeSchema = z.array(z.enum(['user', 'app']));
264
270
  * resolve-mcp): whole-snapshot strictness made lowering fail open on any
265
271
  * schema field the running consumer predates.
266
272
  */
267
- export const McpServersSection = z.record(z.string().min(1), McpServerSchema);
273
+ export const McpServersSection = z.record(z.string().min(1), McpServerEntrySchema);
268
274
  export const AgentSectionV1 = z.strictObject({
269
275
  // ── Deploy routing ──
270
276
  /**
@@ -303,18 +309,33 @@ export const AgentSectionV1 = z.strictObject({
303
309
  modelProvider: z.enum(['openai', 'openrouter']).optional(),
304
310
  systemPrompt: SystemPromptSchema.optional(),
305
311
  /**
306
- * MCP servers the agent may call. **Replaces** the platform default
307
- * (`{ ggui: { kind: 'external', url: 'https://mcp.ggui.ai', transport: 'http' } }`)
308
- * when presentnot merged. Omit the block to inherit the default; include
309
- * `ggui` explicitly to keep it alongside other servers.
312
+ * MCP servers the agent may call. **Merges on top of** the platform default
313
+ * (`{ ggui: { kind: 'external', url: 'https://mcp.ggui.ai', transport: 'http' } }`,
314
+ * guuey#24 option A) see {@link effectiveMcpServers}. Omit the block to
315
+ * inherit the default unchanged; declare `ggui` explicitly to override it;
316
+ * declare `ggui: false` to opt out of it entirely.
310
317
  *
311
- * Each entry is a discriminated union on `kind`:
318
+ * Each entry is a discriminated union on `kind`, or the literal `false`
319
+ * (valid only under the `ggui` key):
312
320
  * - `'colocated'` — guuey-managed HTTP child inside the agent pod
313
321
  * - `'hosted'` — guuey-hosted registry MCP (Starter+)
314
322
  * - `'proxied'` — 3rd-party SaaS via mcp-proxy (v2)
315
323
  * - `'external'` — builder-hosted URL (plain or federated)
316
324
  */
317
- mcpServers: z.record(z.string().min(1), McpServerSchema).optional(),
325
+ mcpServers: z
326
+ .record(z.string().min(1), McpServerEntrySchema)
327
+ .superRefine((servers, ctx) => {
328
+ for (const [name, entry] of Object.entries(servers)) {
329
+ if (entry === false && name !== 'ggui') {
330
+ ctx.addIssue({
331
+ code: z.ZodIssueCode.custom,
332
+ path: [name],
333
+ message: `mcpServers.${name}: false is only valid for the "ggui" key (it opts out of the platform-default generative-UI server) — remove the "${name}" entry instead`,
334
+ });
335
+ }
336
+ }
337
+ })
338
+ .optional(),
318
339
  tools: ToolGatesSchema.optional(),
319
340
  runtime: RuntimeConfigSchema.optional(),
320
341
  /** Claude Agent SDK-specific knobs. Only read when `framework: 'claude-agent-sdk'`. */
@@ -424,7 +445,7 @@ export function validateNoLiteralSecrets(agent) {
424
445
  const servers = agent?.mcpServers;
425
446
  if (!servers)
426
447
  return violations;
427
- for (const [serverName, server] of Object.entries(servers)) {
448
+ for (const [serverName, server] of declaredServerEntries(servers)) {
428
449
  // Only the `external` union arm carries a `headers` field.
429
450
  const headers = 'headers' in server ? server.headers : undefined;
430
451
  if (!headers)
@@ -472,7 +493,7 @@ export function validateColocatedServerNames(agent) {
472
493
  const servers = agent?.mcpServers;
473
494
  if (!servers)
474
495
  return violations;
475
- for (const [name, server] of Object.entries(servers)) {
496
+ for (const [name, server] of declaredServerEntries(servers)) {
476
497
  if (server.kind === 'colocated' && !isValidColocatedServerName(name)) {
477
498
  violations.push(`colocated MCP server name "${name}" is invalid — use only letters, digits, hyphen, underscore (it becomes part of a URL and a storage scope)`);
478
499
  }
@@ -499,7 +520,7 @@ export function validateNoProxiedServers(agent) {
499
520
  const servers = agent?.mcpServers;
500
521
  if (!servers)
501
522
  return violations;
502
- for (const [name, server] of Object.entries(servers)) {
523
+ for (const [name, server] of declaredServerEntries(servers)) {
503
524
  if (server.kind === 'proxied') {
504
525
  violations.push(`MCP server "${name}": kind 'proxied' (the mcp-proxy credential broker) is not yet supported — use 'external', 'hosted', or 'colocated'.`);
505
526
  }
@@ -563,9 +584,10 @@ export function validateReservedServerNames(agent) {
563
584
  return violations;
564
585
  }
565
586
  /**
566
- * Platform default MCP server map. Applied by the pod when `agent.mcpServers`
567
- * is absent. Exposed here so non-pod consumers (CLI dry-run, lints) can show
568
- * the effective shape without duplicating the literal.
587
+ * Platform default MCP server map. Seeded under every declared map by
588
+ * {@link effectiveMcpServers} (opt out with `ggui: false`). Exposed here so
589
+ * non-pod consumers (CLI dry-run, lints) can show the effective shape without
590
+ * duplicating the literal.
569
591
  *
570
592
  * The ggui server is `kind: 'external'` — it is builder-declared when present
571
593
  * or injected by the platform at runtime. Federation still detects it by host
@@ -574,3 +596,23 @@ export function validateReservedServerNames(agent) {
574
596
  export const DEFAULT_AGENT_MCP_SERVERS = {
575
597
  ggui: { kind: 'external', url: 'https://mcp.ggui.ai', transport: 'http' },
576
598
  };
599
+ /**
600
+ * The EFFECTIVE server map (guuey#24, option A): seed the platform default,
601
+ * layer the declared map on top (explicit wins), drop `ggui: false`. This is
602
+ * the ONE owner of default-application semantics — the resolution seams
603
+ * (credential broker, render-tool resolution) call this; declared-map
604
+ * ITERATION sites use {@link declaredServerEntries} instead.
605
+ */
606
+ export function effectiveMcpServers(declared) {
607
+ const merged = { ...DEFAULT_AGENT_MCP_SERVERS, ...declared };
608
+ const out = {};
609
+ for (const [name, entry] of Object.entries(merged)) {
610
+ if (entry !== false)
611
+ out[name] = entry;
612
+ }
613
+ return out;
614
+ }
615
+ /** The declared entries that are real servers (the `ggui: false` opt-out filtered out) — the narrowing every declared-map iteration site uses. */
616
+ export function declaredServerEntries(servers) {
617
+ return Object.entries(servers ?? {}).filter((e) => e[1] !== false);
618
+ }
package/dist/schema.d.ts CHANGED
@@ -77,7 +77,7 @@ export declare const GuueyJsonV1: z.ZodObject<{
77
77
  systemPrompt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
78
78
  file: z.ZodString;
79
79
  }, z.core.$strict>]>>;
80
- mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
80
+ mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
81
81
  kind: z.ZodLiteral<"colocated">;
82
82
  source: z.ZodString;
83
83
  devPort: z.ZodOptional<z.ZodNumber>;
@@ -104,7 +104,7 @@ export declare const GuueyJsonV1: z.ZodObject<{
104
104
  read: "read";
105
105
  "read-write": "read-write";
106
106
  }>>;
107
- }, z.core.$strict>], "kind">>>;
107
+ }, z.core.$strict>], "kind">, z.ZodLiteral<false>]>>>;
108
108
  tools: z.ZodOptional<z.ZodObject<{
109
109
  allowlist: z.ZodOptional<z.ZodArray<z.ZodString>>;
110
110
  denylist: z.ZodOptional<z.ZodArray<z.ZodString>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guuey/config",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Open-source schemas + loaders for the three guuey config files: agent.json (declarative agent definition), guuey.json (hosted-deploy overlay), and the helper types around them. Consumed by @guuey/cli, the guuey backend, and devs writing their own agent or MCP server.",
5
5
  "license": "MIT",
6
6
  "type": "module",