/** * `guuey.json` v1 — the merged platform config. * * Single source of truth for a guuey-deployed project. Composed of: * * - `agent` (required for agent deploys) — declarative runtime + deploy config * - `app` (optional) — App Store / Portal listing metadata * - `ggui` (optional) — cross-protocol integration if the agent uses ggui rendering * * Plus top-level platform identity (`appId`, `workspaceId`) populated by * the CLI after `guuey create` / `guuey pull --app-id`. * * **Filename convention** (filename = artifact kind, see design doc §3): * ``` * guuey.json ← agent deploy (this file's schema) * guuey.mcp.json ← MCP server deploy (separate schema — see guuey-mcp.ts when added) * ``` * * **History.** Pre-2026-05-25 the repo carried two separate files: * - `agent.json` — runtime contract (slice 2.0) * - `guuey.json` — hosted overlay (project, deploy, deployments, mcpProxies, mcpServers) * * Slice 7.2 (2026-05-25) merged them per platform-architecture design doc §3.1 * + §14.2 field-by-field migration table. Pre-launch no-backcompat rule — * the old shape is GONE, not deprecated. * * **Minimum valid `guuey.json`** (every other field defaults): * * ```jsonc * { * "schema": "1", * "agent": { * "framework": "claude-agent-sdk", * "model": "claude-sonnet-4-6", * "systemPrompt": { "file": "prompts/system.md" } * } * } * ``` */ import { z } from 'zod'; import { type GuueyAgent } from './agent.js'; import { type GuueyApp } from './app.js'; import { type GuueyGguiSection } from './ggui.js'; /** * The ONE `guuey.json` `schema` value this package understands — the * schema-version stance (guuey#248 b2): * * - The root `schema` is a decimal integer string (`"1"`, `"2"`, …), bumped * only on a change that an older reader cannot interpret correctly. * - A document declaring a NEWER schema than this constant is refused * everywhere: the CLI (`SCHEMA_TOO_NEW` — upgrade `@guuey/cli`) and the * reconcile / deploy-trigger APIs (`400 SCHEMA_UNSUPPORTED`). Never * "best-effort parse what we recognize" — the unknown half is precisely * the half that matters. * - A document declaring an OLDER schema is accepted only when a migration * to this version exists. Today there is exactly one version and no * migrations, so the rule collapses to equal-or-refuse; when `"2"` ships, * the `1 → 2` migration lands in this package and BOTH sides (CLI + API) * pick it up through {@link classifyGuueyJsonSchema}. * * The CLI and the platform API compare against the SAME constant (both * consume this package), so "the CLI accepted it but the API refused it" * can only ever mean a version skew between the two — which is exactly the * message the API's refusal names. */ export declare const SUPPORTED_GUUEY_JSON_SCHEMA = "1"; /** * Where a raw `guuey.json` document's `schema` sits relative to * {@link SUPPORTED_GUUEY_JSON_SCHEMA}: * * - `supported` — equal (or an older version a migration exists for; none * today). * - `newer` — a later version than this reader knows: refuse + upgrade. * - `older` — an earlier version with NO migration: refuse. * - `invalid` — absent, not a string, or not a decimal integer string; the * full schema parse reports the precise issue, this verdict only says the * version-gate cannot even compare. */ export type GuueyJsonSchemaVerdict = { kind: 'supported'; found: string; } | { kind: 'newer'; found: string; } | { kind: 'older'; found: string; } | { kind: 'invalid'; found: string | undefined; }; /** * Classify a raw (JSON-decoded, NOT yet schema-parsed) document's root * `schema` against {@link SUPPORTED_GUUEY_JSON_SCHEMA}. Pure; never throws. * Run it BEFORE `parseGuueyJson` so a too-new document gets the "upgrade * your CLI" face instead of zod's `expected "1"` at the first field. */ export declare function classifyGuueyJsonSchema(raw: unknown): GuueyJsonSchemaVerdict; /** * Thrown by {@link assertSupportedGuueyJsonSchema} — carries the code the * CLI prints and the API maps to its 400 (`SCHEMA_TOO_NEW` = upgrade the * reader; `SCHEMA_UNSUPPORTED` = an older version no migration exists for). * The message already names the found + supported versions and the remedy. */ export declare class GuueyJsonSchemaError extends Error { readonly code: 'SCHEMA_TOO_NEW' | 'SCHEMA_UNSUPPORTED'; readonly found: string; constructor(code: 'SCHEMA_TOO_NEW' | 'SCHEMA_UNSUPPORTED', found: string, message: string); } /** * Refuse a document whose `schema` this reader cannot honor. `invalid` * verdicts pass through untouched — the schema parse that follows reports * the precise issue (`at "schema": expected "1"`), which is the right face * for a typo; this gate exists for the version SKEW cases only. * * Runs inside `readGuueyJsonFile` / `loadGuueyJson` (every CLI read of a * checked-in file — `deploy`, `dev`, `agent apply`, …) and in the platform's * reconcile + deploy-trigger handlers, so both ends of the wire refuse the * same documents for the same reason. The message names the remedy for the * only reader outside the platform: the CLI. */ export declare function assertSupportedGuueyJsonSchema(raw: unknown): void; /** * Top-level guuey.json v1 schema. * * `agent` is required — there's no "empty" guuey.json. A repo that hosts * only an MCP server uses `guuey.mcp.json` instead (separate schema). * * `appId` and `workspaceId` are platform-resolved identifiers stamped by * the CLI after `guuey create` / `guuey pull --app-id`. A fresh project has * neither. After first `guuey create`, both may be present. * * Re-exports the sub-section types for consumer convenience. */ export declare const GuueyJsonV1: z.ZodObject<{ schema: z.ZodLiteral<"1">; appId: z.ZodOptional; workspaceId: z.ZodOptional; agent: z.ZodObject<{ mode: z.ZodOptional>; framework: z.ZodOptional>; entry: z.ZodOptional; model: z.ZodOptional; modelProvider: z.ZodOptional>; systemPrompt: z.ZodOptional]>>; mcpServers: z.ZodOptional; source: z.ZodString; devPort: z.ZodOptional; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"hosted">; server: z.ZodOptional; source: z.ZodOptional; devPort: z.ZodOptional; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"external">; url: z.ZodString; transport: z.ZodOptional>; federate: z.ZodOptional; credential: z.ZodOptional>; authMode: z.ZodOptional>; headers: z.ZodOptional>; devPort: z.ZodOptional; mcpResourceUrl: z.ZodOptional; profileAccess: z.ZodOptional>; }, z.core.$strict>], "kind">, z.ZodLiteral]>>>; tools: z.ZodOptional>; denylist: z.ZodOptional>; }, z.core.$strict>>; modes: z.ZodOptional]>>; systemPrompt: z.ZodOptional]>>; tools: z.ZodOptional>; denylist: z.ZodOptional>; }, z.core.$strict>>; audience: z.ZodOptional>>; }, z.core.$strict>>>; defaultMode: z.ZodOptional; hooks: z.ZodOptional, z.ZodObject<{ kind: z.ZodLiteral<"tool">; server: z.ZodString; tool: z.ZodString; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"agent">; definition: z.ZodString; }, z.core.$strict>]>>>; 'handoff.requested': z.ZodOptional, z.ZodObject<{ kind: z.ZodLiteral<"tool">; server: z.ZodString; tool: z.ZodString; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"agent">; definition: z.ZodString; }, z.core.$strict>]>>>; 'session.idled': z.ZodOptional, z.ZodObject<{ kind: z.ZodLiteral<"tool">; server: z.ZodString; tool: z.ZodString; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"agent">; definition: z.ZodString; }, z.core.$strict>]>>>; 'turn.completed': z.ZodOptional, z.ZodObject<{ kind: z.ZodLiteral<"tool">; server: z.ZodString; tool: z.ZodString; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"agent">; definition: z.ZodString; }, z.core.$strict>]>>>; 'session.started': z.ZodOptional, z.ZodObject<{ kind: z.ZodLiteral<"tool">; server: z.ZodString; tool: z.ZodString; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"agent">; definition: z.ZodString; }, z.core.$strict>]>>>; 'turn.start': z.ZodOptional, z.ZodObject<{ kind: z.ZodLiteral<"tool">; server: z.ZodString; tool: z.ZodString; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"agent">; definition: z.ZodString; }, z.core.$strict>]>>>; 'schedule.tick': z.ZodOptional, z.ZodObject<{ kind: z.ZodLiteral<"tool">; server: z.ZodString; tool: z.ZodString; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"agent">; definition: z.ZodString; }, z.core.$strict>]>>>; definitions: z.ZodOptional; on: z.ZodArray>; instruction: z.ZodString; tools: z.ZodOptional>; required: z.ZodOptional>; model: z.ZodOptional>; maxTurns: z.ZodOptional; timeoutMs: z.ZodOptional; actAs: z.ZodOptional>; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"tool">; on: z.ZodArray>; tool: z.ZodString; }, z.core.$strict>]>>>; schedules: z.ZodOptional; handlers: z.ZodArray, z.ZodObject<{ kind: z.ZodLiteral<"tool">; server: z.ZodString; tool: z.ZodString; }, z.core.$strict>, z.ZodObject<{ kind: z.ZodLiteral<"agent">; definition: z.ZodString; }, z.core.$strict>]>>; }, z.core.$strict>>>; }, z.core.$strict>>; surfaceHints: z.ZodOptional; runtime: z.ZodOptional; temperature: z.ZodOptional; }, z.core.$strict>>; claude: z.ZodOptional>; }, z.core.$strict>>; }, z.core.$strict>>; auth: z.ZodOptional>; memory: z.ZodOptional>; storage: z.ZodOptional>>; profileAccess: z.ZodOptional>; env: z.ZodOptional>; secrets: z.ZodOptional>; endpoint: z.ZodOptional>; streaming: z.ZodOptional; }, z.core.$strict>>; deploy: z.ZodOptional>; region: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>; app: z.ZodOptional; name: z.ZodOptional; description: z.ZodOptional; iconUrl: z.ZodOptional; tags: z.ZodOptional>; customDomain: z.ZodOptional; access: z.ZodOptional>; userAuthConfig: z.ZodOptional>>; allowedDomains: z.ZodOptional>; guestAccess: z.ZodOptional>; }, z.core.$strict>>; theme: z.ZodOptional, z.ZodObject<{ name: z.ZodOptional; mode: z.ZodEnum<{ light: "light"; dark: "dark"; }>; colors: z.ZodObject<{ light: z.ZodObject<{ accent: z.ZodString; onAccent: z.ZodString; ink: z.ZodString; inkMuted: z.ZodString; surface: z.ZodString; canvas: z.ZodString; canvasMuted: z.ZodString; error: z.ZodString; link: z.ZodOptional; secondaryAccent: z.ZodOptional; onSecondaryAccent: z.ZodOptional; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; }, z.core.$strict>; dark: z.ZodObject<{ accent: z.ZodString; onAccent: z.ZodString; ink: z.ZodString; inkMuted: z.ZodString; surface: z.ZodString; canvas: z.ZodString; canvasMuted: z.ZodString; error: z.ZodString; link: z.ZodOptional; secondaryAccent: z.ZodOptional; onSecondaryAccent: z.ZodOptional; success: z.ZodOptional; warning: z.ZodOptional; info: z.ZodOptional; }, z.core.$strict>; }, z.core.$strict>; typography: z.ZodOptional; monoFontFamily: z.ZodOptional; headingFontFamily: z.ZodOptional; scale: z.ZodOptional; faces: z.ZodOptional; style: z.ZodOptional; display: z.ZodOptional; }, z.core.$strict>>>; }, z.core.$strict>>; shape: z.ZodOptional; density: z.ZodEnum<{ compact: "compact"; comfortable: "comfortable"; }>; shadow: z.ZodOptional; intensity: z.ZodOptional; }, z.core.$strict>>; glass: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; typeScale: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; h1: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; h2: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; body: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; label: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; rhythm: z.ZodOptional; inset: z.ZodOptional; }, z.core.$strict>>; motion: z.ZodOptional; base: z.ZodOptional; slow: z.ZodOptional; }, z.core.$strict>>; easing: z.ZodOptional; emphasized: z.ZodOptional; exit: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; scrim: z.ZodOptional; opacity: z.ZodNumber; blur: z.ZodNumber; }, z.core.$strict>>; courts: z.ZodOptional; mode: z.ZodOptional>; colors: z.ZodOptional; onAccent: z.ZodOptional; ink: z.ZodOptional; inkMuted: z.ZodOptional; surface: z.ZodOptional; canvas: z.ZodOptional; canvasMuted: z.ZodOptional; error: z.ZodOptional; link: z.ZodOptional>; secondaryAccent: z.ZodOptional>; onSecondaryAccent: z.ZodOptional>; success: z.ZodOptional>; warning: z.ZodOptional>; info: z.ZodOptional>; }, z.core.$strict>>; dark: z.ZodOptional; onAccent: z.ZodOptional; ink: z.ZodOptional; inkMuted: z.ZodOptional; surface: z.ZodOptional; canvas: z.ZodOptional; canvasMuted: z.ZodOptional; error: z.ZodOptional; link: z.ZodOptional>; secondaryAccent: z.ZodOptional>; onSecondaryAccent: z.ZodOptional>; success: z.ZodOptional>; warning: z.ZodOptional>; info: z.ZodOptional>; }, z.core.$strict>>; }, z.core.$strict>>; typography: z.ZodOptional; monoFontFamily: z.ZodOptional; headingFontFamily: z.ZodOptional; scale: z.ZodOptional; faces: z.ZodOptional; style: z.ZodOptional; display: z.ZodOptional; }, z.core.$strict>>>; }, z.core.$strict>>; shape: z.ZodOptional>; density: z.ZodOptional>; shadow: z.ZodOptional; intensity: z.ZodOptional; }, z.core.$strict>>; glass: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; typeScale: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; h1: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; h2: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; body: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; label: z.ZodOptional; weight: z.ZodOptional; tracking: z.ZodOptional; leading: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; rhythm: z.ZodOptional; inset: z.ZodOptional; }, z.core.$strict>>; motion: z.ZodOptional; base: z.ZodOptional; slow: z.ZodOptional; }, z.core.$strict>>; easing: z.ZodOptional; emphasized: z.ZodOptional; exit: z.ZodOptional; }, z.core.$strict>>; }, z.core.$strict>>; scrim: z.ZodOptional; opacity: z.ZodNumber; blur: z.ZodNumber; }, z.core.$strict>>; }, z.core.$strict>>>; }, z.core.$strict>]>>; page: z.ZodOptional>; welcomeCopy: z.ZodOptional>; ctaLabel: z.ZodOptional>; ctaUrl: z.ZodOptional>; identityEndpointUrl: z.ZodOptional>; noindex: z.ZodOptional>; }, z.core.$strict>>; suggestions: z.ZodOptional>; }, z.core.$strict>>; ggui: z.ZodOptional; configFile: z.ZodOptional; inline: z.ZodOptional>; }, z.core.$strict>>; worker: z.ZodOptional; protocol: z.ZodDefault>; runtime: z.ZodOptional>; }, z.core.$strict>>; }, z.core.$strict>; /** Static TypeScript type for `guuey.json` v1. */ export type GuueyJsonV1 = z.infer; /** * Author-side shape for `guuey.json` v1 — what a writer may construct before * `parseGuueyJson` applies schema defaults (e.g. `protocol` → `'silver'`). * Fields with defaults are optional here and required on {@link GuueyJsonV1}. */ export type GuueyJsonV1Input = z.input; export type { GuueyAgent, GuueyApp, GuueyGguiSection }; /** * Canonical filename — always at the project root, always this name. * Exported so tooling uses the same constant instead of hard-coding. */ export declare const GUUEY_JSON_FILENAME = "guuey.json"; /** * Parse a raw JSON value into a validated {@link GuueyJsonV1}. * Throws a `ZodError` with human-readable issues on invalid input. * * Callers must have already JSON-decoded the source. Does NOT resolve * `agent.systemPrompt.file` references — that's the loader's job (see * `./loader.ts#loadGuueyJson`). Pure parse is safe to run anywhere; * file resolution requires a base directory and is Node-only. */ export declare function parseGuueyJson(raw: unknown): GuueyJsonV1; /** * Safe-parse variant — returns a discriminated `z.safeParse` result. * Prefer this inside CLI tooling where you want to render the issue * list without try/catch. */ export declare function safeParseGuueyJson(raw: unknown): ReturnType; //# sourceMappingURL=schema.d.ts.map