@guuey/config 0.1.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.
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Guuey hosted control-plane types — agent sizing, deployment
3
+ * lifecycle, and the streaming events Guuey's backend emits during
4
+ * deploys.
5
+ *
6
+ * These types describe Guuey hosting concerns: `DeployTarget`
7
+ * includes the `'ggui'` vendor literal, `DeployEvent` is streamed by
8
+ * Guuey's AppSync subscription, and `HostingConfig` is a shape on
9
+ * `guuey.json`. They lived in `@ggui-ai/protocol` until 2026-04-18
10
+ * as a historical artefact — they were never vendor-neutral wire
11
+ * types. Relocated here as part of the overlay-type cleanup in the
12
+ * two-file manifest model. See
13
+ * `docs/plans/2026-04-17-ggui-oss-split.md` §8 for the lock.
14
+ *
15
+ * Open packages must not import from this module. Consumers today
16
+ * are all closed (`@guuey-private/types`, `cloud/`). If an open
17
+ * package ever needs one of these types, re-evaluate the
18
+ * classification before adding the import — most likely the open
19
+ * code should not depend on hosted-control-plane shapes at all.
20
+ */
21
+ /**
22
+ * Agent container size — describes workload intensity.
23
+ * Developers pick a size; Guuey maps it to CPU/memory internally.
24
+ *
25
+ * Exported as a tuple so `schema.ts` can reuse the same canonical list
26
+ * when building the `deploy.size` zod enum. Keeping one source of truth
27
+ * for the literal set avoids the two drifting — the hosting type and
28
+ * the `guuey.json` overlay must always agree on what sizes exist.
29
+ */
30
+ export declare const AGENT_SIZES: readonly ["xs", "sm", "md", "lg", "xl"];
31
+ export type AgentSize = (typeof AGENT_SIZES)[number];
32
+ /**
33
+ * Deployment target — where the agent runs. `'ggui'` is the Guuey
34
+ * hosted platform; the other literals are recognised but not
35
+ * first-party.
36
+ */
37
+ export type DeployTarget = 'ggui' | 'fly' | 'railway' | 'self';
38
+ /**
39
+ * Deployment lifecycle status — superset of all states.
40
+ *
41
+ * Transient states (building, pushing, deploying, health_checking)
42
+ * exist only in {@link DeployEvent} streams. The backend stores only
43
+ * settled states (not_deployed, live, failed, stopped, rolled_back).
44
+ * The persisted enum is intentionally narrower.
45
+ */
46
+ export type DeploymentStatus = 'not_deployed' | 'building' | 'pushing' | 'deploying' | 'health_checking' | 'live' | 'failed' | 'stopped' | 'rolled_back';
47
+ /**
48
+ * Progress event emitted during deployment.
49
+ * Streamed to CLI and Platform Dashboard via AppSync subscription.
50
+ */
51
+ export interface DeployEvent {
52
+ /** App being deployed */
53
+ appId: string;
54
+ /** Unique build identifier */
55
+ buildId: string;
56
+ /** Current deployment phase */
57
+ status: DeploymentStatus;
58
+ /** Human-readable progress message */
59
+ message: string;
60
+ /** ISO 8601 timestamp */
61
+ timestamp: string;
62
+ /** Deployment version number (set when deploying or later) */
63
+ version?: number;
64
+ /** Live endpoint URL (set when status = 'live') */
65
+ url?: string;
66
+ /** Error details (set when status = 'failed') */
67
+ error?: string;
68
+ }
69
+ /**
70
+ * Hosting configuration field in `guuey.json`.
71
+ */
72
+ export interface HostingConfig {
73
+ /** Agent container size (default: 'xs' for free, 'sm' for paid) */
74
+ size?: AgentSize;
75
+ /** Deployment target (default: 'ggui') */
76
+ target?: DeployTarget;
77
+ }
78
+ //# sourceMappingURL=hosting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosting.d.ts","sourceRoot":"","sources":["../src/hosting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,yCAA0C,CAAC;AACnE,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GACxB,cAAc,GACd,UAAU,GACV,SAAS,GACT,WAAW,GACX,iBAAiB,GACjB,MAAM,GACN,QAAQ,GACR,SAAS,GACT,aAAa,CAAC;AAElB;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,MAAM,EAAE,gBAAgB,CAAC;IACzB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Guuey hosted control-plane types — agent sizing, deployment
3
+ * lifecycle, and the streaming events Guuey's backend emits during
4
+ * deploys.
5
+ *
6
+ * These types describe Guuey hosting concerns: `DeployTarget`
7
+ * includes the `'ggui'` vendor literal, `DeployEvent` is streamed by
8
+ * Guuey's AppSync subscription, and `HostingConfig` is a shape on
9
+ * `guuey.json`. They lived in `@ggui-ai/protocol` until 2026-04-18
10
+ * as a historical artefact — they were never vendor-neutral wire
11
+ * types. Relocated here as part of the overlay-type cleanup in the
12
+ * two-file manifest model. See
13
+ * `docs/plans/2026-04-17-ggui-oss-split.md` §8 for the lock.
14
+ *
15
+ * Open packages must not import from this module. Consumers today
16
+ * are all closed (`@guuey-private/types`, `cloud/`). If an open
17
+ * package ever needs one of these types, re-evaluate the
18
+ * classification before adding the import — most likely the open
19
+ * code should not depend on hosted-control-plane shapes at all.
20
+ */
21
+ /**
22
+ * Agent container size — describes workload intensity.
23
+ * Developers pick a size; Guuey maps it to CPU/memory internally.
24
+ *
25
+ * Exported as a tuple so `schema.ts` can reuse the same canonical list
26
+ * when building the `deploy.size` zod enum. Keeping one source of truth
27
+ * for the literal set avoids the two drifting — the hosting type and
28
+ * the `guuey.json` overlay must always agree on what sizes exist.
29
+ */
30
+ export const AGENT_SIZES = ['xs', 'sm', 'md', 'lg', 'xl'];
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `@guuey/config` — schemas + loaders for `guuey.json` (the merged
3
+ * platform config file).
4
+ *
5
+ * Post-2026-05-25 slice 7.2: `agent.json` was merged into
6
+ * `guuey.json#agent`. See `docs/plans/2026-05-25-platform-architecture.md`
7
+ * §3.1 + §14.2 for the canonical shape + field-by-field migration.
8
+ *
9
+ * Consumers: `@guuey/cli`, guuey backend (cliApi handlers,
10
+ * nocode-runtime, deploy-controller), framework adapters under
11
+ * `oss/packages/frameworks/*`.
12
+ */
13
+ export * from './schema.js';
14
+ export * from './agent.js';
15
+ export * from './app.js';
16
+ export * from './ggui.js';
17
+ export * from './loader.js';
18
+ export * from './hosting.js';
19
+ export * from './system-prompt.js';
20
+ export * from './registry.js';
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `@guuey/config` — schemas + loaders for `guuey.json` (the merged
3
+ * platform config file).
4
+ *
5
+ * Post-2026-05-25 slice 7.2: `agent.json` was merged into
6
+ * `guuey.json#agent`. See `docs/plans/2026-05-25-platform-architecture.md`
7
+ * §3.1 + §14.2 for the canonical shape + field-by-field migration.
8
+ *
9
+ * Consumers: `@guuey/cli`, guuey backend (cliApi handlers,
10
+ * nocode-runtime, deploy-controller), framework adapters under
11
+ * `oss/packages/frameworks/*`.
12
+ */
13
+ export * from './schema.js';
14
+ export * from './agent.js';
15
+ export * from './app.js';
16
+ export * from './ggui.js';
17
+ export * from './loader.js';
18
+ export * from './hosting.js';
19
+ export * from './system-prompt.js';
20
+ export * from './registry.js';
@@ -0,0 +1,70 @@
1
+ import { GuueyJsonV1 } from './schema.js';
2
+ /** How many parent directories `findGuueyJson` will walk by default. */
3
+ export declare const DEFAULT_FIND_MAX_DEPTH = 8;
4
+ /**
5
+ * Walk up from `startDir` (default: `process.cwd()`) looking for a
6
+ * `guuey.json`. Returns the absolute path to the first match, or
7
+ * `null` if no file is found within `maxDepth` levels.
8
+ *
9
+ * Stops when the filesystem root is reached, regardless of `maxDepth`.
10
+ * Never throws — a missing file is a valid result (not in a guuey project),
11
+ * not an error.
12
+ */
13
+ export declare function findGuueyJson(startDir?: string, maxDepth?: number): string | null;
14
+ /**
15
+ * Read + parse `guuey.json` from `path`. Throws if the file is missing,
16
+ * unreadable, malformed JSON, or fails schema validation.
17
+ *
18
+ * Does NOT resolve `agent.systemPrompt.file` references. Use
19
+ * {@link loadGuueyJson} for file resolution.
20
+ */
21
+ export declare function readGuueyJsonFile(path: string): GuueyJsonV1;
22
+ /**
23
+ * Write a `guuey.json` to disk at `path` with stable 2-space indentation
24
+ * and a trailing newline.
25
+ *
26
+ * Validates the document against {@link GuueyJsonV1} before writing — bad
27
+ * data never lands on disk.
28
+ */
29
+ export declare function writeGuueyJsonFile(path: string, doc: GuueyJsonV1): void;
30
+ /**
31
+ * Result of resolving file-references inside a `guuey.json` document.
32
+ *
33
+ * `doc` is the original document (with `{ file: '...' }` references intact);
34
+ * `resolvedSystemPrompt` is the inlined string the pod will use at boot.
35
+ */
36
+ export interface ResolvedGuueyJson {
37
+ /** The original parsed document. */
38
+ doc: GuueyJsonV1;
39
+ /**
40
+ * The resolved system prompt — either the inline string from
41
+ * `agent.systemPrompt`, or the file contents when it was a
42
+ * `{ file: '...' }` reference, or `undefined` when no prompt was set
43
+ * (caller falls back to `GUUEY_DEFAULT_SYSTEM_PROMPT`).
44
+ */
45
+ resolvedSystemPrompt: string | undefined;
46
+ /** Absolute path the document was loaded from (for diagnostics). */
47
+ sourcePath: string;
48
+ }
49
+ /**
50
+ * Load + parse `guuey.json` from `path`, then resolve any
51
+ * `agent.systemPrompt.file` reference into an inlined string.
52
+ *
53
+ * The resolved prompt is returned alongside the parsed document so callers
54
+ * can choose how to use it. The deploy snapshot inlines it into a string
55
+ * shape; the pod runtime reads the resolved prompt directly.
56
+ *
57
+ * Throws if the file is missing, unreadable, malformed, fails schema
58
+ * validation, OR the systemPrompt.file path resolves to a missing or
59
+ * unreadable file.
60
+ */
61
+ export declare function loadGuueyJson(path: string): ResolvedGuueyJson;
62
+ /**
63
+ * Build the snapshot the deploy upload + pod boot consume.
64
+ *
65
+ * Replaces `agent.systemPrompt = { file }` with `agent.systemPrompt = <inlined>`
66
+ * so the snapshot is self-contained. Returns a deep-cloned document
67
+ * (caller mutations don't leak back).
68
+ */
69
+ export declare function buildDeploySnapshot(loaded: ResolvedGuueyJson): GuueyJsonV1;
70
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAuBA,OAAO,EAEL,WAAW,EAEZ,MAAM,aAAa,CAAC;AAErB,wEAAwE;AACxE,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,GAAE,MAAsB,EAChC,QAAQ,GAAE,MAA+B,GACxC,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAa3D;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAIvE;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,GAAG,EAAE,WAAW,CAAC;IACjB;;;;;OAKG;IACH,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAI7D;AAyCD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAM1E"}
package/dist/loader.js ADDED
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Node-only filesystem helpers for `guuey.json`.
3
+ *
4
+ * Pure-parse helpers (`parseGuueyJson` / `safeParseGuueyJson`) live in
5
+ * `./schema.ts` and are safe to import from non-Node contexts. This
6
+ * module adds the file-resolution layer: reading `guuey.json` from disk,
7
+ * inlining `agent.systemPrompt.file` references, and producing the
8
+ * snapshot the deploy upload + pod boot both read.
9
+ *
10
+ * Intended callers:
11
+ *
12
+ * - `@guuey/cli` — `guuey deploy` reads + inlines + POSTs the snapshot.
13
+ * - `@guuey/cli` — `guuey pull` writes back from a hosted record.
14
+ * - Guuey control-plane services that re-validate a submitted snapshot
15
+ * server-side before persisting to `AgentDeployment`.
16
+ * - `nocode-runtime` / `@guuey/host` — pod reads the snapshot back at boot
17
+ * (from the env-injected JSON, not directly from disk).
18
+ *
19
+ * The open `ggui` ecosystem must NOT import from this package — `guuey.json`
20
+ * is Guuey platform config, not protocol shape.
21
+ */
22
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
23
+ import { dirname, isAbsolute, join, resolve } from 'node:path';
24
+ import { GUUEY_JSON_FILENAME, parseGuueyJson, } from './schema.js';
25
+ /** How many parent directories `findGuueyJson` will walk by default. */
26
+ export const DEFAULT_FIND_MAX_DEPTH = 8;
27
+ /**
28
+ * Walk up from `startDir` (default: `process.cwd()`) looking for a
29
+ * `guuey.json`. Returns the absolute path to the first match, or
30
+ * `null` if no file is found within `maxDepth` levels.
31
+ *
32
+ * Stops when the filesystem root is reached, regardless of `maxDepth`.
33
+ * Never throws — a missing file is a valid result (not in a guuey project),
34
+ * not an error.
35
+ */
36
+ export function findGuueyJson(startDir = process.cwd(), maxDepth = DEFAULT_FIND_MAX_DEPTH) {
37
+ let dir = resolve(startDir);
38
+ for (let i = 0; i <= maxDepth; i++) {
39
+ const candidate = join(dir, GUUEY_JSON_FILENAME);
40
+ if (existsSync(candidate))
41
+ return candidate;
42
+ const parent = dirname(dir);
43
+ if (parent === dir)
44
+ return null;
45
+ dir = parent;
46
+ }
47
+ return null;
48
+ }
49
+ /**
50
+ * Read + parse `guuey.json` from `path`. Throws if the file is missing,
51
+ * unreadable, malformed JSON, or fails schema validation.
52
+ *
53
+ * Does NOT resolve `agent.systemPrompt.file` references. Use
54
+ * {@link loadGuueyJson} for file resolution.
55
+ */
56
+ export function readGuueyJsonFile(path) {
57
+ if (!existsSync(path)) {
58
+ throw new Error(`guuey.json not found at ${path}`);
59
+ }
60
+ const raw = readFileSync(path, 'utf-8');
61
+ let json;
62
+ try {
63
+ json = JSON.parse(raw);
64
+ }
65
+ catch (err) {
66
+ const msg = err instanceof Error ? err.message : String(err);
67
+ throw new Error(`guuey.json at ${path} is not valid JSON: ${msg}`);
68
+ }
69
+ return parseGuueyJson(json);
70
+ }
71
+ /**
72
+ * Write a `guuey.json` to disk at `path` with stable 2-space indentation
73
+ * and a trailing newline.
74
+ *
75
+ * Validates the document against {@link GuueyJsonV1} before writing — bad
76
+ * data never lands on disk.
77
+ */
78
+ export function writeGuueyJsonFile(path, doc) {
79
+ const validated = parseGuueyJson(doc);
80
+ const serialized = JSON.stringify(validated, null, 2) + '\n';
81
+ writeFileSync(path, serialized, 'utf-8');
82
+ }
83
+ /**
84
+ * Load + parse `guuey.json` from `path`, then resolve any
85
+ * `agent.systemPrompt.file` reference into an inlined string.
86
+ *
87
+ * The resolved prompt is returned alongside the parsed document so callers
88
+ * can choose how to use it. The deploy snapshot inlines it into a string
89
+ * shape; the pod runtime reads the resolved prompt directly.
90
+ *
91
+ * Throws if the file is missing, unreadable, malformed, fails schema
92
+ * validation, OR the systemPrompt.file path resolves to a missing or
93
+ * unreadable file.
94
+ */
95
+ export function loadGuueyJson(path) {
96
+ const doc = readGuueyJsonFile(path);
97
+ const resolvedSystemPrompt = resolveSystemPrompt(doc, path);
98
+ return { doc, resolvedSystemPrompt, sourcePath: path };
99
+ }
100
+ /**
101
+ * Resolve `agent.systemPrompt` to a final string (or undefined).
102
+ *
103
+ * - Absent → undefined (caller applies platform default).
104
+ * - Inline string → returned as-is.
105
+ * - `{ file }` → resolved relative to `guueyJsonPath`'s directory, file read.
106
+ *
107
+ * File paths must be relative + must not escape the project root (no
108
+ * `..` traversal). Absolute paths are rejected — keeps the snapshot
109
+ * portable across deploy environments.
110
+ */
111
+ function resolveSystemPrompt(doc, guueyJsonPath) {
112
+ const sp = doc.agent.systemPrompt;
113
+ if (sp === undefined)
114
+ return undefined;
115
+ if (typeof sp === 'string')
116
+ return sp;
117
+ // sp = { file: '...' }
118
+ if (isAbsolute(sp.file)) {
119
+ throw new Error(`agent.systemPrompt.file must be a relative path (got absolute: ${sp.file})`);
120
+ }
121
+ if (sp.file.split('/').includes('..')) {
122
+ throw new Error(`agent.systemPrompt.file must not traverse parent directories (got: ${sp.file})`);
123
+ }
124
+ const baseDir = dirname(guueyJsonPath);
125
+ const resolved = resolve(baseDir, sp.file);
126
+ if (!existsSync(resolved)) {
127
+ throw new Error(`agent.systemPrompt.file references missing file: ${sp.file} (resolved to ${resolved})`);
128
+ }
129
+ return readFileSync(resolved, 'utf-8');
130
+ }
131
+ /**
132
+ * Build the snapshot the deploy upload + pod boot consume.
133
+ *
134
+ * Replaces `agent.systemPrompt = { file }` with `agent.systemPrompt = <inlined>`
135
+ * so the snapshot is self-contained. Returns a deep-cloned document
136
+ * (caller mutations don't leak back).
137
+ */
138
+ export function buildDeploySnapshot(loaded) {
139
+ const cloned = JSON.parse(JSON.stringify(loaded.doc));
140
+ if (loaded.resolvedSystemPrompt !== undefined) {
141
+ cloned.agent.systemPrompt = loaded.resolvedSystemPrompt;
142
+ }
143
+ return cloned;
144
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * `mcpProxies` — Guuey hosted overlay shape for managed MCP relays.
3
+ *
4
+ * Relocated 2026-04-21 from `@ggui-ai/protocol/types/mcp-proxy.ts` as
5
+ * part of the OSS split §8.2 classification fix. These types describe
6
+ * a GUUEY HOSTING CONCEPT (a managed proxy that relays MCP calls with
7
+ * upstream OAuth linking), not a vendor-neutral protocol shape, and
8
+ * therefore belong in the closed `@guuey/config`
9
+ * package alongside the rest of `guuey.json`.
10
+ *
11
+ * ## The classification decision
12
+ *
13
+ * `mcpProxies` is the declaration block a developer adds to
14
+ * `guuey.json` to tell Guuey hosting: *"on behalf of this project,
15
+ * relay these external MCP providers, using this OAuth linking
16
+ * config, exposing these discovered servers."* That is
17
+ * platform-layer plumbing — Guuey runs the relay, handles the
18
+ * credential storage, dispatches the discovery — and it does not
19
+ * describe anything an OSS-only `ggui` deployment emits or consumes.
20
+ *
21
+ * Per §8.2: the OSS `ggui` server does NOT read `guuey.json`.
22
+ * Consumers that need overlay values (the closed `guuey` CLI,
23
+ * Guuey-hosted Lambdas, the Guuey-internal control-plane UI) are
24
+ * the only call sites allowed to import from this package. Open
25
+ * packages that historically read `mcpProxies` (`@ggui-ai/server`'s
26
+ * Claude-passthrough feature) retain their feature code but inline
27
+ * the minimal structural shape they actually use — it stays a
28
+ * Guuey-platform plumbing path, not a protocol contract.
29
+ *
30
+ * ## Scope of this module
31
+ *
32
+ * - {@link McpProxyLinkingConfig} — upstream OAuth config for
33
+ * proxies that relay calls on behalf of an external account
34
+ * (e.g. Claude.ai). Keys surface in the Guuey control plane's
35
+ * credential-linking UI.
36
+ * - {@link McpProxyConfig} — a single proxy's discovery + proxy
37
+ * URL pattern + optional server filter + optional linking block.
38
+ * - {@link McpProxiesConfig} — the top-level record keyed by
39
+ * proxy id (`claude_ai`, `guuey`, future `omo`...). Exactly the
40
+ * shape `guuey.json#mcpProxies` carries.
41
+ *
42
+ * ## Vendor-neutral constants stay in `@ggui-ai/protocol`
43
+ *
44
+ * Claude.ai-specific constants and discovery-response wire types
45
+ * (`CLAUDE_AI_*`, `DiscoveredMcpServer`, `ClaudeAiDiscoveryResponse`)
46
+ * remain in `@ggui-ai/protocol/types/mcp-proxy.ts` — those describe
47
+ * Anthropic's public API, not Guuey-overlay config.
48
+ *
49
+ * ## Strictness
50
+ *
51
+ * Zod validation matches the rest of `guuey.json`: strict objects,
52
+ * non-empty strings, URL validation on linking endpoints. Unknown
53
+ * keys on nested objects fail parse (prevents silent drift toward
54
+ * a "what else can we stuff into guuey.json" shape).
55
+ */
56
+ import { z } from 'zod';
57
+ /**
58
+ * OAuth linking config for proxies that relay on behalf of an
59
+ * external account. Omit for proxies where Guuey session auth is
60
+ * the only identity needed (e.g. a Guuey-native proxy).
61
+ */
62
+ declare const McpProxyLinkingSchema: z.ZodObject<{
63
+ authUrl: z.ZodURL;
64
+ tokenUrl: z.ZodURL;
65
+ scopes: z.ZodArray<z.ZodString>;
66
+ clientId: z.ZodOptional<z.ZodString>;
67
+ manualRedirectUrl: z.ZodOptional<z.ZodURL>;
68
+ }, z.core.$strict>;
69
+ /**
70
+ * Configuration for a single MCP proxy in `guuey.json#mcpProxies`.
71
+ *
72
+ * `discovery` + `proxy` are both URL-valued, but `proxy` is a URL
73
+ * PATTERN (contains `{server_id}` which is substituted at call
74
+ * time). Both are validated as URLs — `{server_id}` is accepted
75
+ * by URL parsers as opaque path segment.
76
+ */
77
+ declare const McpProxyConfigSchema: z.ZodObject<{
78
+ discovery: z.ZodURL;
79
+ proxy: z.ZodURL;
80
+ linking: z.ZodOptional<z.ZodObject<{
81
+ authUrl: z.ZodURL;
82
+ tokenUrl: z.ZodURL;
83
+ scopes: z.ZodArray<z.ZodString>;
84
+ clientId: z.ZodOptional<z.ZodString>;
85
+ manualRedirectUrl: z.ZodOptional<z.ZodURL>;
86
+ }, z.core.$strict>>;
87
+ servers: z.ZodOptional<z.ZodArray<z.ZodString>>;
88
+ }, z.core.$strict>;
89
+ /**
90
+ * The `mcpProxies` section of `guuey.json`. Keys are proxy
91
+ * identifiers (`claude_ai`, `guuey`, future `omo`, …).
92
+ *
93
+ * Record shape intentionally — new proxy ids are additive; a fixed
94
+ * literal union here would force a schema change every time a new
95
+ * hosted-relay integration lands.
96
+ */
97
+ export declare const McpProxiesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
98
+ discovery: z.ZodURL;
99
+ proxy: z.ZodURL;
100
+ linking: z.ZodOptional<z.ZodObject<{
101
+ authUrl: z.ZodURL;
102
+ tokenUrl: z.ZodURL;
103
+ scopes: z.ZodArray<z.ZodString>;
104
+ clientId: z.ZodOptional<z.ZodString>;
105
+ manualRedirectUrl: z.ZodOptional<z.ZodURL>;
106
+ }, z.core.$strict>>;
107
+ servers: z.ZodOptional<z.ZodArray<z.ZodString>>;
108
+ }, z.core.$strict>>;
109
+ /** Linking block type derived from the zod schema. */
110
+ export type McpProxyLinkingConfig = z.infer<typeof McpProxyLinkingSchema>;
111
+ /** Single-proxy config type derived from the zod schema. */
112
+ export type McpProxyConfig = z.infer<typeof McpProxyConfigSchema>;
113
+ /** Full `mcpProxies` overlay type derived from the zod schema. */
114
+ export type McpProxiesConfig = z.infer<typeof McpProxiesSchema>;
115
+ /**
116
+ * Parse a raw JSON value into a validated {@link McpProxiesConfig}.
117
+ * Throws a `ZodError` on invalid input.
118
+ */
119
+ export declare function parseMcpProxies(raw: unknown): McpProxiesConfig;
120
+ /** Safe-parse variant — see {@link parseMcpProxies}. */
121
+ export declare function safeParseMcpProxies(raw: unknown): ReturnType<typeof McpProxiesSchema.safeParse>;
122
+ export {};
123
+ //# sourceMappingURL=mcp-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-proxy.d.ts","sourceRoot":"","sources":["../src/mcp-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,QAAA,MAAM,qBAAqB;;;;;;kBAuBzB,CAAC;AAEH;;;;;;;GAOG;AACH,QAAA,MAAM,oBAAoB;;;;;;;;;;;kBAmBxB,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;mBAG5B,CAAC;AAEF,sDAAsD;AACtD,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1E,4DAA4D;AAC5D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,kEAAkE;AAClE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAE9D;AAED,wDAAwD;AACxD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAE/C"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * `mcpProxies` — Guuey hosted overlay shape for managed MCP relays.
3
+ *
4
+ * Relocated 2026-04-21 from `@ggui-ai/protocol/types/mcp-proxy.ts` as
5
+ * part of the OSS split §8.2 classification fix. These types describe
6
+ * a GUUEY HOSTING CONCEPT (a managed proxy that relays MCP calls with
7
+ * upstream OAuth linking), not a vendor-neutral protocol shape, and
8
+ * therefore belong in the closed `@guuey/config`
9
+ * package alongside the rest of `guuey.json`.
10
+ *
11
+ * ## The classification decision
12
+ *
13
+ * `mcpProxies` is the declaration block a developer adds to
14
+ * `guuey.json` to tell Guuey hosting: *"on behalf of this project,
15
+ * relay these external MCP providers, using this OAuth linking
16
+ * config, exposing these discovered servers."* That is
17
+ * platform-layer plumbing — Guuey runs the relay, handles the
18
+ * credential storage, dispatches the discovery — and it does not
19
+ * describe anything an OSS-only `ggui` deployment emits or consumes.
20
+ *
21
+ * Per §8.2: the OSS `ggui` server does NOT read `guuey.json`.
22
+ * Consumers that need overlay values (the closed `guuey` CLI,
23
+ * Guuey-hosted Lambdas, the Guuey-internal control-plane UI) are
24
+ * the only call sites allowed to import from this package. Open
25
+ * packages that historically read `mcpProxies` (`@ggui-ai/server`'s
26
+ * Claude-passthrough feature) retain their feature code but inline
27
+ * the minimal structural shape they actually use — it stays a
28
+ * Guuey-platform plumbing path, not a protocol contract.
29
+ *
30
+ * ## Scope of this module
31
+ *
32
+ * - {@link McpProxyLinkingConfig} — upstream OAuth config for
33
+ * proxies that relay calls on behalf of an external account
34
+ * (e.g. Claude.ai). Keys surface in the Guuey control plane's
35
+ * credential-linking UI.
36
+ * - {@link McpProxyConfig} — a single proxy's discovery + proxy
37
+ * URL pattern + optional server filter + optional linking block.
38
+ * - {@link McpProxiesConfig} — the top-level record keyed by
39
+ * proxy id (`claude_ai`, `guuey`, future `omo`...). Exactly the
40
+ * shape `guuey.json#mcpProxies` carries.
41
+ *
42
+ * ## Vendor-neutral constants stay in `@ggui-ai/protocol`
43
+ *
44
+ * Claude.ai-specific constants and discovery-response wire types
45
+ * (`CLAUDE_AI_*`, `DiscoveredMcpServer`, `ClaudeAiDiscoveryResponse`)
46
+ * remain in `@ggui-ai/protocol/types/mcp-proxy.ts` — those describe
47
+ * Anthropic's public API, not Guuey-overlay config.
48
+ *
49
+ * ## Strictness
50
+ *
51
+ * Zod validation matches the rest of `guuey.json`: strict objects,
52
+ * non-empty strings, URL validation on linking endpoints. Unknown
53
+ * keys on nested objects fail parse (prevents silent drift toward
54
+ * a "what else can we stuff into guuey.json" shape).
55
+ */
56
+ import { z } from 'zod';
57
+ /**
58
+ * OAuth linking config for proxies that relay on behalf of an
59
+ * external account. Omit for proxies where Guuey session auth is
60
+ * the only identity needed (e.g. a Guuey-native proxy).
61
+ */
62
+ const McpProxyLinkingSchema = z.strictObject({
63
+ /** OAuth authorize endpoint. */
64
+ authUrl: z.url(),
65
+ /** OAuth token endpoint. */
66
+ tokenUrl: z.url(),
67
+ /**
68
+ * OAuth scopes to request. Empty array means "use the upstream's
69
+ * default scope set"; it does NOT mean "no scopes at all."
70
+ */
71
+ scopes: z.array(z.string().min(1)),
72
+ /**
73
+ * OAuth client_id to use. When omitted, the proxy uses a
74
+ * well-known public client_id (e.g. Claude Code's registered
75
+ * client for Claude.ai).
76
+ */
77
+ clientId: z.string().min(1).optional(),
78
+ /**
79
+ * Manual redirect URL for environments without a localhost
80
+ * callback. The upstream AS redirects here and renders the
81
+ * authorization code for the user to copy-paste. Used by
82
+ * production web flows.
83
+ */
84
+ manualRedirectUrl: z.url().optional(),
85
+ });
86
+ /**
87
+ * Configuration for a single MCP proxy in `guuey.json#mcpProxies`.
88
+ *
89
+ * `discovery` + `proxy` are both URL-valued, but `proxy` is a URL
90
+ * PATTERN (contains `{server_id}` which is substituted at call
91
+ * time). Both are validated as URLs — `{server_id}` is accepted
92
+ * by URL parsers as opaque path segment.
93
+ */
94
+ const McpProxyConfigSchema = z.strictObject({
95
+ /** Discovery URL — fetches available MCP servers for this proxy. */
96
+ discovery: z.url(),
97
+ /**
98
+ * Proxy URL pattern — `{server_id}` is substituted with the
99
+ * discovered server id at relay time. Validated as URL; the
100
+ * placeholder survives URL parsing as an opaque path segment.
101
+ */
102
+ proxy: z.url(),
103
+ /**
104
+ * OAuth linking config for upstream account linking. Omit for
105
+ * Guuey-native proxies where the session token is sufficient.
106
+ */
107
+ linking: McpProxyLinkingSchema.optional(),
108
+ /**
109
+ * Filter which discovered servers to expose, matched by display
110
+ * name. When omitted, all discovered servers are exposed.
111
+ */
112
+ servers: z.array(z.string().min(1)).optional(),
113
+ });
114
+ /**
115
+ * The `mcpProxies` section of `guuey.json`. Keys are proxy
116
+ * identifiers (`claude_ai`, `guuey`, future `omo`, …).
117
+ *
118
+ * Record shape intentionally — new proxy ids are additive; a fixed
119
+ * literal union here would force a schema change every time a new
120
+ * hosted-relay integration lands.
121
+ */
122
+ export const McpProxiesSchema = z.record(z.string().min(1), McpProxyConfigSchema);
123
+ /**
124
+ * Parse a raw JSON value into a validated {@link McpProxiesConfig}.
125
+ * Throws a `ZodError` on invalid input.
126
+ */
127
+ export function parseMcpProxies(raw) {
128
+ return McpProxiesSchema.parse(raw);
129
+ }
130
+ /** Safe-parse variant — see {@link parseMcpProxies}. */
131
+ export function safeParseMcpProxies(raw) {
132
+ return McpProxiesSchema.safeParse(raw);
133
+ }