@ggui-ai/project-config 0.13.0 → 0.14.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/README.md CHANGED
@@ -57,7 +57,9 @@ if (path) {
57
57
  }
58
58
  ```
59
59
 
60
- `protocol` MUST match `PROTOCOL_VERSION` exported by `@ggui-ai/protocol` in the version installed.
60
+ **Contract:** `protocol` MUST be a member of `CLIENT_SUPPORTED_VERSIONS` exported by the installed `@ggui-ai/protocol` — membership, not equality with the current stamp. The loader (`loadGguiJson` / `safeLoadGguiJson` on the `./node` subpath) checks exactly that predicate — the wire's own — and refuses a non-member with `UPGRADE_REQUIRED` (`GguiJsonProtocolUnsupportedError`, carrying `declared` / `supported` / `current`). Pass `{ versionPolicy: 'advisory', onDiagnostic }` to load anyway and receive the same finding as a diagnostic; there is no third posture. The schema itself validates the field as pattern-only so an old declaration stays readable.
61
+
62
+ **House rule for files shipped as a starting point** (this repo's `samples/`): declare the CURRENT stamp, `PROTOCOL_VERSION` — pinned by the samples test. Today the supported set has one member, so the two rules coincide; when it grows, a supported-but-stale declaration still loads and only the samples pin insists on currency.
61
63
 
62
64
  Optional blocks: `storage` (renders / vectors / threads via `memory` or `sqlite`), `theme`, `primitives`, `blueprints`, `mcpMounts`, and `operator`. See the exported Zod schema for the full, authoritative shape.
63
65
 
package/dist/node.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { UPGRADE_REQUIRED } from '@ggui-ai/protocol';
1
2
  import { GguiJsonV1 } from './schema.js';
2
3
  /** How many parent directories `findGguiJson` will walk by default. */
3
4
  export declare const DEFAULT_FIND_MAX_DEPTH = 8;
@@ -23,16 +24,70 @@ export declare class GguiJsonLoadError extends Error {
23
24
  cause?: unknown;
24
25
  });
25
26
  }
27
+ /**
28
+ * How the loader treats a `protocol` declaration that is not in
29
+ * `CLIENT_SUPPORTED_VERSIONS` — the handshake's own knob: the same two
30
+ * postures and the same default (`reject`). A refusal, or a diagnostic
31
+ * that lets the load proceed. There is no third posture.
32
+ */
33
+ export type GguiJsonVersionPolicy = 'advisory' | 'reject';
34
+ /**
35
+ * The loader's protocol finding. Under `reject` it rides the thrown
36
+ * {@link GguiJsonProtocolUnsupportedError}; under `advisory` it reaches
37
+ * {@link LoadGguiJsonOptions.onDiagnostic} and the load continues.
38
+ */
39
+ export interface GguiJsonProtocolDiagnostic {
40
+ readonly kind: 'protocol-unsupported';
41
+ /** The canonical wire code — the loader's outcome IS the handshake's. */
42
+ readonly code: typeof UPGRADE_REQUIRED;
43
+ /** The `protocol` the file declares. */
44
+ readonly declared: string;
45
+ /** The set this installation speaks (`CLIENT_SUPPORTED_VERSIONS`). */
46
+ readonly supported: readonly string[];
47
+ /** The current stamp (`PROTOCOL_VERSION`) — what a fresh declaration writes. */
48
+ readonly current: string;
49
+ readonly path: string;
50
+ readonly message: string;
51
+ }
52
+ export interface LoadGguiJsonOptions {
53
+ /** @default 'reject' */
54
+ readonly versionPolicy?: GguiJsonVersionPolicy;
55
+ /** Receives the diagnostic under `'advisory'`; under `'reject'` the same facts ride the error. */
56
+ readonly onDiagnostic?: (diagnostic: GguiJsonProtocolDiagnostic) => void;
57
+ }
58
+ /**
59
+ * The loader's version refusal: the file declares a `protocol` outside
60
+ * `CLIENT_SUPPORTED_VERSIONS`, so nothing built on this installation
61
+ * can speak to it. `.code` is the canonical `UPGRADE_REQUIRED` —
62
+ * symmetric with the handshake's error frame — and `declared` /
63
+ * `supported` / `current` carry what an author needs to fix the file.
64
+ *
65
+ * A subclass of {@link GguiJsonLoadError}, so every existing catch site
66
+ * (and {@link safeLoadGguiJson}) handles it unchanged.
67
+ */
68
+ export declare class GguiJsonProtocolUnsupportedError extends GguiJsonLoadError {
69
+ readonly code: typeof UPGRADE_REQUIRED;
70
+ readonly declared: string;
71
+ readonly supported: readonly string[];
72
+ readonly current: string;
73
+ constructor(diagnostic: GguiJsonProtocolDiagnostic);
74
+ }
26
75
  /**
27
76
  * Read `ggui.json` at `path`, parse JSON, validate against the v1
28
- * schema. Returns the fully-defaulted document.
77
+ * schema, and check the declared `protocol` against what this
78
+ * installation speaks. Returns the fully-defaulted document.
29
79
  *
30
80
  * Throws {@link GguiJsonLoadError} if:
31
81
  * - the file does not exist,
32
82
  * - the file is not valid JSON,
33
- * - the document fails schema validation (cause set to `ZodError`).
83
+ * - the document fails schema validation (cause set to `ZodError`),
84
+ * - the declared `protocol` is not in `CLIENT_SUPPORTED_VERSIONS` and
85
+ * `options.versionPolicy` is `'reject'` (the default) — as the
86
+ * {@link GguiJsonProtocolUnsupportedError} subclass, carrying
87
+ * `UPGRADE_REQUIRED`. Under `'advisory'` that state loads and
88
+ * reaches `options.onDiagnostic` instead.
34
89
  */
35
- export declare function loadGguiJson(path: string): GguiJsonV1;
90
+ export declare function loadGguiJson(path: string, options?: LoadGguiJsonOptions): GguiJsonV1;
36
91
  /**
37
92
  * Result of {@link safeLoadGguiJson} — mirrors `z.safeParse` so
38
93
  * consumers can branch without try/catch.
@@ -47,9 +102,11 @@ export type SafeLoadResult = {
47
102
  /**
48
103
  * Non-throwing variant of {@link loadGguiJson}. Returns a
49
104
  * discriminated result. Use this in CLI surfaces that render issue
50
- * lists directly.
105
+ * lists directly. Same `options` and the same protocol default: an
106
+ * unsupported declaration comes back as `{ success: false, error }`
107
+ * with the {@link GguiJsonProtocolUnsupportedError}.
51
108
  */
52
- export declare function safeLoadGguiJson(path: string): SafeLoadResult;
109
+ export declare function safeLoadGguiJson(path: string, options?: LoadGguiJsonOptions): SafeLoadResult;
53
110
  /**
54
111
  * Serialize and write a `ggui.json` document to `path`. The input is
55
112
  * re-validated against the v1 schema before writing so a caller
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAqBA,OAAO,EAEL,UAAU,EAEX,MAAM,aAAa,CAAC;AAErB,uEAAuE;AACvE,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,GAAE,MAAsB,EAChC,QAAQ,GAAE,MAA+B,GACxC,MAAM,GAAG,IAAI,CAUf;AAED;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAKzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAoCrD;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GACnC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,CAAC;AAEjD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS7D;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,CAGhE;AAMD,OAAO,EACL,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAMrB,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AAOxB,OAAO,EACL,kBAAkB,EAClB,kCAAkC,EAClC,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,GAC/B,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,GAC9B,MAAM,0BAA0B,CAAC;AAIlC,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,uBAAuB,EACvB,2BAA2B,EAC3B,KAAK,kBAAkB,GACxB,MAAM,0BAA0B,CAAC;AAMlC,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AAMpB,OAAO,EACL,SAAS,EACT,yBAAyB,EACzB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
package/dist/node.js CHANGED
@@ -19,6 +19,7 @@
19
19
  */
20
20
  import { existsSync, readFileSync, writeFileSync } from 'node:fs';
21
21
  import { dirname, join, resolve } from 'node:path';
22
+ import { CLIENT_SUPPORTED_VERSIONS, PROTOCOL_VERSION, UPGRADE_REQUIRED, } from '@ggui-ai/protocol';
22
23
  import { GGUI_JSON_FILENAME, parseGguiJson, } from './schema.js';
23
24
  /** How many parent directories `findGguiJson` will walk by default. */
24
25
  export const DEFAULT_FIND_MAX_DEPTH = 8;
@@ -58,16 +59,76 @@ export class GguiJsonLoadError extends Error {
58
59
  this.path = path;
59
60
  }
60
61
  }
62
+ /**
63
+ * The loader's version refusal: the file declares a `protocol` outside
64
+ * `CLIENT_SUPPORTED_VERSIONS`, so nothing built on this installation
65
+ * can speak to it. `.code` is the canonical `UPGRADE_REQUIRED` —
66
+ * symmetric with the handshake's error frame — and `declared` /
67
+ * `supported` / `current` carry what an author needs to fix the file.
68
+ *
69
+ * A subclass of {@link GguiJsonLoadError}, so every existing catch site
70
+ * (and {@link safeLoadGguiJson}) handles it unchanged.
71
+ */
72
+ export class GguiJsonProtocolUnsupportedError extends GguiJsonLoadError {
73
+ code = UPGRADE_REQUIRED;
74
+ declared;
75
+ supported;
76
+ current;
77
+ constructor(diagnostic) {
78
+ super(diagnostic.message, diagnostic.path);
79
+ this.name = 'GguiJsonProtocolUnsupportedError';
80
+ this.declared = diagnostic.declared;
81
+ this.supported = diagnostic.supported;
82
+ this.current = diagnostic.current;
83
+ }
84
+ }
85
+ /**
86
+ * Membership, not currency, is the contract: the declaration must be
87
+ * IN the supported set — the wire's own predicate, one predicate for
88
+ * the file and the handshake. Never `=== PROTOCOL_VERSION`: the day the
89
+ * set has two members an exact-stamp check would refuse a declaration
90
+ * the wire accepts.
91
+ *
92
+ * In-set-but-not-current ("stale") is diagnostic-only by ruling and
93
+ * never a refusal. It is unreachable while the set is a singleton; add
94
+ * that diagnostic, with its test, when a second member lands.
95
+ */
96
+ function checkProtocolMembership(doc, path, options) {
97
+ if (CLIENT_SUPPORTED_VERSIONS.includes(doc.protocol))
98
+ return;
99
+ const diagnostic = {
100
+ kind: 'protocol-unsupported',
101
+ code: UPGRADE_REQUIRED,
102
+ declared: doc.protocol,
103
+ supported: CLIENT_SUPPORTED_VERSIONS,
104
+ current: PROTOCOL_VERSION,
105
+ path,
106
+ message: `ggui.json at ${path} declares protocol '${doc.protocol}', which this ` +
107
+ `installation does not speak (supported: [${CLIENT_SUPPORTED_VERSIONS.join(', ')}]). ` +
108
+ `Set "protocol" to '${PROTOCOL_VERSION}' (the current version), or install the ` +
109
+ `@ggui-ai/* packages that speak '${doc.protocol}'.`,
110
+ };
111
+ if ((options.versionPolicy ?? 'reject') === 'reject') {
112
+ throw new GguiJsonProtocolUnsupportedError(diagnostic);
113
+ }
114
+ options.onDiagnostic?.(diagnostic);
115
+ }
61
116
  /**
62
117
  * Read `ggui.json` at `path`, parse JSON, validate against the v1
63
- * schema. Returns the fully-defaulted document.
118
+ * schema, and check the declared `protocol` against what this
119
+ * installation speaks. Returns the fully-defaulted document.
64
120
  *
65
121
  * Throws {@link GguiJsonLoadError} if:
66
122
  * - the file does not exist,
67
123
  * - the file is not valid JSON,
68
- * - the document fails schema validation (cause set to `ZodError`).
124
+ * - the document fails schema validation (cause set to `ZodError`),
125
+ * - the declared `protocol` is not in `CLIENT_SUPPORTED_VERSIONS` and
126
+ * `options.versionPolicy` is `'reject'` (the default) — as the
127
+ * {@link GguiJsonProtocolUnsupportedError} subclass, carrying
128
+ * `UPGRADE_REQUIRED`. Under `'advisory'` that state loads and
129
+ * reaches `options.onDiagnostic` instead.
69
130
  */
