@ggui-ai/artifact-manifest 0.1.0-rc.1
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/LICENSE +201 -0
- package/README.md +50 -0
- package/dist/artifact-manifest.d.ts +118 -0
- package/dist/artifact-manifest.d.ts.map +1 -0
- package/dist/artifact-manifest.js +69 -0
- package/dist/base.d.ts +98 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +128 -0
- package/dist/blueprint-manifest.d.ts +126 -0
- package/dist/blueprint-manifest.d.ts.map +1 -0
- package/dist/blueprint-manifest.js +159 -0
- package/dist/gadget-manifest.d.ts +180 -0
- package/dist/gadget-manifest.d.ts.map +1 -0
- package/dist/gadget-manifest.js +270 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/manifest-to-registry-entry.d.ts +43 -0
- package/dist/manifest-to-registry-entry.d.ts.map +1 -0
- package/dist/manifest-to-registry-entry.js +39 -0
- package/package.json +59 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ggui.blueprint.json` — author-side manifest for cached UI
|
|
3
|
+
* blueprints published to the ggui marketplace.
|
|
4
|
+
*
|
|
5
|
+
* Blueprints are the OTHER artifact kind the registry hosts (beside
|
|
6
|
+
* gadgets). A blueprint bundles:
|
|
7
|
+
*
|
|
8
|
+
* - **TSX source** — the React component body the runtime renders.
|
|
9
|
+
* - **DataContract** (optional) — the contract shape this blueprint
|
|
10
|
+
* was designed for. Consumed by the cache-match path.
|
|
11
|
+
* - **fixtureProps** (optional) — sample props used by the
|
|
12
|
+
* conformance gate's runtime probe.
|
|
13
|
+
* - **variance tags** (optional) — persona / aesthetic / context
|
|
14
|
+
* hints that drive the LLM-driven variant selector when multiple
|
|
15
|
+
* blueprints share a `(appId, contractHash)` group.
|
|
16
|
+
*
|
|
17
|
+
* ## In-process counterpart
|
|
18
|
+
*
|
|
19
|
+
* The in-process registration tool at
|
|
20
|
+
* `cloud/ggui-protocol-pod/src/tools/register-blueprint.ts` accepts
|
|
21
|
+
* `{source, contract?, fixtureProps?}` and a slug
|
|
22
|
+
* `^[a-z0-9][a-z0-9_-]{0,63}$`. This manifest's `source` /
|
|
23
|
+
* `contract` / `fixtureProps` fields mirror that envelope exactly
|
|
24
|
+
* — round-tripping a blueprint through
|
|
25
|
+
* `ggui_ops_register_blueprint` then exporting it back into a
|
|
26
|
+
* `ggui.blueprint.json` must not require any field rewriting beyond
|
|
27
|
+
* adding the marketplace identity (`scope`, `name`, `version`,
|
|
28
|
+
* `kind`, `visibility`) and optional variance tags.
|
|
29
|
+
*
|
|
30
|
+
* The `name` regex matches the in-process slug rule
|
|
31
|
+
* ({@link BLUEPRINT_NAME_RE}) — diverging would break round-trip.
|
|
32
|
+
*
|
|
33
|
+
* ## Why no `matchers` field
|
|
34
|
+
*
|
|
35
|
+
* The existing `screen-blueprints/match.ts` matcher operates on the
|
|
36
|
+
* runtime-side `MatchableBlueprint` row (carries `blueprintId`,
|
|
37
|
+
* `serverId`, `dataTools`, `status`) — these are runtime registry
|
|
38
|
+
* artifacts, not authoring-time manifest declarations. The selector
|
|
39
|
+
* for cached-blueprint variants reads {@link BlueprintVariance}
|
|
40
|
+
* (persona + aesthetic + context + seedPrompt), which IS authoring-
|
|
41
|
+
* time information and lives on this manifest under `variance`.
|
|
42
|
+
*
|
|
43
|
+
* If a future authoring-time matchers shape lands in
|
|
44
|
+
* `@ggui-ai/protocol`, add it here under `matchers?:
|
|
45
|
+
* BlueprintMatchers` and reuse the protocol type. Don't redefine it.
|
|
46
|
+
*
|
|
47
|
+
* ## Discriminator
|
|
48
|
+
*
|
|
49
|
+
* The top-level `kind: "blueprint"` literal is the discriminator
|
|
50
|
+
* {@link artifactManifestSchema} uses to narrow between gadget and
|
|
51
|
+
* blueprint manifests. Authors MUST set it.
|
|
52
|
+
*
|
|
53
|
+
* ## Strictness
|
|
54
|
+
*
|
|
55
|
+
* Root + nested objects are strict — unknown keys fail parse. Same
|
|
56
|
+
* loud-feedback posture as the gadget manifest.
|
|
57
|
+
*/
|
|
58
|
+
import { z } from 'zod';
|
|
59
|
+
import { type BlueprintVariance, type DataContract } from '@ggui-ai/protocol';
|
|
60
|
+
/**
|
|
61
|
+
* Strict zod schema for `ggui.blueprint.json`. Strict root — unknown
|
|
62
|
+
* keys fail parse. Discriminated on `kind: "blueprint"`.
|
|
63
|
+
*
|
|
64
|
+
* Note: `contract` is intentionally NOT made strict here — it
|
|
65
|
+
* delegates to {@link dataContractSchema} from `@ggui-ai/protocol`,
|
|
66
|
+
* which owns its own strictness posture (and `JsonSchema` body fields
|
|
67
|
+
* are deliberately open).
|
|
68
|
+
*/
|
|
69
|
+
export declare const blueprintManifestSchema: z.ZodObject<{
|
|
70
|
+
description: z.ZodOptional<z.ZodString>;
|
|
71
|
+
tags: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
72
|
+
author: z.ZodOptional<z.ZodObject<{
|
|
73
|
+
name: z.ZodString;
|
|
74
|
+
email: z.ZodOptional<z.ZodEmail>;
|
|
75
|
+
url: z.ZodOptional<z.ZodURL>;
|
|
76
|
+
}, z.core.$strict>>;
|
|
77
|
+
license: z.ZodOptional<z.ZodString>;
|
|
78
|
+
homepage: z.ZodOptional<z.ZodURL>;
|
|
79
|
+
kind: z.ZodLiteral<"blueprint">;
|
|
80
|
+
scope: z.ZodString;
|
|
81
|
+
name: z.ZodString;
|
|
82
|
+
version: z.ZodString;
|
|
83
|
+
source: z.ZodString;
|
|
84
|
+
visibility: z.ZodEnum<{
|
|
85
|
+
public: "public";
|
|
86
|
+
private: "private";
|
|
87
|
+
}>;
|
|
88
|
+
contract: z.ZodOptional<z.ZodType<DataContract, unknown, z.core.$ZodTypeInternals<DataContract, unknown>>>;
|
|
89
|
+
fixtureProps: z.ZodOptional<z.ZodUnknown>;
|
|
90
|
+
variance: z.ZodOptional<z.ZodType<BlueprintVariance, unknown, z.core.$ZodTypeInternals<BlueprintVariance, unknown>>>;
|
|
91
|
+
}, z.core.$strict>;
|
|
92
|
+
/**
|
|
93
|
+
* Static TypeScript type derived from {@link blueprintManifestSchema}.
|
|
94
|
+
*
|
|
95
|
+
* Authors writing `ggui.blueprint.json` should
|
|
96
|
+
* `import type { BlueprintManifest } from '@ggui-ai/artifact-manifest'`
|
|
97
|
+
* and let inference flow. The `contract` field is typed `DataContract
|
|
98
|
+
* | undefined` (reuses the protocol type); `variance` is typed
|
|
99
|
+
* `BlueprintVariance | undefined` (also reused).
|
|
100
|
+
*/
|
|
101
|
+
export type BlueprintManifest = z.infer<typeof blueprintManifestSchema>;
|
|
102
|
+
/**
|
|
103
|
+
* Canonical filename — always at the blueprint repo root, always
|
|
104
|
+
* this name. Exported so tooling uses the constant instead of
|
|
105
|
+
* hard-coding the string.
|
|
106
|
+
*/
|
|
107
|
+
export declare const GGUI_BLUEPRINT_JSON_FILENAME = "ggui.blueprint.json";
|
|
108
|
+
/**
|
|
109
|
+
* Parse a raw JSON value into a validated {@link BlueprintManifest}.
|
|
110
|
+
* Throws a `ZodError` with human-readable issues on invalid input.
|
|
111
|
+
*
|
|
112
|
+
* Accepts any `unknown` — callers are expected to have already
|
|
113
|
+
* decoded the JSON (`JSON.parse(source)`).
|
|
114
|
+
*/
|
|
115
|
+
export declare function parseBlueprintManifest(raw: unknown): BlueprintManifest;
|
|
116
|
+
/**
|
|
117
|
+
* Assertion helper — narrows `raw` to {@link BlueprintManifest} on
|
|
118
|
+
* success, throws `ZodError` on failure.
|
|
119
|
+
*/
|
|
120
|
+
export declare function assertBlueprintManifestValid(raw: unknown): asserts raw is BlueprintManifest;
|
|
121
|
+
/**
|
|
122
|
+
* Safe-parse variant — returns a discriminated `z.safeParse` result
|
|
123
|
+
* (`{ success: true, data }` vs `{ success: false, error }`).
|
|
124
|
+
*/
|
|
125
|
+
export declare function safeParseBlueprintManifest(raw: unknown): ReturnType<typeof blueprintManifestSchema.safeParse>;
|
|
126
|
+
//# sourceMappingURL=blueprint-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blueprint-manifest.d.ts","sourceRoot":"","sources":["../src/blueprint-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAGlB,MAAM,mBAAmB,CAAC;AAgC3B;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;kBAiDlC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAmBxE;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,wBAAwB,CAAC;AAElE;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAEtE;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,GAAG,IAAI,iBAAiB,CAElC;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAEtD"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ggui.blueprint.json` — author-side manifest for cached UI
|
|
3
|
+
* blueprints published to the ggui marketplace.
|
|
4
|
+
*
|
|
5
|
+
* Blueprints are the OTHER artifact kind the registry hosts (beside
|
|
6
|
+
* gadgets). A blueprint bundles:
|
|
7
|
+
*
|
|
8
|
+
* - **TSX source** — the React component body the runtime renders.
|
|
9
|
+
* - **DataContract** (optional) — the contract shape this blueprint
|
|
10
|
+
* was designed for. Consumed by the cache-match path.
|
|
11
|
+
* - **fixtureProps** (optional) — sample props used by the
|
|
12
|
+
* conformance gate's runtime probe.
|
|
13
|
+
* - **variance tags** (optional) — persona / aesthetic / context
|
|
14
|
+
* hints that drive the LLM-driven variant selector when multiple
|
|
15
|
+
* blueprints share a `(appId, contractHash)` group.
|
|
16
|
+
*
|
|
17
|
+
* ## In-process counterpart
|
|
18
|
+
*
|
|
19
|
+
* The in-process registration tool at
|
|
20
|
+
* `cloud/ggui-protocol-pod/src/tools/register-blueprint.ts` accepts
|
|
21
|
+
* `{source, contract?, fixtureProps?}` and a slug
|
|
22
|
+
* `^[a-z0-9][a-z0-9_-]{0,63}$`. This manifest's `source` /
|
|
23
|
+
* `contract` / `fixtureProps` fields mirror that envelope exactly
|
|
24
|
+
* — round-tripping a blueprint through
|
|
25
|
+
* `ggui_ops_register_blueprint` then exporting it back into a
|
|
26
|
+
* `ggui.blueprint.json` must not require any field rewriting beyond
|
|
27
|
+
* adding the marketplace identity (`scope`, `name`, `version`,
|
|
28
|
+
* `kind`, `visibility`) and optional variance tags.
|
|
29
|
+
*
|
|
30
|
+
* The `name` regex matches the in-process slug rule
|
|
31
|
+
* ({@link BLUEPRINT_NAME_RE}) — diverging would break round-trip.
|
|
32
|
+
*
|
|
33
|
+
* ## Why no `matchers` field
|
|
34
|
+
*
|
|
35
|
+
* The existing `screen-blueprints/match.ts` matcher operates on the
|
|
36
|
+
* runtime-side `MatchableBlueprint` row (carries `blueprintId`,
|
|
37
|
+
* `serverId`, `dataTools`, `status`) — these are runtime registry
|
|
38
|
+
* artifacts, not authoring-time manifest declarations. The selector
|
|
39
|
+
* for cached-blueprint variants reads {@link BlueprintVariance}
|
|
40
|
+
* (persona + aesthetic + context + seedPrompt), which IS authoring-
|
|
41
|
+
* time information and lives on this manifest under `variance`.
|
|
42
|
+
*
|
|
43
|
+
* If a future authoring-time matchers shape lands in
|
|
44
|
+
* `@ggui-ai/protocol`, add it here under `matchers?:
|
|
45
|
+
* BlueprintMatchers` and reuse the protocol type. Don't redefine it.
|
|
46
|
+
*
|
|
47
|
+
* ## Discriminator
|
|
48
|
+
*
|
|
49
|
+
* The top-level `kind: "blueprint"` literal is the discriminator
|
|
50
|
+
* {@link artifactManifestSchema} uses to narrow between gadget and
|
|
51
|
+
* blueprint manifests. Authors MUST set it.
|
|
52
|
+
*
|
|
53
|
+
* ## Strictness
|
|
54
|
+
*
|
|
55
|
+
* Root + nested objects are strict — unknown keys fail parse. Same
|
|
56
|
+
* loud-feedback posture as the gadget manifest.
|
|
57
|
+
*/
|
|
58
|
+
import { z } from 'zod';
|
|
59
|
+
import { blueprintVarianceSchema, dataContractSchema, } from '@ggui-ai/protocol';
|
|
60
|
+
import { ArtifactScopeSchema, ArtifactVersionSchema, ArtifactVisibilitySchema, BLUEPRINT_NAME_RE, sharedMetadataShape, } from './base.js';
|
|
61
|
+
/**
|
|
62
|
+
* Blueprint name regex — the same kebab-case rule as gadgets. See
|
|
63
|
+
* {@link BLUEPRINT_NAME_RE} for the rationale.
|
|
64
|
+
*/
|
|
65
|
+
const BlueprintNameSchema = z.string().min(2).max(64).regex(BLUEPRINT_NAME_RE, {
|
|
66
|
+
message: 'name must be 2-64 chars matching `^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$` (lowercase alphanumerics + hyphens, no underscores, no single-character names).',
|
|
67
|
+
});
|
|
68
|
+
/**
|
|
69
|
+
* `fixtureProps` is intentionally `unknown` — the conformance gate's
|
|
70
|
+
* runtime probe round-trips it through `JSON.stringify` and feeds it
|
|
71
|
+
* as `props` to the rendered TSX. Any JSON-safe shape rides through;
|
|
72
|
+
* the blueprint's own `contract.propsSchema` (when present) is what
|
|
73
|
+
* actually validates the shape at runtime probe time. Mirrors the
|
|
74
|
+
* in-process register-blueprint's `fixtureProps: z.unknown().optional()`.
|
|
75
|
+
*
|
|
76
|
+
* `z.unknown()` is permitted here (not `Record<string, unknown>`)
|
|
77
|
+
* because the value is genuinely shape-unknown at THIS layer — only
|
|
78
|
+
* the blueprint's own contract knows what shape its props take.
|
|
79
|
+
*/
|
|
80
|
+
const fixturePropsSchema = z.unknown();
|
|
81
|
+
/**
|
|
82
|
+
* Strict zod schema for `ggui.blueprint.json`. Strict root — unknown
|
|
83
|
+
* keys fail parse. Discriminated on `kind: "blueprint"`.
|
|
84
|
+
*
|
|
85
|
+
* Note: `contract` is intentionally NOT made strict here — it
|
|
86
|
+
* delegates to {@link dataContractSchema} from `@ggui-ai/protocol`,
|
|
87
|
+
* which owns its own strictness posture (and `JsonSchema` body fields
|
|
88
|
+
* are deliberately open).
|
|
89
|
+
*/
|
|
90
|
+
export const blueprintManifestSchema = z.strictObject({
|
|
91
|
+
// ---- Discriminator ----
|
|
92
|
+
kind: z
|
|
93
|
+
.literal('blueprint')
|
|
94
|
+
.describe('Discriminator — picks the blueprint variant of the artifact-manifest union. MUST be the literal string `"blueprint"`.'),
|
|
95
|
+
// ---- Identity (required) ----
|
|
96
|
+
scope: ArtifactScopeSchema.describe('Blueprint scope. Must start with `@` (e.g. `@my-org`). Disambiguates the `<scope>/<name>` install identifier.'),
|
|
97
|
+
name: BlueprintNameSchema.describe('Blueprint slug. 2-64 chars, `^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$` — kebab-case, no underscores, no single-character names. Unified with the gadget naming rule under LOCKED-25 (2026-05-18). The in-process `ggui_ops_register_blueprint` slug rule mirrors this for round-trip preservation.'),
|
|
98
|
+
version: ArtifactVersionSchema.describe('SemVer. `MAJOR.MINOR.PATCH` with optional `-pre` / `+build` suffixes. Per-version immutable once published.'),
|
|
99
|
+
// ---- Core blueprint shape (required: source) ----
|
|
100
|
+
source: z
|
|
101
|
+
.string()
|
|
102
|
+
.min(1)
|
|
103
|
+
.describe('TSX source body with a default-exported React component. Mirrors the in-process register-blueprint `blueprint.source` field — the conformance gate compiles + runtime-probes this string before the registry accepts the upload.'),
|
|
104
|
+
visibility: ArtifactVisibilitySchema.describe('Storage + signing posture. `public` = sigstore-signed, listable; `private` = Ed25519-signed, visible only within publisher org.'),
|
|
105
|
+
// ---- Optional core blueprint shape ----
|
|
106
|
+
contract: dataContractSchema
|
|
107
|
+
.optional()
|
|
108
|
+
.describe("The DataContract envelope this blueprint was designed for. Consumed by the cache-match path to short-circuit cold gen when an agent's contract hash matches. Optional — a blueprint can publish without a contract for cases where the matcher relies on variance + tags only."),
|
|
109
|
+
fixtureProps: fixturePropsSchema
|
|
110
|
+
.optional()
|
|
111
|
+
.describe("Sample props for the conformance gate's runtime probe. Any JSON-safe shape; validated for top-level required-key shape against `contract.propsSpec.properties` at static gate time and used as the input props on the sandboxed React render in the runtime probe."),
|
|
112
|
+
variance: blueprintVarianceSchema
|
|
113
|
+
.optional()
|
|
114
|
+
.describe("Persona + aesthetic + context + seedPrompt hints that drive the LLM-driven variant selector when multiple blueprints share a `(appId, contractHash)` group. Mirrors `Blueprint.variance` in `@ggui-ai/protocol`."),
|
|
115
|
+
// ---- Shared metadata ----
|
|
116
|
+
...sharedMetadataShape,
|
|
117
|
+
});
|
|
118
|
+
// Verify the manifest TS type actually projects the reused protocol
|
|
119
|
+
// types — if a future zod-vs-TS drift slips one of these to `any`,
|
|
120
|
+
// the parameter-to-return-type assignments below stop compiling.
|
|
121
|
+
// Module-private static checks; the bodies are never invoked.
|
|
122
|
+
function _blueprintContractTypeCheck(c) {
|
|
123
|
+
return c;
|
|
124
|
+
}
|
|
125
|
+
function _blueprintVarianceTypeCheck(v) {
|
|
126
|
+
return v;
|
|
127
|
+
}
|
|
128
|
+
void _blueprintContractTypeCheck;
|
|
129
|
+
void _blueprintVarianceTypeCheck;
|
|
130
|
+
/**
|
|
131
|
+
* Canonical filename — always at the blueprint repo root, always
|
|
132
|
+
* this name. Exported so tooling uses the constant instead of
|
|
133
|
+
* hard-coding the string.
|
|
134
|
+
*/
|
|
135
|
+
export const GGUI_BLUEPRINT_JSON_FILENAME = 'ggui.blueprint.json';
|
|
136
|
+
/**
|
|
137
|
+
* Parse a raw JSON value into a validated {@link BlueprintManifest}.
|
|
138
|
+
* Throws a `ZodError` with human-readable issues on invalid input.
|
|
139
|
+
*
|
|
140
|
+
* Accepts any `unknown` — callers are expected to have already
|
|
141
|
+
* decoded the JSON (`JSON.parse(source)`).
|
|
142
|
+
*/
|
|
143
|
+
export function parseBlueprintManifest(raw) {
|
|
144
|
+
return blueprintManifestSchema.parse(raw);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Assertion helper — narrows `raw` to {@link BlueprintManifest} on
|
|
148
|
+
* success, throws `ZodError` on failure.
|
|
149
|
+
*/
|
|
150
|
+
export function assertBlueprintManifestValid(raw) {
|
|
151
|
+
blueprintManifestSchema.parse(raw);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Safe-parse variant — returns a discriminated `z.safeParse` result
|
|
155
|
+
* (`{ success: true, data }` vs `{ success: false, error }`).
|
|
156
|
+
*/
|
|
157
|
+
export function safeParseBlueprintManifest(raw) {
|
|
158
|
+
return blueprintManifestSchema.safeParse(raw);
|
|
159
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ggui.gadget.json` — author-side manifest for ggui gadgets
|
|
3
|
+
* published to the marketplace.
|
|
4
|
+
*
|
|
5
|
+
* Lives at the root of a gadget author's repo (one repo = one gadget).
|
|
6
|
+
* `ggui publish` reads this file, builds the bundle, runs the local
|
|
7
|
+
* conformance gate, then uploads bundle + sig + descriptor to the
|
|
8
|
+
* resolved registry. End-users install via `ggui install
|
|
9
|
+
* <scope/name@version>` which appends to their app's
|
|
10
|
+
* `ggui.json#app.gadgets`.
|
|
11
|
+
*
|
|
12
|
+
* ## Relationship to `strictGadgetDescriptorSchema`
|
|
13
|
+
*
|
|
14
|
+
* The registry-side `strictGadgetDescriptorSchema` (in
|
|
15
|
+
* `@ggui-ai/protocol`) describes what a wrapper looks like *after* it
|
|
16
|
+
* has been registered (it carries `package` / `bundleUrl` / etc — the
|
|
17
|
+
* fetchable shape). This author-side manifest describes what a wrapper
|
|
18
|
+
* looks like *before* publish (build-config + identity + signing
|
|
19
|
+
* posture). Field semantics agree where they overlap:
|
|
20
|
+
*
|
|
21
|
+
* | Field | author manifest | registry entry |
|
|
22
|
+
* |---------------|------------------------|--------------------------|
|
|
23
|
+
* | `scope` | required (`@org`) | implicit in entry key |
|
|
24
|
+
* | `name` | required (kebab-case) | implicit in entry key |
|
|
25
|
+
* | `version` | required (semver) | required |
|
|
26
|
+
* | `exports[]` | required (≥1) | required (`exports[]`) |
|
|
27
|
+
* | `description` | required (pkg summary) | REQUIRED at registry |
|
|
28
|
+
* | `requires[]` | `GGUI_PUBLIC_APP_*` | same regex (locked) |
|
|
29
|
+
* | `connect[]` | URL allowlist | same shape (`string[]`) |
|
|
30
|
+
* | `bundle` | source entry path | replaced by `bundleUrl` |
|
|
31
|
+
* | `style` | source entry path | replaced by `styleUrl` |
|
|
32
|
+
* | `visibility` | required (pub/priv) | not on registry entry |
|
|
33
|
+
* | `peerDeps` | conformance allowlist | not on registry entry |
|
|
34
|
+
*
|
|
35
|
+
* The schemas are deliberately separate — manifest carries build
|
|
36
|
+
* config, registry entry carries fetch URLs. The publish flow
|
|
37
|
+
* translates one into the other. Don't import `registryGadget
|
|
38
|
+
* EntrySchema` and extend it; the shapes overlap but are not subset/
|
|
39
|
+
* superset.
|
|
40
|
+
*
|
|
41
|
+
* ## Discriminator
|
|
42
|
+
*
|
|
43
|
+
* The top-level `kind: "gadget"` literal is the discriminator that
|
|
44
|
+
* lets {@link artifactManifestSchema} narrow between gadget and
|
|
45
|
+
* blueprint manifests. Authors MUST set it; the schema rejects
|
|
46
|
+
* absent or misspelled `kind` with a clear path-`["kind"]` issue.
|
|
47
|
+
*
|
|
48
|
+
* ## Strictness
|
|
49
|
+
*
|
|
50
|
+
* Root + nested objects are strict — unknown keys fail parse. This is
|
|
51
|
+
* the gadget author's first feedback surface; typos in
|
|
52
|
+
* `ggui.gadget.json` should fail loud, not silently get ignored at
|
|
53
|
+
* publish time.
|
|
54
|
+
*/
|
|
55
|
+
import { z } from 'zod';
|
|
56
|
+
/**
|
|
57
|
+
* One export of a gadget package — a hook or a component. Mirrors the
|
|
58
|
+
* protocol's `GadgetExport` shape: a gadget package bundles ≥1 of
|
|
59
|
+
* these behind a single npm identity. There is no `kind` field —
|
|
60
|
+
* discrimination is by field presence: a `hook` key (`use`-prefixed
|
|
61
|
+
* name) marks a hook, a `component` key (PascalCase name) marks a
|
|
62
|
+
* component.
|
|
63
|
+
*/
|
|
64
|
+
export declare const gadgetExportSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
65
|
+
description: z.ZodString;
|
|
66
|
+
usage: z.ZodString;
|
|
67
|
+
example: z.ZodType<import("@ggui-ai/protocol").JsonValue, unknown, z.core.$ZodTypeInternals<import("@ggui-ai/protocol").JsonValue, unknown>>;
|
|
68
|
+
gotchas: z.ZodOptional<z.ZodString>;
|
|
69
|
+
hook: z.ZodString;
|
|
70
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
71
|
+
description: z.ZodString;
|
|
72
|
+
usage: z.ZodString;
|
|
73
|
+
example: z.ZodType<import("@ggui-ai/protocol").JsonValue, unknown, z.core.$ZodTypeInternals<import("@ggui-ai/protocol").JsonValue, unknown>>;
|
|
74
|
+
gotchas: z.ZodOptional<z.ZodString>;
|
|
75
|
+
component: z.ZodString;
|
|
76
|
+
}, z.core.$strict>]>;
|
|
77
|
+
/**
|
|
78
|
+
* Strict zod schema for `ggui.gadget.json`. Strict root + nested
|
|
79
|
+
* objects — unknown keys fail parse. Discriminated on `kind:
|
|
80
|
+
* "gadget"`.
|
|
81
|
+
*/
|
|
82
|
+
export declare const gadgetManifestSchema: z.ZodObject<{
|
|
83
|
+
connect: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
84
|
+
tags: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
85
|
+
author: z.ZodOptional<z.ZodObject<{
|
|
86
|
+
name: z.ZodString;
|
|
87
|
+
email: z.ZodOptional<z.ZodEmail>;
|
|
88
|
+
url: z.ZodOptional<z.ZodURL>;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
license: z.ZodOptional<z.ZodString>;
|
|
91
|
+
homepage: z.ZodOptional<z.ZodURL>;
|
|
92
|
+
kind: z.ZodLiteral<"gadget">;
|
|
93
|
+
scope: z.ZodString;
|
|
94
|
+
name: z.ZodString;
|
|
95
|
+
version: z.ZodString;
|
|
96
|
+
exports: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
97
|
+
description: z.ZodString;
|
|
98
|
+
usage: z.ZodString;
|
|
99
|
+
example: z.ZodType<import("@ggui-ai/protocol").JsonValue, unknown, z.core.$ZodTypeInternals<import("@ggui-ai/protocol").JsonValue, unknown>>;
|
|
100
|
+
gotchas: z.ZodOptional<z.ZodString>;
|
|
101
|
+
hook: z.ZodString;
|
|
102
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
103
|
+
description: z.ZodString;
|
|
104
|
+
usage: z.ZodString;
|
|
105
|
+
example: z.ZodType<import("@ggui-ai/protocol").JsonValue, unknown, z.core.$ZodTypeInternals<import("@ggui-ai/protocol").JsonValue, unknown>>;
|
|
106
|
+
gotchas: z.ZodOptional<z.ZodString>;
|
|
107
|
+
component: z.ZodString;
|
|
108
|
+
}, z.core.$strict>]>>;
|
|
109
|
+
bundle: z.ZodString;
|
|
110
|
+
visibility: z.ZodEnum<{
|
|
111
|
+
public: "public";
|
|
112
|
+
private: "private";
|
|
113
|
+
}>;
|
|
114
|
+
description: z.ZodString;
|
|
115
|
+
style: z.ZodOptional<z.ZodString>;
|
|
116
|
+
/**
|
|
117
|
+
* `requires` — App-side public-env keys the wrapper needs to
|
|
118
|
+
* function. Each entry MUST match `GGUI_PUBLIC_APP_*`. The shared
|
|
119
|
+
* `gadgetRequiresSchema` from `@ggui-ai/protocol` is the single
|
|
120
|
+
* source of truth for this constraint.
|
|
121
|
+
*/
|
|
122
|
+
requires: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
123
|
+
peerDeps: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
124
|
+
/**
|
|
125
|
+
* Author-default registry hostname the wrapper publishes to. Forms
|
|
126
|
+
* the third tier of bundleHost resolution at push time:
|
|
127
|
+
*
|
|
128
|
+
* 1. operator's `app.gadgets[*].bundleUrl` (full URL, escape hatch)
|
|
129
|
+
* 2. operator's `app.gadgets[*].bundleHost` (override)
|
|
130
|
+
* 3. THIS field — gadget author's default
|
|
131
|
+
* 4. spec default `registry.ggui.ai`
|
|
132
|
+
*
|
|
133
|
+
* Most wrappers omit this (they publish to the hosted registry, and
|
|
134
|
+
* the spec default covers them). Set this only when the wrapper ships
|
|
135
|
+
* via a non-default registry (private org registry, sandbox-only
|
|
136
|
+
* fixture, …). The operator override remains the right knob for
|
|
137
|
+
* sandbox-vs-prod swaps.
|
|
138
|
+
*
|
|
139
|
+
* Hostname-only — no scheme, no path. Validated via
|
|
140
|
+
* {@link BUNDLE_HOST_RE} in `@ggui-ai/protocol`.
|
|
141
|
+
*/
|
|
142
|
+
bundleHost: z.ZodOptional<z.ZodString>;
|
|
143
|
+
}, z.core.$strict>;
|
|
144
|
+
/**
|
|
145
|
+
* Static TypeScript type derived from {@link gadgetManifestSchema}.
|
|
146
|
+
*
|
|
147
|
+
* Authors writing `ggui.gadget.json` should `import type {
|
|
148
|
+
* GadgetManifest } from '@ggui-ai/artifact-manifest'` and let the
|
|
149
|
+
* inference flow.
|
|
150
|
+
*/
|
|
151
|
+
export type GadgetManifest = z.infer<typeof gadgetManifestSchema>;
|
|
152
|
+
/**
|
|
153
|
+
* Canonical filename — always at the gadget repo root, always this
|
|
154
|
+
* name. Exported so tooling uses the constant instead of hard-coding
|
|
155
|
+
* the string.
|
|
156
|
+
*/
|
|
157
|
+
export declare const GGUI_GADGET_JSON_FILENAME = "ggui.gadget.json";
|
|
158
|
+
/**
|
|
159
|
+
* Parse a raw JSON value into a validated {@link GadgetManifest}.
|
|
160
|
+
* Throws a `ZodError` with human-readable issues on invalid input.
|
|
161
|
+
*
|
|
162
|
+
* Accepts any `unknown` — callers are expected to have already
|
|
163
|
+
* decoded the JSON (`JSON.parse(source)`).
|
|
164
|
+
*/
|
|
165
|
+
export declare function parseGadgetManifest(raw: unknown): GadgetManifest;
|
|
166
|
+
/**
|
|
167
|
+
* Assertion helper — narrows `raw` to {@link GadgetManifest} on
|
|
168
|
+
* success, throws `ZodError` on failure. Useful when the caller wants
|
|
169
|
+
* to keep the original reference (rather than the parsed copy
|
|
170
|
+
* `parseGadgetManifest` returns).
|
|
171
|
+
*/
|
|
172
|
+
export declare function assertGadgetManifestValid(raw: unknown): asserts raw is GadgetManifest;
|
|
173
|
+
/**
|
|
174
|
+
* Safe-parse variant — returns a discriminated `z.safeParse` result
|
|
175
|
+
* (`{ success: true, data }` vs `{ success: false, error }`). Prefer
|
|
176
|
+
* this inside CLI tooling where you want to render the issue list
|
|
177
|
+
* without try/catch.
|
|
178
|
+
*/
|
|
179
|
+
export declare function safeParseGadgetManifest(raw: unknown): ReturnType<typeof gadgetManifestSchema.safeParse>;
|
|
180
|
+
//# sourceMappingURL=gadget-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gadget-manifest.d.ts","sourceRoot":"","sources":["../src/gadget-manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAsFxB;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;oBAwB7B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4D/B;;;;;OAKG;;;IAcH;;;;;;;;;;;;;;;;;OAiBG;;kBAwBH,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,qBAAqB,CAAC;AAE5D;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,GAAG,IAAI,cAAc,CAE/B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,OAAO,GACX,UAAU,CAAC,OAAO,oBAAoB,CAAC,SAAS,CAAC,CAEnD"}
|