@guuey/config 0.1.1 → 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'`
@@ -49,20 +49,30 @@ import { z } from 'zod';
49
49
  */
50
50
  export declare const AGENT_FRAMEWORKS: readonly ["claude-agent-sdk", "openai-agents-sdk", "google-adk", "vanilla"];
51
51
  export type AgentFramework = (typeof AGENT_FRAMEWORKS)[number];
52
+ /**
53
+ * Cross-app profile access posture. `'read'` = the agent may recall the
54
+ * user's cross-app profile; `'read-write'` additionally lets it write this
55
+ * app's section. Absent = no profile access (default-closed, consent-gated).
56
+ */
57
+ export declare const ProfileAccessSchema: z.ZodEnum<{
58
+ read: "read";
59
+ "read-write": "read-write";
60
+ }>;
61
+ /** Static TypeScript type derived from {@link ProfileAccessSchema}. */
62
+ export type ProfileAccess = z.infer<typeof ProfileAccessSchema>;
52
63
  /**
53
64
  * A single MCP server entry inside `agent.mcpServers`.
54
65
  *
55
66
  * Discriminated union on `kind` — one slot per hosting mode:
56
- * - `colocated` — stdio child inside the agent pod
67
+ * - `colocated` — guuey-managed HTTP child inside the agent pod
57
68
  * - `hosted` — guuey-hosted registry MCP (Starter+)
58
69
  * - `proxied` — 3rd-party SaaS via mcp-proxy credential broker (v2)
59
70
  * - `external` — builder-hosted, reached by URL (plain or federated)
60
71
  */
61
72
  declare const McpServerSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
62
73
  kind: z.ZodLiteral<"colocated">;