70
- export function loadGguiJson(path) {
131
+ export function loadGguiJson(path, options = {}) {
71
132
  if (!existsSync(path)) {
72
133
  throw new GguiJsonLoadError(`ggui.json not found at ${path}`, path);
73
134
  }
@@ -85,21 +146,28 @@ export function loadGguiJson(path) {
85
146
  catch (cause) {
86
147
  throw new GguiJsonLoadError(`ggui.json at ${path} is not valid JSON`, path, { cause });
87
148
  }
149
+ let doc;
88
150
  try {
89
- return parseGguiJson(decoded);
151
+ doc = parseGguiJson(decoded);
90
152
  }
91
153
  catch (cause) {
92
154
  throw new GguiJsonLoadError(`ggui.json at ${path} failed schema validation`, path, { cause });
93
155
  }
156
+ // Outside the schema `try`: a version refusal is its own outcome,
157
+ // never re-wrapped as a schema failure.
158
+ checkProtocolMembership(doc, path, options);
159
+ return doc;
94
160
  }
95
161
  /**
96
162
  * Non-throwing variant of {@link loadGguiJson}. Returns a
97
163
  * discriminated result. Use this in CLI surfaces that render issue
98
- * lists directly.
164
+ * lists directly. Same `options` and the same protocol default: an
165
+ * unsupported declaration comes back as `{ success: false, error }`
166
+ * with the {@link GguiJsonProtocolUnsupportedError}.
99
167
  */
100
- export function safeLoadGguiJson(path) {
168
+ export function safeLoadGguiJson(path, options = {}) {
101
169
  try {
102
- return { success: true, data: loadGguiJson(path) };
170
+ return { success: true, data: loadGguiJson(path, options) };
103
171
  }
104
172
  catch (error) {
105
173
  if (error instanceof GguiJsonLoadError) {
package/dist/schema.d.ts CHANGED
@@ -153,7 +153,7 @@ export type StorageConfig = z.infer<typeof StorageSchema>;
153
153
  declare const GenerationSchema: z.ZodObject<{
154
154
  model: z.ZodPipe<z.ZodString, z.ZodTransform<{
155
155
  provider: "anthropic";
156
- model: "claude-fable-5" | "claude-opus-5" | "claude-sonnet-5" | "claude-haiku-4-5-20251001" | "claude-opus-4-8" | "claude-sonnet-4-6" | "claude-opus-4-7" | "claude-opus-4-6";
156
+ model: "claude-fable-5-1" | "claude-fable-5" | "claude-opus-5" | "claude-sonnet-5" | "claude-haiku-4-5-20251001" | "claude-opus-4-8" | "claude-sonnet-4-6" | "claude-opus-4-7" | "claude-opus-4-6";
157
157
  } | {
158
158
  provider: "openai";
159
159
  model: "gpt-5.6" | "gpt-5.6-sol" | "gpt-5.6-terra" | "gpt-5.6-luna" | "gpt-5.5" | "gpt-5.5-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-pro-2026-04-23" | "gpt-5.4" | "gpt-5.4-2026-03-05" | "gpt-5.4-mini" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-nano-2026-03-17" | "gpt-5.3-codex";
@@ -162,7 +162,7 @@ declare const GenerationSchema: z.ZodObject<{
162
162
  model: "gemini-3.7-flash" | "gemini-3.6-flash" | "gemini-3.5-flash" | "gemini-3.5-flash-lite" | "gemini-flash-latest" | "gemini-3.1-flash-lite" | "gemini-3.1-pro-preview" | "gemini-3.1-flash-lite-preview" | "gemini-3-flash-preview";
163
163
  } | {
164
164
  provider: "bedrock";
165
- model: (string & {}) | "anthropic.claude-fable-5" | "anthropic.claude-opus-5" | "anthropic.claude-sonnet-5" | "anthropic.claude-opus-4-8" | "us.anthropic.claude-haiku-4-5-20251001-v1:0" | "eu.anthropic.claude-haiku-4-5-20251001-v1:0" | "apac.anthropic.claude-haiku-4-5-20251001-v1:0" | "global.anthropic.claude-haiku-4-5-20251001-v1:0" | "us.anthropic.claude-sonnet-4-6" | "eu.anthropic.claude-sonnet-4-6" | "apac.anthropic.claude-sonnet-4-6" | "us.anthropic.claude-opus-4-7" | "eu.anthropic.claude-opus-4-7" | "apac.anthropic.claude-opus-4-7" | "global.anthropic.claude-opus-4-7" | "us.anthropic.claude-opus-4-6-v1";
165
+ model: (string & {}) | "anthropic.claude-fable-5-1" | "anthropic.claude-fable-5" | "anthropic.claude-opus-5" | "anthropic.claude-sonnet-5" | "anthropic.claude-opus-4-8" | "us.anthropic.claude-haiku-4-5-20251001-v1:0" | "eu.anthropic.claude-haiku-4-5-20251001-v1:0" | "apac.anthropic.claude-haiku-4-5-20251001-v1:0" | "global.anthropic.claude-haiku-4-5-20251001-v1:0" | "us.anthropic.claude-sonnet-4-6" | "eu.anthropic.claude-sonnet-4-6" | "apac.anthropic.claude-sonnet-4-6" | "us.anthropic.claude-opus-4-7" | "eu.anthropic.claude-opus-4-7" | "apac.anthropic.claude-opus-4-7" | "global.anthropic.claude-opus-4-7" | "us.anthropic.claude-opus-4-6-v1";
166
166
  } | {
167
167
  provider: "openrouter";
168
168
  model: (string & {}) | "anthropic/claude-fable-5" | "anthropic/claude-opus-5" | "anthropic/claude-sonnet-5" | "anthropic/claude-haiku-4.5" | "anthropic/claude-sonnet-4.6" | "anthropic/claude-opus-4.7" | "openai/gpt-5.6-sol" | "openai/gpt-5.6-terra" | "openai/gpt-5.6-luna" | "openai/gpt-5.5" | "openai/gpt-5.5-pro" | "openai/gpt-5.4-mini" | "openai/gpt-5.4-nano" | "google/gemini-3.6-flash" | "google/gemini-3.5-flash" | "google/gemini-3.5-flash-lite" | "google/gemini-3.1-pro-preview" | "google/gemini-3.1-flash-lite" | "x-ai/grok-4.3" | "meta-llama/llama-4-maverick" | "meta-llama/llama-3.3-70b-instruct" | "deepseek/deepseek-v4-pro" | "deepseek/deepseek-r1-0528" | "qwen/qwen3.7-max" | "qwen/qwen3-coder" | "mistralai/mistral-large-2512" | "openai/gpt-oss-120b";
@@ -330,7 +330,7 @@ export declare const GguiJsonV1: z.ZodObject<{
330
330
  generation: z.ZodOptional<z.ZodObject<{
331
331
  model: z.ZodPipe<z.ZodString, z.ZodTransform<{
332
332
  provider: "anthropic";
333
- model: "claude-fable-5" | "claude-opus-5" | "claude-sonnet-5" | "claude-haiku-4-5-20251001" | "claude-opus-4-8" | "claude-sonnet-4-6" | "claude-opus-4-7" | "claude-opus-4-6";
333
+ model: "claude-fable-5-1" | "claude-fable-5" | "claude-opus-5" | "claude-sonnet-5" | "claude-haiku-4-5-20251001" | "claude-opus-4-8" | "claude-sonnet-4-6" | "claude-opus-4-7" | "claude-opus-4-6";
334
334
  } | {
335
335
  provider: "openai";
336
336
  model: "gpt-5.6" | "gpt-5.6-sol" | "gpt-5.6-terra" | "gpt-5.6-luna" | "gpt-5.5" | "gpt-5.5-2026-04-23" | "gpt-5.5-pro" | "gpt-5.5-pro-2026-04-23" | "gpt-5.4" | "gpt-5.4-2026-03-05" | "gpt-5.4-mini" | "gpt-5.4-mini-2026-03-17" | "gpt-5.4-nano" | "gpt-5.4-nano-2026-03-17" | "gpt-5.3-codex";
@@ -339,7 +339,7 @@ export declare const GguiJsonV1: z.ZodObject<{
339
339
  model: "gemini-3.7-flash" | "gemini-3.6-flash" | "gemini-3.5-flash" | "gemini-3.5-flash-lite" | "gemini-flash-latest" | "gemini-3.1-flash-lite" | "gemini-3.1-pro-preview" | "gemini-3.1-flash-lite-preview" | "gemini-3-flash-preview";
340
340
  } | {
341
341
  provider: "bedrock";
342
- model: (string & {}) | "anthropic.claude-fable-5" | "anthropic.claude-opus-5" | "anthropic.claude-sonnet-5" | "anthropic.claude-opus-4-8" | "us.anthropic.claude-haiku-4-5-20251001-v1:0" | "eu.anthropic.claude-haiku-4-5-20251001-v1:0" | "apac.anthropic.claude-haiku-4-5-20251001-v1:0" | "global.anthropic.claude-haiku-4-5-20251001-v1:0" | "us.anthropic.claude-sonnet-4-6" | "eu.anthropic.claude-sonnet-4-6" | "apac.anthropic.claude-sonnet-4-6" | "us.anthropic.claude-opus-4-7" | "eu.anthropic.claude-opus-4-7" | "apac.anthropic.claude-opus-4-7" | "global.anthropic.claude-opus-4-7" | "us.anthropic.claude-opus-4-6-v1";
342
+ model: (string & {}) | "anthropic.claude-fable-5-1" | "anthropic.claude-fable-5" | "anthropic.claude-opus-5" | "anthropic.claude-sonnet-5" | "anthropic.claude-opus-4-8" | "us.anthropic.claude-haiku-4-5-20251001-v1:0" | "eu.anthropic.claude-haiku-4-5-20251001-v1:0" | "apac.anthropic.claude-haiku-4-5-20251001-v1:0" | "global.anthropic.claude-haiku-4-5-20251001-v1:0" | "us.anthropic.claude-sonnet-4-6" | "eu.anthropic.claude-sonnet-4-6" | "apac.anthropic.claude-sonnet-4-6" | "us.anthropic.claude-opus-4-7" | "eu.anthropic.claude-opus-4-7" | "apac.anthropic.claude-opus-4-7" | "global.anthropic.claude-opus-4-7" | "us.anthropic.claude-opus-4-6-v1";
343
343
  } | {
344
344
  provider: "openrouter";
345
345
  model: (string & {}) | "anthropic/claude-fable-5" | "anthropic/claude-opus-5" | "anthropic/claude-sonnet-5" | "anthropic/claude-haiku-4.5" | "anthropic/claude-sonnet-4.6" | "anthropic/claude-opus-4.7" | "openai/gpt-5.6-sol" | "openai/gpt-5.6-terra" | "openai/gpt-5.6-luna" | "openai/gpt-5.5" | "openai/gpt-5.5-pro" | "openai/gpt-5.4-mini" | "openai/gpt-5.4-nano" | "google/gemini-3.6-flash" | "google/gemini-3.5-flash" | "google/gemini-3.5-flash-lite" | "google/gemini-3.1-pro-preview" | "google/gemini-3.1-flash-lite" | "x-ai/grok-4.3" | "meta-llama/llama-4-maverick" | "meta-llama/llama-3.3-70b-instruct" | "deepseek/deepseek-v4-pro" | "deepseek/deepseek-r1-0528" | "qwen/qwen3.7-max" | "qwen/qwen3-coder" | "mistralai/mistral-large-2512" | "openai/gpt-oss-120b";
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmHxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,cAAc;;;;;kBAoBlB,CAAC;AAEH,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AA+H5D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;oBAI5B,CAAC;AAqEH;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB;;;;;8BAGxB,CAAC;AAEH,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;kBAejB,CAAC;AAEH;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,oDAAoD;AACpD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;kBA6CpB,CAAC;AAEH;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiKrB,CAAC;AAEH,yDAAyD;AACzD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,UAAU,CAAC,SAAS,CAAC,CAEzC"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwHxB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,cAAc;;;;;kBAoBlB,CAAC;AAEH,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AA+H5D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;oBAI5B,CAAC;AAqEH;;;;;GAKG;AACH,QAAA,MAAM,oBAAoB;;;;;8BAGxB,CAAC;AAEH,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;kBAejB,CAAC;AAEH;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAExE,oDAAoD;AACpD,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;kBA6CpB,CAAC;AAEH;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiKrB,CAAC;AAEH,yDAAyD;AACzD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,UAAU,CAAC,SAAS,CAAC,CAEzC"}
package/dist/schema.js CHANGED
@@ -66,10 +66,15 @@ const SlugSchema = z
66
66
  * The wire contract version this app speaks — distinct from the
67
67
  * `schema` field which versions the file format itself.
68
68
  *
69
- * Future tightening: could import a known-versions list from
70
- * `@ggui-ai/protocol` and validate membership. Deliberately left as
71
- * pattern-only for v1 to avoid the cross-package dep until a real
72
- * consumer benefits from the tighter check.
69
+ * Pattern-only HERE by design, and stays so: `ggui.json` is a
70
+ * declaration layer, and a parser that rejected a well-formed old
71
+ * declaration would make the file unreadable exactly when the reader
72
+ * must say "upgrade" — unparseable is not unsupported. Membership
73
+ * against `CLIENT_SUPPORTED_VERSIONS` is the LOADER's check
74
+ * (`loadGguiJson` in `./node.ts`), which refuses non-members with the
75
+ * wire's own `UPGRADE_REQUIRED` under the handshake's `versionPolicy`
76
+ * knob. Shipped samples additionally pin the CURRENT stamp as a house
77
+ * rule (`samples-protocol.conformance.test.ts`).
73
78
  */
74
79
  const ProtocolVersionSchema = z
75
80
  .string()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/project-config",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Schema and loader for `ggui.json` — the portable app/agent manifest for the ggui protocol. Vendor-neutral. Consumed by the `ggui` CLI and any host that reconstitutes an agent from the manifest.",
5
5
  "keywords": [
6
6
  "ggui",
@@ -33,8 +33,8 @@
33
33
  "dependencies": {
34
34
  "tinyglobby": "^0.2.16",
35
35
  "zod": "^4.3.6",
36
- "@ggui-ai/design": "0.13.0",
37
- "@ggui-ai/protocol": "0.13.0"
36
+ "@ggui-ai/design": "0.14.0",
37
+ "@ggui-ai/protocol": "0.14.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^24.0.0",
@@ -54,7 +54,7 @@
54
54
  "access": "public"
55
55
  },
56
56
  "engines": {
57
- "node": ">=20.0.0"
57
+ "node": ">=22.0.0"
58
58
  },
59
59
  "author": "ggui contributors <hello@ggui.ai>",
60
60
  "scripts": {