63
- command: z.ZodString;
64
- args: z.ZodOptional<z.ZodArray<z.ZodString>>;
65
- headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
74
+ source: z.ZodString;
75
+ devPort: z.ZodOptional<z.ZodNumber>;
66
76
  }, z.core.$strict>, z.ZodObject<{
67
77
  kind: z.ZodLiteral<"hosted">;
68
78
  server: z.ZodOptional<z.ZodString>;
@@ -81,7 +91,46 @@ declare const McpServerSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
81
91
  federate: z.ZodOptional<z.ZodBoolean>;
82
92
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
83
93
  devPort: z.ZodOptional<z.ZodNumber>;
94
+ mcpResourceUrl: z.ZodOptional<z.ZodURL>;
95
+ profileAccess: z.ZodOptional<z.ZodEnum<{
96
+ read: "read";
97
+ "read-write": "read-write";
98
+ }>>;
84
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>;
85
134
  /**
86
135
  * Tool-gate block — allowlist applied first (intersect with what the MCP
87
136
  * server advertises), then denylist subtracts. Tool names are MCP-namespaced
@@ -150,6 +199,40 @@ declare const DeploySchema: z.ZodObject<{
150
199
  * Exported as a zod object so the top-level `GuueyJsonV1` schema (in
151
200
  * `./schema.ts`) can nest it. Static type via {@link GuueyAgent}.
152
201
  */
202
+ /**
203
+ * The `agent.mcpServers` map alone — for consumers that resolve/lower the
204
+ * servers SUBTREE without validating the whole snapshot (deploy-controller's
205
+ * resolve-mcp): whole-snapshot strictness made lowering fail open on any
206
+ * schema field the running consumer predates.
207
+ */
208
+ export declare const McpServersSection: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
209
+ kind: z.ZodLiteral<"colocated">;
210
+ source: z.ZodString;
211
+ devPort: z.ZodOptional<z.ZodNumber>;
212
+ }, z.core.$strict>, z.ZodObject<{
213
+ kind: z.ZodLiteral<"hosted">;
214
+ server: z.ZodOptional<z.ZodString>;
215
+ source: z.ZodOptional<z.ZodString>;
216
+ devPort: z.ZodOptional<z.ZodNumber>;
217
+ }, z.core.$strict>, z.ZodObject<{
218
+ kind: z.ZodLiteral<"proxied">;
219
+ connection: z.ZodString;
220
+ }, z.core.$strict>, z.ZodObject<{
221
+ kind: z.ZodLiteral<"external">;
222
+ url: z.ZodURL;
223
+ transport: z.ZodOptional<z.ZodEnum<{
224
+ http: "http";
225
+ sse: "sse";
226
+ }>>;
227
+ federate: z.ZodOptional<z.ZodBoolean>;
228
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
229
+ devPort: z.ZodOptional<z.ZodNumber>;
230
+ mcpResourceUrl: z.ZodOptional<z.ZodURL>;
231
+ profileAccess: z.ZodOptional<z.ZodEnum<{
232
+ read: "read";
233
+ "read-write": "read-write";
234
+ }>>;
235
+ }, z.core.$strict>], "kind">, z.ZodLiteral<false>]>>;
153
236
  export declare const AgentSectionV1: z.ZodObject<{
154
237
  mode: z.ZodOptional<z.ZodEnum<{
155
238
  code: "code";
@@ -161,6 +244,7 @@ export declare const AgentSectionV1: z.ZodObject<{
161
244
  "google-adk": "google-adk";
162
245
  vanilla: "vanilla";
163
246
  }>>;
247
+ entry: z.ZodOptional<z.ZodString>;
164
248
  model: z.ZodOptional<z.ZodString>;
165
249
  modelProvider: z.ZodOptional<z.ZodEnum<{
166
250
  openai: "openai";
@@ -169,11 +253,10 @@ export declare const AgentSectionV1: z.ZodObject<{
169
253
  systemPrompt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
170
254
  file: z.ZodString;
171
255
  }, z.core.$strict>]>>;
172
- 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<{
173
257
  kind: z.ZodLiteral<"colocated">;
174
- command: z.ZodString;
175
- args: z.ZodOptional<z.ZodArray<z.ZodString>>;
176
- headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
258
+ source: z.ZodString;
259
+ devPort: z.ZodOptional<z.ZodNumber>;
177
260
  }, z.core.$strict>, z.ZodObject<{
178
261
  kind: z.ZodLiteral<"hosted">;
179
262
  server: z.ZodOptional<z.ZodString>;
@@ -192,7 +275,12 @@ export declare const AgentSectionV1: z.ZodObject<{
192
275
  federate: z.ZodOptional<z.ZodBoolean>;
193
276
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
194
277
  devPort: z.ZodOptional<z.ZodNumber>;
195
- }, z.core.$strict>], "kind">>>;
278
+ mcpResourceUrl: z.ZodOptional<z.ZodURL>;
279
+ profileAccess: z.ZodOptional<z.ZodEnum<{
280
+ read: "read";
281
+ "read-write": "read-write";
282
+ }>>;
283
+ }, z.core.$strict>], "kind">, z.ZodLiteral<false>]>>>;
196
284
  tools: z.ZodOptional<z.ZodObject<{
197
285
  allowlist: z.ZodOptional<z.ZodArray<z.ZodString>>;
198
286
  denylist: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -223,6 +311,10 @@ export declare const AgentSectionV1: z.ZodObject<{
223
311
  user: "user";
224
312
  app: "app";
225
313
  }>>>;
314
+ profileAccess: z.ZodOptional<z.ZodEnum<{
315
+ read: "read";
316
+ "read-write": "read-write";
317
+ }>>;
226
318
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
227
319
  secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
228
320
  endpoint: z.ZodOptional<z.ZodObject<{
@@ -271,14 +363,68 @@ export type GuueyAgentDeploy = z.infer<typeof DeploySchema>;
271
363
  */
272
364
  export declare function validateNoLiteralSecrets(agent: GuueyAgent | undefined): string[];
273
365
  /**
274
- * Platform default MCP server map. Applied by the pod when `agent.mcpServers`
275
- * is absent. Exposed here so non-pod consumers (CLI dry-run, lints) can show
276
- * the effective shape without duplicating the literal.
366
+ * Validate that every `kind: 'colocated'` entry's NAME (the `mcpServers`
367
+ * map key) is safe to compose into `colocatedResourceUrl` i.e. passes
368
+ * {@link isValidColocatedServerName} (from `./colocated.ts`, the single
369
+ * source of truth for the rule). Returns a list of human-readable
370
+ * violation messages (empty = clean).
371
+ */
372
+ export declare function validateColocatedServerNames(agent: GuueyAgent | undefined): string[];
373
+ /**
374
+ * Validate that no `agent.mcpServers` entry uses `kind: 'proxied'`. Returns a
375
+ * list of human-readable violation messages (empty = clean), one per proxied
376
+ * entry, naming the server so the builder knows which ref to change.
377
+ */
378
+ export declare function validateNoProxiedServers(agent: GuueyAgent | undefined): string[];
379
+ /**
380
+ * The reserved colocated key the auto-injected memory MCP is booted + spliced
381
+ * under (memmcp). NEVER builder-declarable — the memory child's own server
382
+ * advertises this same name and its aud is `colocatedResourceUrl(appId, this)`.
383
+ */
384
+ export declare const RESERVED_MEMORY_SERVER_NAME = "guuey-memory";
385
+ /**
386
+ * The reserved colocated key the auto-injected cross-app profile MCP is
387
+ * booted + spliced under (profile T1+). NEVER builder-declarable — mirrors
388
+ * {@link RESERVED_MEMORY_SERVER_NAME}'s reservation for the same reason: a
389
+ * builder-declared server under this key would be silently replaced by the
390
+ * platform entry at invoke time.
391
+ */
392
+ export declare const RESERVED_PROFILE_SERVER_NAME = "guuey-profile";
393
+ /**
394
+ * Every `mcpServers` map key the platform reserves. Extensible — one entry
395
+ * today ({@link RESERVED_MEMORY_SERVER_NAME}); future platform-injected
396
+ * servers add their key here and inherit the deploy-time rejection for free.
397
+ */
398
+ export declare const RESERVED_MCP_SERVER_NAMES: readonly string[];
399
+ /**
400
+ * Validate that no `agent.mcpServers` entry uses a platform-RESERVED name
401
+ * ({@link RESERVED_MCP_SERVER_NAMES}) — regardless of `kind` (the key is
402
+ * reserved, not just one hosting mode; a builder must not shadow it as
403
+ * `colocated`, `external`, or anything else). Returns a list of human-readable
404
+ * violation messages (empty = clean), one per reserved entry. Mirrors
405
+ * {@link validateNoProxiedServers}'s shape.
406
+ */
407
+ export declare function validateReservedServerNames(agent: GuueyAgent | undefined): string[];
408
+ /**
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.
277
413
  *
278
414
  * The ggui server is `kind: 'external'` — it is builder-declared when present
279
415
  * or injected by the platform at runtime. Federation still detects it by host
280
416
  * (via `isGguiUrl`) regardless of which key it's declared under.
281
417
  */
282
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]>;
283
429
  export {};
284
430
  //# sourceMappingURL=agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,6EAKnB,CAAC;AACX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAoF/D;;;;;;;;GAQG;AACH,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;4BAKnB,CAAC;AAEH;;;;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,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAoEzB,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;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAEzE,CAAC"}
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'`
@@ -41,6 +41,7 @@
41
41
  */
42
42
  import { z } from 'zod';
43
43
  import { AGENT_SIZES } from './hosting.js';
44
+ import { isValidColocatedServerName } from './colocated.js';
44
45
  /**
45
46
  * Supported framework adapters. The pod runtime selects the matching
46
47
  * `@guuey/framework-*` adapter at boot. `vanilla` skips the framework
@@ -61,18 +62,25 @@ export const AGENT_FRAMEWORKS = [
61
62
  */
62
63
  const HeadersSchema = z.record(z.string().min(1), z.string());
63
64
  /**
64
- * `kind: 'colocated'` MCP server runs as a stdio child **inside the agent
65
- * pod** (co-locate = same gVisor sandbox). COGS: ~$0 (rides the agent pod).
66
- * Nocode runtime spawns `command [args…]` at boot.
65
+ * Cross-app profile access posture. `'read'` = the agent may recall the
66
+ * user's cross-app profile; `'read-write'` additionally lets it write this
67
+ * app's section. Absent = no profile access (default-closed, consent-gated).
68
+ */
69
+ export const ProfileAccessSchema = z.enum(['read', 'read-write']);
70
+ /**
71
+ * `kind: 'colocated'` — MCP server runs as a guuey-managed HTTP child
72
+ * **inside the agent pod** (co-locate = same gVisor sandbox). COGS: ~$0
73
+ * (rides the agent pod). `source` is a project-relative path the Router
74
+ * lowering builds/boots as a local HTTP server; `devPort` mirrors the
75
+ * `hosted`/`external` dev-loop story (name→localhost URL resolution for
76
+ * `guuey dev`).
67
77
  */
68
78
  const ColocatedMcp = z.strictObject({
69
79
  kind: z.literal('colocated'),
70
- /** Executable name or path. Required. */
71
- command: z.string().min(1),
72
- /** Argv beyond `command`. */
73
- args: z.array(z.string()).optional(),
74
- /** Static headers (less common for stdio, but supported for symmetry). */
75
- headers: HeadersSchema.optional(),
80
+ /** Source directory relative to `guuey.json`. Required. */
81
+ source: z.string().min(1),
82
+ /** Local dev-loop port (`guuey dev`) this MCP is served on for name→localhost URL resolution. */
83
+ devPort: z.number().int().min(1).max(65535).optional(),
76
84
  });
77
85
  /**
78
86
  * `kind: 'hosted'` — a workspace-owned registry MCP running on guuey's
@@ -104,7 +112,7 @@ const HostedMcp = z
104
112
  */
105
113
  const ProxiedMcp = z.strictObject({
106
114
  kind: z.literal('proxied'),
107
- /** mcp-proxy connection id (from `guuey connections add`). */
115
+ /** mcp-proxy connection id (not yet available — rides with the mcp-proxy credential broker). */
108
116
  connection: z.string().min(1),
109
117
  });
110
118
  /**
@@ -130,12 +138,24 @@ const ExternalMcp = z.strictObject({
130
138
  headers: HeadersSchema.optional(),
131
139
  /** Local dev-loop port (`guuey dev`) this MCP is served on for name→localhost URL resolution. */
132
140
  devPort: z.number().int().min(1).max(65535).optional(),
141
+ /**
142
+ * INTERNAL — set only by Router lowering; when present the federation mint
143
+ * uses this as the RFC 8707 resource instead of `url`.
144
+ */
145
+ mcpResourceUrl: z.url().optional(),
146
+ /**
147
+ * INTERNAL — set only by Router lowering when this entry is the spliced
148
+ * profile MCP; carries the agent's `profileAccess` posture onto the entry
149
+ * itself so the profile child's tool gate (read vs read-write) survives
150
+ * independent of the top-level `agent.profileAccess` field.
151
+ */
152
+ profileAccess: ProfileAccessSchema.optional(),
133
153
  });
134
154
  /**
135
155
  * A single MCP server entry inside `agent.mcpServers`.
136
156
  *
137
157
  * Discriminated union on `kind` — one slot per hosting mode:
138
- * - `colocated` — stdio child inside the agent pod
158
+ * - `colocated` — guuey-managed HTTP child inside the agent pod
139
159
  * - `hosted` — guuey-hosted registry MCP (Starter+)
140
160
  * - `proxied` — 3rd-party SaaS via mcp-proxy credential broker (v2)
141
161
  * - `external` — builder-hosted, reached by URL (plain or federated)
@@ -146,6 +166,12 @@ const McpServerSchema = z.discriminatedUnion('kind', [
146
166
  ProxiedMcp,
147
167
  ExternalMcp,
148
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)]);
149
175
  /**
150
176
  * Tool-gate block — allowlist applied first (intersect with what the MCP
151
177
  * server advertises), then denylist subtracts. Tool names are MCP-namespaced
@@ -238,6 +264,13 @@ const StorageScopeSchema = z.array(z.enum(['user', 'app']));
238
264
  * Exported as a zod object so the top-level `GuueyJsonV1` schema (in
239
265
  * `./schema.ts`) can nest it. Static type via {@link GuueyAgent}.
240
266
  */
267
+ /**
268
+ * The `agent.mcpServers` map alone — for consumers that resolve/lower the
269
+ * servers SUBTREE without validating the whole snapshot (deploy-controller's
270
+ * resolve-mcp): whole-snapshot strictness made lowering fail open on any
271
+ * schema field the running consumer predates.
272
+ */
273
+ export const McpServersSection = z.record(z.string().min(1), McpServerEntrySchema);
241
274
  export const AgentSectionV1 = z.strictObject({
242
275
  // ── Deploy routing ──
243
276
  /**
@@ -256,6 +289,14 @@ export const AgentSectionV1 = z.strictObject({
256
289
  mode: z.enum(['code', 'declarative']).optional(),
257
290
  // ── Framework + runtime ──
258
291
  framework: z.enum(AGENT_FRAMEWORKS).optional(),
292
+ /**
293
+ * Graceful code-mode: a module (path relative to the project root, built
294
+ * output) whose default export is the framework-native agent object or a
295
+ * factory `(guuey: GuueyContext) => agent`. The platform host imports and
296
+ * runs it — the dev writes zero harness code. Mutually exclusive with the
297
+ * full-worker `worker` field (which wins when both are present).
298
+ */
299
+ entry: z.string().min(1).optional(),
259
300
  model: z.string().min(1).optional(),
260
301
  /**
261
302
  * Managed-LLM provider selector — only meaningful for
@@ -268,18 +309,33 @@ export const AgentSectionV1 = z.strictObject({
268
309
  modelProvider: z.enum(['openai', 'openrouter']).optional(),
269
310
  systemPrompt: SystemPromptSchema.optional(),
270
311
  /**
271
- * MCP servers the agent may call. **Replaces** the platform default
272
- * (`{ ggui: { kind: 'external', url: 'https://mcp.ggui.ai', transport: 'http' } }`)
273
- * when presentnot merged. Omit the block to inherit the default; include
274
- * `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.
275
317
  *
276
- * Each entry is a discriminated union on `kind`:
277
- * - `'colocated'` stdio child inside the agent pod
318
+ * Each entry is a discriminated union on `kind`, or the literal `false`
319
+ * (valid only under the `ggui` key):
320
+ * - `'colocated'` — guuey-managed HTTP child inside the agent pod
278
321
  * - `'hosted'` — guuey-hosted registry MCP (Starter+)
279
322
  * - `'proxied'` — 3rd-party SaaS via mcp-proxy (v2)
280
323
  * - `'external'` — builder-hosted URL (plain or federated)
281
324
  */
282
- 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(),
283
339
  tools: ToolGatesSchema.optional(),
284
340
  runtime: RuntimeConfigSchema.optional(),
285
341
  /** Claude Agent SDK-specific knobs. Only read when `framework: 'claude-agent-sdk'`. */
@@ -288,6 +344,7 @@ export const AgentSectionV1 = z.strictObject({
288
344
  auth: AuthSchema.optional(),
289
345
  memory: MemorySchema.optional(),
290
346
  storage: StorageScopeSchema.optional(),
347
+ profileAccess: ProfileAccessSchema.optional(),
291
348
  // ── Env + secrets ──
292
349
  /** Literal non-sensitive env vars baked into the pod at boot. */
293
350
  env: z.record(z.string().min(1), z.string()).optional(),
@@ -388,8 +445,8 @@ export function validateNoLiteralSecrets(agent) {
388
445
  const servers = agent?.mcpServers;
389
446
  if (!servers)
390
447
  return violations;
391
- for (const [serverName, server] of Object.entries(servers)) {
392
- // Only `colocated` and `external` union arms carry a `headers` field.
448
+ for (const [serverName, server] of declaredServerEntries(servers)) {
449
+ // Only the `external` union arm carries a `headers` field.
393
450
  const headers = 'headers' in server ? server.headers : undefined;
394
451
  if (!headers)
395
452
  continue;
@@ -412,10 +469,125 @@ export function validateNoLiteralSecrets(agent) {
412
469
  }
413
470
  return violations;
414
471
  }
472
+ // ── No-invalid-colocated-names validation (deploy-time contract enforcement) ──
473
+ //
474
+ // `agent.mcpServers`' key is schema-typed only `z.string().min(1)` — any
475
+ // non-empty string parses. But at pod boot, `lowerColocated` composes the
476
+ // KEY (not just `source`) into `colocatedResourceUrl(appId, name)`, which
477
+ // THROWS for anything outside `/^[A-Za-z0-9_-]+$/` (see `./colocated.ts`).
478
+ // An invalid colocated name therefore parses fine client-side and only
479
+ // fails once the pod is already booting, as an unactionable
480
+ // `POD_FATAL_BOOT_ERROR` crash-loop. `validateColocatedServerNames` is the
481
+ // deploy-time pre-flight that catches it first — mirrors
482
+ // `validateNoLiteralSecrets`'s shape (explicit lint, called by
483
+ // `@guuey/cli`'s `commands/deploy.ts` right before upload).
484
+ /**
485
+ * Validate that every `kind: 'colocated'` entry's NAME (the `mcpServers`
486
+ * map key) is safe to compose into `colocatedResourceUrl` — i.e. passes
487
+ * {@link isValidColocatedServerName} (from `./colocated.ts`, the single
488
+ * source of truth for the rule). Returns a list of human-readable
489
+ * violation messages (empty = clean).
490
+ */
491
+ export function validateColocatedServerNames(agent) {
492
+ const violations = [];
493
+ const servers = agent?.mcpServers;
494
+ if (!servers)
495
+ return violations;
496
+ for (const [name, server] of declaredServerEntries(servers)) {
497
+ if (server.kind === 'colocated' && !isValidColocatedServerName(name)) {
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)`);
499
+ }
500
+ }
501
+ return violations;
502
+ }
503
+ // ── No-proxied-servers validation (deploy-time contract enforcement) ────────
504
+ //
505
+ // `kind: 'proxied'` keeps its schema arm (the documented mcp-proxy
506
+ // credential-broker deferral — wires when the 2nd stored-creds customer signs
507
+ // up) but has NO runtime support today: a pod that booted one would silently
508
+ // miss those tools. `validateNoProxiedServers` is the synchronous deploy-time
509
+ // pre-flight (mirrors `validateColocatedServerNames`'s shape) that rejects it
510
+ // with a fast, actionable error. The deploy-controller's
511
+ // `resolveMcpServersInSnapshot` carries the authoritative backstop throw for
512
+ // code deploys, which never pass through this validator.
513
+ /**
514
+ * Validate that no `agent.mcpServers` entry uses `kind: 'proxied'`. Returns a
515
+ * list of human-readable violation messages (empty = clean), one per proxied
516
+ * entry, naming the server so the builder knows which ref to change.
517
+ */
518
+ export function validateNoProxiedServers(agent) {
519
+ const violations = [];
520
+ const servers = agent?.mcpServers;
521
+ if (!servers)
522
+ return violations;
523
+ for (const [name, server] of declaredServerEntries(servers)) {
524
+ if (server.kind === 'proxied') {
525
+ violations.push(`MCP server "${name}": kind 'proxied' (the mcp-proxy credential broker) is not yet supported — use 'external', 'hosted', or 'colocated'.`);
526
+ }
527
+ }
528
+ return violations;
529
+ }
530
+ // ── Reserved platform MCP server names (deploy-time reservation) ────────────
531
+ //
532
+ // Some `mcpServers` map keys are OWNED by the platform: the runtime splices a
533
+ // platform-managed entry under them (memmcp — the auto-injected memory MCP is
534
+ // spliced under `guuey-memory` for authenticated invokes; see
535
+ // `nocode-runtime/src/run-seam.ts` + `boot-colocated.ts`). A builder that
536
+ // declares a server under a reserved key would (a) boot as builder code under
537
+ // the same key the platform child owns, and (b) be silently REPLACED by the
538
+ // platform entry at invoke time. `validateReservedServerNames` is the
539
+ // synchronous deploy-time pre-flight that rejects it with a fast, actionable
540
+ // 400 — the primary guard; the run-seam collision guard is defense-in-depth for
541
+ // stale pre-validator snapshots. Single source of the reserved literal: this
542
+ // module. The boot/splice layer (`boot-colocated.ts`) imports it from here.
543
+ /**
544
+ * The reserved colocated key the auto-injected memory MCP is booted + spliced
545
+ * under (memmcp). NEVER builder-declarable — the memory child's own server
546
+ * advertises this same name and its aud is `colocatedResourceUrl(appId, this)`.
547
+ */
548
+ export const RESERVED_MEMORY_SERVER_NAME = 'guuey-memory';
549
+ /**
550
+ * The reserved colocated key the auto-injected cross-app profile MCP is
551
+ * booted + spliced under (profile T1+). NEVER builder-declarable — mirrors
552
+ * {@link RESERVED_MEMORY_SERVER_NAME}'s reservation for the same reason: a
553
+ * builder-declared server under this key would be silently replaced by the
554
+ * platform entry at invoke time.
555
+ */
556
+ export const RESERVED_PROFILE_SERVER_NAME = 'guuey-profile';
557
+ /**
558
+ * Every `mcpServers` map key the platform reserves. Extensible — one entry
559
+ * today ({@link RESERVED_MEMORY_SERVER_NAME}); future platform-injected
560
+ * servers add their key here and inherit the deploy-time rejection for free.
561
+ */
562
+ export const RESERVED_MCP_SERVER_NAMES = [
563
+ RESERVED_MEMORY_SERVER_NAME,
564
+ RESERVED_PROFILE_SERVER_NAME,
565
+ ];
415
566
  /**
416
- * Platform default MCP server map. Applied by the pod when `agent.mcpServers`
417
- * is absent. Exposed here so non-pod consumers (CLI dry-run, lints) can show
418
- * the effective shape without duplicating the literal.
567
+ * Validate that no `agent.mcpServers` entry uses a platform-RESERVED name
568
+ * ({@link RESERVED_MCP_SERVER_NAMES}) regardless of `kind` (the key is
569
+ * reserved, not just one hosting mode; a builder must not shadow it as
570
+ * `colocated`, `external`, or anything else). Returns a list of human-readable
571
+ * violation messages (empty = clean), one per reserved entry. Mirrors
572
+ * {@link validateNoProxiedServers}'s shape.
573
+ */
574
+ export function validateReservedServerNames(agent) {
575
+ const violations = [];
576
+ const servers = agent?.mcpServers;
577
+ if (!servers)
578
+ return violations;
579
+ for (const name of Object.keys(servers)) {
580
+ if (RESERVED_MCP_SERVER_NAMES.includes(name)) {
581
+ violations.push(`MCP server "${name}": that name is reserved by the platform (an auto-injected server uses it) — rename this server.`);
582
+ }
583
+ }
584
+ return violations;
585
+ }
586
+ /**
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.
419
591
  *
420
592
  * The ggui server is `kind: 'external'` — it is builder-declared when present
421
593
  * or injected by the platform at runtime. Federation still detects it by host
@@ -424,3 +596,23 @@ export function validateNoLiteralSecrets(agent) {
424
596
  export const DEFAULT_AGENT_MCP_SERVERS = {
425
597
  ggui: { kind: 'external', url: 'https://mcp.ggui.ai', transport: 'http' },
426
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
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `@guuey/config/browser` — the package minus `loader.js`.
3
+ *
4
+ * `loader.js` imports `node:fs` (guuey.json file resolution), which a
5
+ * browser bundler cannot chunk — importing the root barrel from client
6
+ * code fails `next build` outright (Turbopack: "does not support
7
+ * external modules (request: node:fs)"). Browser consumers (Guuey
8
+ * Studio's agent-config) import this entry instead; Node consumers
9
+ * (CLI, backend, pods) keep the root barrel.
10
+ *
11
+ * Every module re-exported here must stay free of Node builtins.
12
+ */
13
+ export * from './schema.js';
14
+ export * from './agent.js';
15
+ export * from './app.js';
16
+ export * from './ggui.js';
17
+ export * from './hosting.js';
18
+ export * from './system-prompt.js';
19
+ export * from './registry.js';
20
+ export * from './guuey-context.js';
21
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `@guuey/config/browser` — the package minus `loader.js`.
3
+ *
4
+ * `loader.js` imports `node:fs` (guuey.json file resolution), which a
5
+ * browser bundler cannot chunk — importing the root barrel from client
6
+ * code fails `next build` outright (Turbopack: "does not support
7
+ * external modules (request: node:fs)"). Browser consumers (Guuey
8
+ * Studio's agent-config) import this entry instead; Node consumers
9
+ * (CLI, backend, pods) keep the root barrel.
10
+ *
11
+ * Every module re-exported here must stay free of Node builtins.
12
+ */
13
+ export * from './schema.js';
14
+ export * from './agent.js';
15
+ export * from './app.js';
16
+ export * from './ggui.js';
17
+ export * from './hosting.js';
18
+ export * from './system-prompt.js';
19
+ export * from './registry.js';
20
+ export * from './guuey-context.js';
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Synthetic resource-URL helper for `kind: 'colocated'` MCP servers.
3
+ *
4
+ * A colocated MCP has no real network URL (it's a guuey-managed HTTP child
5
+ * inside the agent pod, reached over a loopback/localhost hop the Router
6
+ * wires up) — but RFC 8707 federation still needs a stable `aud`/resource
7
+ * value to mint against, and `@guuey/state`'s KV needs a stable scope key.
8
+ * `colocatedResourceUrl` composes both from `(appId, serverName)`.
9
+ *
10
+ * The returned URL is consumed by `backend/amplify/functions/oidcMint/
11
+ * handler.ts`'s `parseMcpResourceUrl`, which requires: `https://` prefix,
12
+ * a trailing `/`, and a total length ≤ 512 chars. Both segments are
13
+ * validated against `/^[A-Za-z0-9_-]+$/` BEFORE composing the URL — they
14
+ * are used verbatim as URL path segments AND as a KV scope key, so an
15
+ * unvalidated segment (e.g. containing `/` or whitespace) could smuggle an
16
+ * extra path segment or break the scope contract.
17
+ */
18
+ /**
19
+ * The synthetic origin every colocated resource URL lives on. Guuey-owned
20
+ * and compile-time-fixed (NOT env-varying — the host never resolves; it
21
+ * exists only as a stable RFC 8707 `aud` / KV-scope namespace), so
22
+ * consumers that must recognize "is this URL guuey-controlled?" (e.g. the
23
+ * stateApi admin-ownership walk's origin filter) import THIS constant
24
+ * instead of re-declaring the string or threading a new env var.
25
+ */
26
+ export declare const COLOCATED_ORIGIN = "https://colocated.guuey.com";
27
+ /**
28
+ * Whether `value` is safe to use as a `colocatedResourceUrl` path segment /
29
+ * KV scope key (letters, digits, hyphen, underscore only). Single source of
30
+ * truth for that rule — reused by {@link assertSafeSegment} here AND by
31
+ * `./agent.ts#validateColocatedServerNames` (the CLI deploy-time check
32
+ * `@guuey/cli`'s `commands/deploy.ts` runs before upload), so a bad
33
+ * colocated server name is rejected before deploy instead of surfacing only
34
+ * as a `POD_FATAL_BOOT_ERROR` crash-loop when the pod's `lowerColocated`
35
+ * calls `colocatedResourceUrl` at boot.
36
+ */
37
+ export declare function isValidColocatedServerName(value: string): boolean;
38
+ /**
39
+ * Build the synthetic `https://colocated.guuey.com/<appId>/<serverName>/`
40
+ * resource URL for a colocated MCP server. Throws if either segment fails
41
+ * the safe-segment check.
42
+ */
43
+ export declare function colocatedResourceUrl(appId: string, serverName: string): string;
44
+ //# sourceMappingURL=colocated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colocated.d.ts","sourceRoot":"","sources":["../src/colocated.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,gCAAgC,CAAC;AAE9D;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjE;AAUD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAI9E"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Synthetic resource-URL helper for `kind: 'colocated'` MCP servers.
3
+ *
4
+ * A colocated MCP has no real network URL (it's a guuey-managed HTTP child
5
+ * inside the agent pod, reached over a loopback/localhost hop the Router
6
+ * wires up) — but RFC 8707 federation still needs a stable `aud`/resource
7
+ * value to mint against, and `@guuey/state`'s KV needs a stable scope key.
8
+ * `colocatedResourceUrl` composes both from `(appId, serverName)`.
9
+ *
10
+ * The returned URL is consumed by `backend/amplify/functions/oidcMint/
11
+ * handler.ts`'s `parseMcpResourceUrl`, which requires: `https://` prefix,
12
+ * a trailing `/`, and a total length ≤ 512 chars. Both segments are
13
+ * validated against `/^[A-Za-z0-9_-]+$/` BEFORE composing the URL — they
14
+ * are used verbatim as URL path segments AND as a KV scope key, so an
15
+ * unvalidated segment (e.g. containing `/` or whitespace) could smuggle an
16
+ * extra path segment or break the scope contract.
17
+ */
18
+ const SAFE_SEGMENT_RE = /^[A-Za-z0-9_-]+$/;
19
+ /**
20
+ * The synthetic origin every colocated resource URL lives on. Guuey-owned
21
+ * and compile-time-fixed (NOT env-varying — the host never resolves; it
22
+ * exists only as a stable RFC 8707 `aud` / KV-scope namespace), so
23
+ * consumers that must recognize "is this URL guuey-controlled?" (e.g. the
24
+ * stateApi admin-ownership walk's origin filter) import THIS constant
25
+ * instead of re-declaring the string or threading a new env var.
26
+ */
27
+ export const COLOCATED_ORIGIN = 'https://colocated.guuey.com';
28
+ /**
29
+ * Whether `value` is safe to use as a `colocatedResourceUrl` path segment /
30
+ * KV scope key (letters, digits, hyphen, underscore only). Single source of
31
+ * truth for that rule — reused by {@link assertSafeSegment} here AND by
32
+ * `./agent.ts#validateColocatedServerNames` (the CLI deploy-time check
33
+ * `@guuey/cli`'s `commands/deploy.ts` runs before upload), so a bad
34
+ * colocated server name is rejected before deploy instead of surfacing only
35
+ * as a `POD_FATAL_BOOT_ERROR` crash-loop when the pod's `lowerColocated`
36
+ * calls `colocatedResourceUrl` at boot.
37
+ */
38
+ export function isValidColocatedServerName(value) {
39
+ return SAFE_SEGMENT_RE.test(value);
40
+ }
41
+ function assertSafeSegment(value, label) {
42
+ if (!isValidColocatedServerName(value)) {
43
+ throw new Error(`colocatedResourceUrl: ${label} "${value}" must match ${SAFE_SEGMENT_RE.source} (it composes a URL path segment and a KV scope key)`);
44
+ }
45
+ }
46
+ /**
47
+ * Build the synthetic `https://colocated.guuey.com/<appId>/<serverName>/`
48
+ * resource URL for a colocated MCP server. Throws if either segment fails
49
+ * the safe-segment check.
50
+ */
51
+ export function colocatedResourceUrl(appId, serverName) {
52
+ assertSafeSegment(appId, 'appId');
53
+ assertSafeSegment(serverName, 'serverName');
54
+ return `${COLOCATED_ORIGIN}/${appId}/${serverName}/`;
55
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * `GuueyContext` — everything the platform resolved for one turn, handed to a
3
+ * graceful-mode agent factory. THE import channel for graceful devs:
4
+ *
5
+ * ```ts
6
+ * import type { GuueyContext } from "@guuey/config";
7
+ * export default (guuey: GuueyContext) => new LlmAgent({
8
+ * model: guuey.model,
9
+ * // Function form — safe for every framework; required for ADK, which
10
+ * // applies `{var}` substitution to a plain-string instruction.
11
+ * instruction: () => guuey.instruction,
12
+ * tools: [myTool, ...guuey.mcpToolsets],
13
+ * });
14
+ * ```
15
+ *
16
+ * Types-only and dependency-free by design (`@guuey/config` is already a
17
+ * template dependency; the host — which ASSEMBLES the context — is not). The
18
+ * tiny shapes below are structurally identical to `@guuey/worker`'s protocol
19
+ * types; duplicating them here keeps config free of a runtime package
20
+ * dependency for what is purely a type channel.
21
+ *
22
+ * The factory runs PER INVOKE (matching the per-invoke agent construction the
23
+ * platform host has always done), so per-turn surfaces — the user, this
24
+ * turn's state — are first-class, not bolted on.
25
+ */
26
+ /** Router-vouched end-user identity for this turn (multi-tenant). */
27
+ export interface GuueyContextUser {
28
+ id: string;
29
+ authMode: "anonymous" | "authenticated";
30
+ }
31
+ /**
32
+ * The three GuueyFS layer mounts (absolute paths):
33
+ * - `app` — read-only app assets,
34
+ * - `home` — per-USER durable storage,
35
+ * - `session` — per-session scratch.
36
+ */
37
+ export interface GuueyContextFiles {
38
+ app: string;
39
+ home: string;
40
+ session: string;
41
+ }
42
+ /** One prior message from the recent history window. */
43
+ export interface GuueyContextMessage {
44
+ role: "user" | "agent";
45
+ text: string;
46
+ }
47
+ /** One thread-memory record folded from prior turns. */
48
+ export interface GuueyContextMemoryRecord {
49
+ key?: string;
50
+ value: unknown;
51
+ }
52
+ /**
53
+ * The full per-turn platform context. `TToolset` is the framework's MCP
54
+ * toolset type (e.g. `MCPToolset` from `@google/adk`) — defaults to `unknown`
55
+ * so the type stays framework-neutral.
56
+ *
57
+ * History, memory, and working state are ALSO auto-injected into
58
+ * `instruction` as the standard context preamble — a factory that ignores
59
+ * them still yields a conversational agent. They appear here read-only so an
60
+ * advanced factory can do better than the default preamble.
61
+ */
62
+ export interface GuueyContext<TToolset = unknown> {
63
+ /** Resolved model id (from guuey.json / registry default). */
64
+ model: string;
65
+ /**
66
+ * The system prompt WITH the standard context preamble (history, thread
67
+ * memory, working state) already prepended. Feed this to the agent unless
68
+ * you are rendering context yourself from the raw fields below.
69
+ */
70
+ instruction: string;
71
+ /** Ready-to-use MCP toolsets for every server declared in guuey.json. */
72
+ mcpToolsets: TToolset[];
73
+ /** The end user this turn serves. */
74
+ user: GuueyContextUser;
75
+ /** The three-tier file storage paths. */
76
+ files: GuueyContextFiles;
77
+ /** Recent conversation window (read side; auto-preambled). */
78
+ history: GuueyContextMessage[];
79
+ /** Thread memory records (read side; auto-preambled). */
80
+ memory: GuueyContextMemoryRecord[];
81
+ /** Prior working state carried from the previous turn (read side). */
82
+ workingState: unknown | undefined;
83
+ }
84
+ /**
85
+ * What a graceful agent module's default export may be: the framework-native
86
+ * agent object itself, or a factory receiving the {@link GuueyContext}.
87
+ * Factories may be async.
88
+ */
89
+ export type GuueyAgentExport<TAgent = object, TToolset = unknown> = TAgent | ((guuey: GuueyContext<TToolset>) => TAgent | Promise<TAgent>);
90
+ //# sourceMappingURL=guuey-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guuey-context.d.ts","sourceRoot":"","sources":["../src/guuey-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,qEAAqE;AACrE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,WAAW,GAAG,eAAe,CAAC;CACzC;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wDAAwD;AACxD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wDAAwD;AACxD,MAAM,WAAW,wBAAwB;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY,CAAC,QAAQ,GAAG,OAAO;IAC9C,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACxB,qCAAqC;IACrC,IAAI,EAAE,gBAAgB,CAAC;IACvB,yCAAyC;IACzC,KAAK,EAAE,iBAAiB,CAAC;IACzB,8DAA8D;IAC9D,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,yDAAyD;IACzD,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACnC,sEAAsE;IACtE,YAAY,EAAE,OAAO,GAAG,SAAS,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,CAAC,MAAM,GAAG,MAAM,EAAE,QAAQ,GAAG,OAAO,IAC5D,MAAM,GACN,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,QAAQ,CAAC,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * `GuueyContext` — everything the platform resolved for one turn, handed to a
3
+ * graceful-mode agent factory. THE import channel for graceful devs:
4
+ *
5
+ * ```ts
6
+ * import type { GuueyContext } from "@guuey/config";
7
+ * export default (guuey: GuueyContext) => new LlmAgent({
8
+ * model: guuey.model,
9
+ * // Function form — safe for every framework; required for ADK, which
10
+ * // applies `{var}` substitution to a plain-string instruction.
11
+ * instruction: () => guuey.instruction,
12
+ * tools: [myTool, ...guuey.mcpToolsets],
13
+ * });
14
+ * ```
15
+ *
16
+ * Types-only and dependency-free by design (`@guuey/config` is already a
17
+ * template dependency; the host — which ASSEMBLES the context — is not). The
18
+ * tiny shapes below are structurally identical to `@guuey/worker`'s protocol
19
+ * types; duplicating them here keeps config free of a runtime package
20
+ * dependency for what is purely a type channel.
21
+ *
22
+ * The factory runs PER INVOKE (matching the per-invoke agent construction the
23
+ * platform host has always done), so per-turn surfaces — the user, this
24
+ * turn's state — are first-class, not bolted on.
25
+ */
26
+ export {};
package/dist/index.d.ts CHANGED
@@ -12,10 +12,12 @@
12
12
  */
13
13
  export * from './schema.js';
14
14
  export * from './agent.js';
15
+ export * from './colocated.js';
15
16
  export * from './app.js';
16
17
  export * from './ggui.js';
17
18
  export * from './loader.js';
18
19
  export * from './hosting.js';
19
20
  export * from './system-prompt.js';
20
21
  export * from './registry.js';
22
+ export * from './guuey-context.js';
21
23
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -12,9 +12,11 @@
12
12
  */
13
13
  export * from './schema.js';
14
14
  export * from './agent.js';
15
+ export * from './colocated.js';
15
16
  export * from './app.js';
16
17
  export * from './ggui.js';
17
18
  export * from './loader.js';
18
19
  export * from './hosting.js';
19
20
  export * from './system-prompt.js';
20
21
  export * from './registry.js';
22
+ export * from './guuey-context.js';
@@ -18,6 +18,13 @@ export interface FrameworkEntry {
18
18
  readonly facetSupportedRange: string | null;
19
19
  readonly defaultProvider: "anthropic" | "openai" | "google";
20
20
  }
21
+ /**
22
+ * Array order is picker order AFTER `modelsForProvider` floats the default to
23
+ * the front — the platform's app-behavior picker shows only `.slice(0, 2)` for
24
+ * google + openai, so the second array entry per provider is a product-visible
25
+ * choice, not incidental. Pinned by
26
+ * `apps/platform/.../ModelSection/ModelSection.test.ts`.
27
+ */
21
28
  export declare const MODEL_REGISTRY: readonly ModelEntry[];
22
29
  export declare const FRAMEWORK_REGISTRY: readonly FrameworkEntry[];
23
30
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,WAAW,GAAG,YAAY,CAAC;AAExE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,kBAAkB,GAAG,mBAAmB,GAAG,YAAY,GAAG,SAAS,CAAC;IACxF,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,eAAe,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAC7D;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,UAAU,EAe/C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,SAAS,cAAc,EA6BvD,CAAC;AAEF;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,SAAS,UAAU,EAAE,CAQlF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG,MAAM,CAM9E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE7D"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,WAAW,GAAG,YAAY,CAAC;AAExE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,CAAC;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,kBAAkB,GAAG,mBAAmB,GAAG,YAAY,GAAG,SAAS,CAAC;IACxF,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,eAAe,EAAE,WAAW,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAC7D;AAED;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,UAAU,EA0B/C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,SAAS,cAAc,EA6BvD,CAAC;AAEF;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,SAAS,UAAU,EAAE,CAQlF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,cAAc,CAAC,WAAW,CAAC,GAAG,MAAM,CAM9E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE7D"}
package/dist/registry.js CHANGED
@@ -2,18 +2,36 @@
2
2
  * Model + framework registry — single source of truth per the model-release
3
3
  * playbook §8 item A; a release = one entry change here + rate-card row.
4
4
  */
5
+ /**
6
+ * Array order is picker order AFTER `modelsForProvider` floats the default to
7
+ * the front — the platform's app-behavior picker shows only `.slice(0, 2)` for
8
+ * google + openai, so the second array entry per provider is a product-visible
9
+ * choice, not incidental. Pinned by
10
+ * `apps/platform/.../ModelSection/ModelSection.test.ts`.
11
+ */
5
12
  export const MODEL_REGISTRY = [
6
13
  { id: "claude-sonnet-5", provider: "anthropic", label: "Claude Sonnet 5", status: "ga", isDefault: true },
7
14
  { id: "claude-fable-5", provider: "anthropic", label: "Claude Fable 5", status: "ga" },
15
+ { id: "claude-opus-5", provider: "anthropic", label: "Claude Opus 5", status: "ga" },
8
16
  { id: "claude-sonnet-4-6", provider: "anthropic", label: "Claude Sonnet 4.6", status: "ga" },
9
17
  { id: "claude-haiku-4-5", provider: "anthropic", label: "Claude Haiku 4.5", status: "ga" },
10
18
  { id: "claude-opus-4-8", provider: "anthropic", label: "Claude Opus 4.8", status: "ga" },
11
- { id: "gpt-5.5", provider: "openai", label: "GPT-5.5", status: "ga", isDefault: true },
19
+ // Terra guuey's OpenAI default (founder call 2026-07-25). This DELIBERATELY
20
+ // diverges from OpenAI's own `gpt-5.6` alias, which routes to Sol: Terra is
21
+ // half Sol's price and the better cost/balance pick for hosted agent
22
+ // workloads. The bare `gpt-5.6` alias is intentionally NOT a registry id
23
+ // (never offered in a picker) — the rate card still rows it at Sol's price so
24
+ // an alias call from BYO config can't under-meter.
25
+ { id: "gpt-5.6-terra", provider: "openai", label: "GPT-5.6 Terra", status: "ga", isDefault: true },
26
+ { id: "gpt-5.6-sol", provider: "openai", label: "GPT-5.6 Sol", status: "ga" },
27
+ { id: "gpt-5.6-luna", provider: "openai", label: "GPT-5.6 Luna", status: "ga" },
28
+ { id: "gpt-5.5", provider: "openai", label: "GPT-5.5", status: "ga" },
12
29
  { id: "gpt-5.4", provider: "openai", label: "GPT-5.4", status: "ga" },
13
30
  { id: "gpt-4o", provider: "openai", label: "GPT-4o", status: "ga" },
14
31
  { id: "gpt-4o-mini", provider: "openai", label: "GPT-4o Mini", status: "ga" },
15
- { id: "gpt-5.6", provider: "openai", label: "GPT-5.6", status: "announced" },
16
- { id: "gemini-3.5-flash", provider: "google", label: "Gemini 3.5 Flash", status: "ga", isDefault: true },
32
+ { id: "gemini-3.6-flash", provider: "google", label: "Gemini 3.6 Flash", status: "ga", isDefault: true },
33
+ { id: "gemini-3.5-flash-lite", provider: "google", label: "Gemini 3.5 Flash Lite", status: "ga" },
34
+ { id: "gemini-3.5-flash", provider: "google", label: "Gemini 3.5 Flash", status: "ga" },
17
35
  { id: "gemini-3.1-pro", provider: "google", label: "Gemini 3.1 Pro", status: "ga" },
18
36
  { id: "gemini-2.5-flash", provider: "google", label: "Gemini 2.5 Flash", status: "ga" },
19
37
  { id: "gemini-2.5-pro", provider: "google", label: "Gemini 2.5 Pro", status: "ga" },
@@ -35,9 +53,9 @@ export const FRAMEWORK_REGISTRY = [
35
53
  },
36
54
  {
37
55
  framework: "google-adk",
38
- sdkPackage: "google-adk",
39
- platformPinnedVersion: "2.3.0",
40
- facetSupportedRange: null,
56
+ sdkPackage: "@google/adk", // the OFFICIAL JS ADK (the Python lane retired with guuey_adk_host)
57
+ platformPinnedVersion: "1.3.0", // pinned in @guuey-private/host-shared
58
+ facetSupportedRange: ">=1.0.0 <2", // @silverprotocol/google-adk peer range
41
59
  defaultProvider: "google",
42
60
  },
43
61
  {
package/dist/schema.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  * - `ggui` (optional) — cross-protocol integration if the agent uses ggui rendering
9
9
  *
10
10
  * Plus top-level platform identity (`appId`, `workspaceId`) populated by
11
- * the CLI after `guuey create` / `guuey link`.
11
+ * the CLI after `guuey create` / `guuey pull --app-id`.
12
12
  *
13
13
  * **Filename convention** (filename = artifact kind, see design doc §3):
14
14
  * ```
@@ -48,8 +48,8 @@ import { type GuueyGguiSection } from './ggui.js';
48
48
  * only an MCP server uses `guuey.mcp.json` instead (separate schema).
49
49
  *
50
50
  * `appId` and `workspaceId` are platform-resolved identifiers stamped by
51
- * the CLI after `guuey create` / `guuey link`. A fresh project has neither.
52
- * After first `guuey create`, both may be present.
51
+ * the CLI after `guuey create` / `guuey pull --app-id`. A fresh project has
52
+ * neither. After first `guuey create`, both may be present.
53
53
  *
54
54
  * Re-exports the sub-section types for consumer convenience.
55
55
  */
@@ -68,6 +68,7 @@ export declare const GuueyJsonV1: z.ZodObject<{
68
68
  "google-adk": "google-adk";
69
69
  vanilla: "vanilla";
70
70
  }>>;
71
+ entry: z.ZodOptional<z.ZodString>;
71
72
  model: z.ZodOptional<z.ZodString>;
72
73
  modelProvider: z.ZodOptional<z.ZodEnum<{
73
74
  openai: "openai";
@@ -76,11 +77,10 @@ export declare const GuueyJsonV1: z.ZodObject<{
76
77
  systemPrompt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
77
78
  file: z.ZodString;
78
79
  }, z.core.$strict>]>>;
79
- 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<{
80
81
  kind: z.ZodLiteral<"colocated">;
81
- command: z.ZodString;
82
- args: z.ZodOptional<z.ZodArray<z.ZodString>>;
83
- headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
82
+ source: z.ZodString;
83
+ devPort: z.ZodOptional<z.ZodNumber>;
84
84
  }, z.core.$strict>, z.ZodObject<{
85
85
  kind: z.ZodLiteral<"hosted">;
86
86
  server: z.ZodOptional<z.ZodString>;
@@ -99,7 +99,12 @@ export declare const GuueyJsonV1: z.ZodObject<{
99
99
  federate: z.ZodOptional<z.ZodBoolean>;
100
100
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
101
101
  devPort: z.ZodOptional<z.ZodNumber>;
102
- }, z.core.$strict>], "kind">>>;
102
+ mcpResourceUrl: z.ZodOptional<z.ZodURL>;
103
+ profileAccess: z.ZodOptional<z.ZodEnum<{
104
+ read: "read";
105
+ "read-write": "read-write";
106
+ }>>;
107
+ }, z.core.$strict>], "kind">, z.ZodLiteral<false>]>>>;
103
108
  tools: z.ZodOptional<z.ZodObject<{
104
109
  allowlist: z.ZodOptional<z.ZodArray<z.ZodString>>;
105
110
  denylist: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -130,6 +135,10 @@ export declare const GuueyJsonV1: z.ZodObject<{
130
135
  user: "user";
131
136
  app: "app";
132
137
  }>>>;
138
+ profileAccess: z.ZodOptional<z.ZodEnum<{
139
+ read: "read";
140
+ "read-write": "read-write";
141
+ }>>;
133
142
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
134
143
  secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
135
144
  endpoint: z.ZodOptional<z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAEjE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmDtB,CAAC;AAEH,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAG3D,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;AAEvD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAExD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,WAAW,CAAC,SAAS,CAAC,CAE1C"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAgB,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAEjE;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmDtB,CAAC;AAEH,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEtD;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAG3D,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;AAEvD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,eAAe,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAExD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,WAAW,CAAC,SAAS,CAAC,CAE1C"}
package/dist/schema.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * - `ggui` (optional) — cross-protocol integration if the agent uses ggui rendering
9
9
  *
10
10
  * Plus top-level platform identity (`appId`, `workspaceId`) populated by
11
- * the CLI after `guuey create` / `guuey link`.
11
+ * the CLI after `guuey create` / `guuey pull --app-id`.
12
12
  *
13
13
  * **Filename convention** (filename = artifact kind, see design doc §3):
14
14
  * ```
@@ -48,8 +48,8 @@ import { GguiSectionV1 } from './ggui.js';
48
48
  * only an MCP server uses `guuey.mcp.json` instead (separate schema).
49
49
  *
50
50
  * `appId` and `workspaceId` are platform-resolved identifiers stamped by
51
- * the CLI after `guuey create` / `guuey link`. A fresh project has neither.
52
- * After first `guuey create`, both may be present.
51
+ * the CLI after `guuey create` / `guuey pull --app-id`. A fresh project has
52
+ * neither. After first `guuey create`, both may be present.
53
53
  *
54
54
  * Re-exports the sub-section types for consumer convenience.
55
55
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guuey/config",
3
- "version": "0.1.1",
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",
@@ -16,6 +16,16 @@
16
16
  "types": "./dist/index.d.ts",
17
17
  "import": "./dist/index.js",
18
18
  "default": "./dist/index.js"
19
+ },
20
+ "./registry": {
21
+ "types": "./dist/registry.d.ts",
22
+ "import": "./dist/registry.js",
23
+ "default": "./dist/registry.js"
24
+ },
25
+ "./browser": {
26
+ "types": "./dist/browser.d.ts",
27
+ "import": "./dist/browser.js",
28
+ "default": "./dist/browser.js"
19
29
  }
20
30
  },
21
31
  "dependencies": {