@ggui-ai/gadgets 0.2.0-alpha.4 → 0.4.0-rc.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
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## Why
6
6
 
7
- LLM-generated component code needs a stable, narrow API for the small set of browser capabilities that interactive UIs reach for: geolocation, clipboard read/write, notifications, file pickers, microphone, camera. Each capability has the same lifecycle shape — pending → ready → error — and the same permission-prompt UX. Encoding that shape once, in a typed React hook, keeps the generator's output:
7
+ LLM-generated component code needs a stable, narrow API for the small set of browser capabilities that interactive UIs reach for: geolocation, clipboard read/write, notifications, file pickers, microphone, camera. Each capability has the same lifecycle shape — idle → prompting → active → completed (or denied / error) — and the same permission-prompt UX. Encoding that shape once, in a typed React hook, keeps the generator's output:
8
8
 
9
9
  - predictable across providers and prompts,
10
10
  - testable by code-property assertions on the generated source (not just the rendered DOM),
@@ -22,7 +22,7 @@ Peer-dep: `react` ^18 || ^19.
22
22
 
23
23
  ## v1 stdlib catalog
24
24
 
25
- Seven hooks ship in v1, all with a shared `{ status, error, value | data | call }` shape:
25
+ Seven hooks ship in v1, all with a shared `{ value, status, error?, start, stop? }` shape:
26
26
 
27
27
  | Hook | Permission | Description |
28
28
  | ------------------- | ----------------- | ------------------------------------------------------------ |
@@ -34,7 +34,7 @@ Seven hooks ship in v1, all with a shared `{ status, error, value | data | call
34
34
  | `useMicrophone` | `microphone` | Stream access to the user's microphone via `getUserMedia`. |
35
35
  | `useCamera` | `camera` | Stream access to the user's camera via `getUserMedia`. |
36
36
 
37
- The same list is exported from `@ggui-ai/protocol` as `STDLIB_GADGETS` and seeds the discovery tool (`ggui_list_gadgets`) for any app without an operator-mutated override.
37
+ The same list is exported from `@ggui-ai/protocol` as `STDLIB_GADGETS` and forms the structural floor of every app's `ggui_list_gadgets` catalog — operator-declared packages (`ggui.json#app.gadgets`) layer on top, winning on a package-name collision.
38
38
 
39
39
  ## How a contract uses these hooks
40
40
 
@@ -59,8 +59,8 @@ export const photoCaptureContract = defineContract({
59
59
  // `gadgets` is package-keyed: `Record<package, Record<exportName,
60
60
  // { description?, usage? }>>`. The wire carries identity only —
61
61
  // `version`, transport fields, and per-export registry metadata
62
- // (`permission`, `example`, `gotchas`, `required`) are NOT on the
63
- // wire; the server resolves them from `App.gadgets` at push time.
62
+ // (`permission`, `example`, `gotchas`) are NOT on the wire; the
63
+ // server resolves them from `App.gadgets` at render time.
64
64
  gadgets: {
65
65
  "@ggui-ai/gadgets": {
66
66
  useCamera: {
package/dist/index.d.mts CHANGED
@@ -10,11 +10,17 @@ export { GadgetError, GadgetHook, GadgetStatus } from '@ggui-ai/protocol';
10
10
  * {@link GadgetHook}. The factory:
11
11
  *
12
12
  * 1. Strictly validates the spec at call time via
13
- * `strictGadgetDescriptorSchema` — non-empty teaching text
14
- * (`description` / `usage` / `example`), at least one of
15
- * `package` / `bundleUrl`, plus a non-function `hookImpl` check
16
- * the schema can't see. Throws {@link WrapperConformanceError}
17
- * with field-level paths on any violation.
13
+ * `strictGadgetDescriptorSchema` — `package` (npm name) and a
14
+ * pin-only semver `version` are REQUIRED on every descriptor,
15
+ * teaching text (`description` / `usage` / `example`) is
16
+ * REQUIRED and non-empty, URL fields (`bundleUrl` / `styleUrl` /
17
+ * `typesUrl`) must be full URLs — plus a non-function `hookImpl`
18
+ * check the schema can't see. Throws
19
+ * {@link WrapperConformanceError} with field-level paths on any
20
+ * violation. (`typesUrl` is not required HERE — at author time
21
+ * the build hasn't emitted a `.d.ts` yet — but registration via
22
+ * `registeredGadgetDescriptorSchema` requires it for every
23
+ * non-stdlib package.)
18
24
  * 2. Returns the React hook function as the primary export, with
19
25
  * the serializable {@link GadgetDescriptor} descriptor attached
20
26
  * as `.descriptor`. Single export, dual purpose:
@@ -26,7 +32,8 @@ export { GadgetError, GadgetHook, GadgetStatus } from '@ggui-ai/protocol';
26
32
  * usage: '...',
27
33
  * example: { ... },
28
34
  * package: '@my-org/ggui-leaflet',
29
- * styleUrl: '/leaflet.css',
35
+ * version: '0.1.0',
36
+ * styleUrl: 'https://cdn.example.com/ggui-leaflet/leaflet.css',
30
37
  * hookImpl: (options) => { …real React hook… },
31
38
  * });
32
39
  *
@@ -56,8 +63,8 @@ export { GadgetError, GadgetHook, GadgetStatus } from '@ggui-ai/protocol';
56
63
  * Author input to {@link createGguiGadget}. A `createGguiGadget` call
57
64
  * builds a gadget PACKAGE that exposes exactly one HOOK export — so
58
65
  * the spec keeps the per-export teaching fields flat (`hook`,
59
- * `description`, `usage`, `example`, `gotchas`, `permission`,
60
- * `required`) alongside the package identity + transport fields
66
+ * `description`, `usage`, `example`, `gotchas`, `permission`)
67
+ * alongside the package identity + transport fields
61
68
  * (`package`, `version`, `bundleUrl`, …) and a `hookImpl` runtime
62
69
  * function. The factory assembles these into a
63
70
  * {@link GadgetDescriptor} of the package+exports shape.
@@ -190,8 +197,6 @@ interface GadgetExportTeaching {
190
197
  readonly gotchas?: string;
191
198
  /** Optional Web-Permissions identifier the export gates on. */
192
199
  readonly permission?: string;
193
- /** Whether the UI MUST mount this export. Default `false`. */
194
- readonly required?: boolean;
195
200
  }
196
201
  /** A hook export declaration — `use`-prefixed name + its impl. */
197
202
  interface GadgetHookExportSpec extends GadgetExportTeaching {
@@ -256,7 +261,7 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
256
261
  * gadget catalog. The wire-side `DataContract.clientCapabilities.gadgets`
257
262
  * is intentionally narrow — it is package-keyed and carries identity
258
263
  * only (`(package, export name)`, no `version`, no transport
259
- * metadata), so push-time resolution looks up the matching
264
+ * metadata), so render-time resolution looks up the matching
260
265
  * {@link GadgetDescriptor} descriptor by npm package name. This module
261
266
  * declares the pluggable "where do descriptors come from?" port + ships
262
267
  * two batteries-included implementations:
@@ -267,8 +272,8 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
267
272
  *
268
273
  * - {@link CachingGadgetCatalog} — decorator over any other adapter
269
274
  * with per-appId TTL caching + single-flight deduplication. Right
270
- * for production cloud paths where descriptors live in DynamoDB /
271
- * a registry service and re-fetching on every push would burn
275
+ * for production paths where descriptors live in a database /
276
+ * a registry service and re-fetching on every render would burn
272
277
  * network round-trips. Caches are scoped per-appId so two apps
273
278
  * never see each other's catalogs.
274
279
  *
@@ -277,18 +282,18 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
277
282
  * - One method: `list(appId)`. Single batch read — never an N+1
278
283
  * "fetch descriptor for one package at a time" pattern. The
279
284
  * resolution caller indexes the returned array by `package`
280
- * itself. Single network call per push (with cache, often zero).
285
+ * itself. Single network call per render (with cache, often zero).
281
286
  *
282
287
  * - Return type is `readonly GadgetDescriptor[]` — the same shape the
283
- * wire push-time resolution + downstream consumers (boilerplate
288
+ * wire render-time resolution + downstream consumers (boilerplate
284
289
  * generator, CSP builder, Permissions-Policy deriver, system
285
290
  * prompt builder) already speak.
286
291
  *
287
292
  * - Errors propagate. Adapters MUST throw on retrieval failure
288
293
  * rather than returning an empty array — silent "no gadgets"
289
- * would let pushes through with broken gadget refs and surface
294
+ * would let renders through with broken gadget refs and surface
290
295
  * as render-time hook-resolution failures. The caller's job is
291
- * to decide whether the push fails (gate fires) or proceeds
296
+ * to decide whether the render fails (gate fires) or proceeds
292
297
  * ungated.
293
298
  *
294
299
  * ## Deployment-specific adapters
@@ -303,9 +308,9 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
303
308
  /**
304
309
  * Per-deployment source of registered gadget descriptors.
305
310
  *
306
- * Named parties: caller (push-time resolution / dev tools) ↔ adapter
307
- * (deployment-specific descriptor backing store, e.g., JSON, DynamoDB,
308
- * in-memory).
311
+ * Named parties: caller (render-time resolution / dev tools) ↔ adapter
312
+ * (deployment-specific descriptor backing store, e.g., JSON, a
313
+ * database, in-memory).
309
314
  *
310
315
  * Obligations:
311
316
  * - `list(appId)` MUST return the full set of descriptors registered
@@ -315,7 +320,7 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
315
320
  * returning `[]` is forbidden (it would mask broken catalogs).
316
321
  *
317
322
  * Failure mode: thrown error propagates to caller. Caller decides
318
- * whether to fail the push (strict) or fall back to a default set
323
+ * whether to fail the render (strict) or fall back to a default set
319
324
  * (lenient).
320
325
  *
321
326
  * Observable violation: caller observes a thrown error or a
@@ -349,8 +354,8 @@ declare class InMemoryGadgetCatalog implements GadgetCatalogAdapter {
349
354
  /**
350
355
  * Decorator adapter — wraps any {@link GadgetCatalogAdapter} with
351
356
  * per-appId TTL caching + single-flight deduplication. Right for
352
- * production paths where the inner adapter hits DynamoDB / a registry
353
- * service and per-push fetches would dominate latency.
357
+ * production paths where the inner adapter hits a database / a
358
+ * registry service and per-render fetches would dominate latency.
354
359
  *
355
360
  * Concurrent `list(appId)` calls during a cache miss share ONE
356
361
  * inflight Promise — no thundering herd against the inner adapter.
@@ -424,23 +429,23 @@ declare class CachingGadgetCatalog implements GadgetCatalogAdapter {
424
429
  * without leaking the values themselves.
425
430
  * - Pass `{ optional: true }` to get `undefined` for a missing key
426
431
  * instead of throwing. Use when the wrapper has a sensible
427
- * fallback (e.g., a default origin); the push gate enforces that
432
+ * fallback (e.g., a default origin); the render gate enforces that
428
433
  * declared `requires` keys are present, so the typical wrapper
429
434
  * path uses the throwing default.
430
435
  * - Empty-string values are returned verbatim (the operator may
431
436
  * have intentionally configured a key with no value).
432
437
  *
433
- * The push gate (`assertPublicEnvSatisfied`) verifies the
438
+ * The render gate (`assertPublicEnvSatisfied`) verifies the
434
439
  * `App.publicEnv` satisfies every declared wrapper's `requires` BEFORE
435
440
  * the iframe boots. So in well-configured deployments, the only
436
441
  * `getPublicEnv` throws are gadget authoring bugs (typoed key, key
437
- * not declared in `requires`). In production, the push gate catches
442
+ * not declared in `requires`). In production, the render gate catches
438
443
  * the misconfiguration upstream.
439
444
  */
440
445
  interface GetPublicEnvOptions {
441
446
  /**
442
447
  * When true, returns `undefined` for a missing key instead of
443
- * throwing. Use sparingly — the push gate enforces declared
448
+ * throwing. Use sparingly — the render gate enforces declared
444
449
  * `requires`, so a missing key usually indicates a wrapper bug
445
450
  * (key not in `requires` array). The throwing default is the
446
451
  * right call for keys that ARE declared in `requires`.
@@ -511,7 +516,8 @@ declare const useGeolocation: GadgetHook<GeolocationCoords, GeolocationOptions>;
511
516
  * the system clipboard via `navigator.clipboard.writeText`. Satisfies
512
517
  * `GadgetHook<string, ClipboardWriteOptions>`.
513
518
  *
514
- * One-shot semantics: call `start({text})` to write; status moves
519
+ * One-shot semantics: pass `{text}` at hook-call time and call
520
+ * `start()` to write; status moves
515
521
  * `idle → prompting → completed` on success or `idle → prompting →
516
522
  * denied/error` on failure. The hook's `value` carries the most
517
523
  * recently written text so component code can confirm what landed
@@ -523,7 +529,9 @@ declare const useGeolocation: GadgetHook<GeolocationCoords, GeolocationOptions>;
523
529
  */
524
530
 
525
531
  interface ClipboardWriteOptions {
526
- /** Text to write. Required at call site, not at hook construction. */
532
+ /** Text to write. Supplied at hook-call time; read when `start()`
533
+ * fires, so component code re-renders the hook call with the
534
+ * latest text rather than passing arguments to `start()`. */
527
535
  readonly text: string;
528
536
  }
529
537
  declare const useClipboardWrite: GadgetHook<string, ClipboardWriteOptions>;
package/dist/index.d.ts CHANGED
@@ -10,11 +10,17 @@ export { GadgetError, GadgetHook, GadgetStatus } from '@ggui-ai/protocol';
10
10
  * {@link GadgetHook}. The factory:
11
11
  *
12
12
  * 1. Strictly validates the spec at call time via
13
- * `strictGadgetDescriptorSchema` — non-empty teaching text
14
- * (`description` / `usage` / `example`), at least one of
15
- * `package` / `bundleUrl`, plus a non-function `hookImpl` check
16
- * the schema can't see. Throws {@link WrapperConformanceError}
17
- * with field-level paths on any violation.
13
+ * `strictGadgetDescriptorSchema` — `package` (npm name) and a
14
+ * pin-only semver `version` are REQUIRED on every descriptor,
15
+ * teaching text (`description` / `usage` / `example`) is
16
+ * REQUIRED and non-empty, URL fields (`bundleUrl` / `styleUrl` /
17
+ * `typesUrl`) must be full URLs — plus a non-function `hookImpl`
18
+ * check the schema can't see. Throws
19
+ * {@link WrapperConformanceError} with field-level paths on any
20
+ * violation. (`typesUrl` is not required HERE — at author time
21
+ * the build hasn't emitted a `.d.ts` yet — but registration via
22
+ * `registeredGadgetDescriptorSchema` requires it for every
23
+ * non-stdlib package.)
18
24
  * 2. Returns the React hook function as the primary export, with
19
25
  * the serializable {@link GadgetDescriptor} descriptor attached
20
26
  * as `.descriptor`. Single export, dual purpose:
@@ -26,7 +32,8 @@ export { GadgetError, GadgetHook, GadgetStatus } from '@ggui-ai/protocol';
26
32
  * usage: '...',
27
33
  * example: { ... },
28
34
  * package: '@my-org/ggui-leaflet',
29
- * styleUrl: '/leaflet.css',
35
+ * version: '0.1.0',
36
+ * styleUrl: 'https://cdn.example.com/ggui-leaflet/leaflet.css',
30
37
  * hookImpl: (options) => { …real React hook… },
31
38
  * });
32
39
  *
@@ -56,8 +63,8 @@ export { GadgetError, GadgetHook, GadgetStatus } from '@ggui-ai/protocol';
56
63
  * Author input to {@link createGguiGadget}. A `createGguiGadget` call
57
64
  * builds a gadget PACKAGE that exposes exactly one HOOK export — so
58
65
  * the spec keeps the per-export teaching fields flat (`hook`,
59
- * `description`, `usage`, `example`, `gotchas`, `permission`,
60
- * `required`) alongside the package identity + transport fields
66
+ * `description`, `usage`, `example`, `gotchas`, `permission`)
67
+ * alongside the package identity + transport fields
61
68
  * (`package`, `version`, `bundleUrl`, …) and a `hookImpl` runtime
62
69
  * function. The factory assembles these into a
63
70
  * {@link GadgetDescriptor} of the package+exports shape.
@@ -190,8 +197,6 @@ interface GadgetExportTeaching {
190
197
  readonly gotchas?: string;
191
198
  /** Optional Web-Permissions identifier the export gates on. */
192
199
  readonly permission?: string;
193
- /** Whether the UI MUST mount this export. Default `false`. */
194
- readonly required?: boolean;
195
200
  }
196
201
  /** A hook export declaration — `use`-prefixed name + its impl. */
197
202
  interface GadgetHookExportSpec extends GadgetExportTeaching {
@@ -256,7 +261,7 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
256
261
  * gadget catalog. The wire-side `DataContract.clientCapabilities.gadgets`
257
262
  * is intentionally narrow — it is package-keyed and carries identity
258
263
  * only (`(package, export name)`, no `version`, no transport
259
- * metadata), so push-time resolution looks up the matching
264
+ * metadata), so render-time resolution looks up the matching
260
265
  * {@link GadgetDescriptor} descriptor by npm package name. This module
261
266
  * declares the pluggable "where do descriptors come from?" port + ships
262
267
  * two batteries-included implementations:
@@ -267,8 +272,8 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
267
272
  *
268
273
  * - {@link CachingGadgetCatalog} — decorator over any other adapter
269
274
  * with per-appId TTL caching + single-flight deduplication. Right
270
- * for production cloud paths where descriptors live in DynamoDB /
271
- * a registry service and re-fetching on every push would burn
275
+ * for production paths where descriptors live in a database /
276
+ * a registry service and re-fetching on every render would burn
272
277
  * network round-trips. Caches are scoped per-appId so two apps
273
278
  * never see each other's catalogs.
274
279
  *
@@ -277,18 +282,18 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
277
282
  * - One method: `list(appId)`. Single batch read — never an N+1
278
283
  * "fetch descriptor for one package at a time" pattern. The
279
284
  * resolution caller indexes the returned array by `package`
280
- * itself. Single network call per push (with cache, often zero).
285
+ * itself. Single network call per render (with cache, often zero).
281
286
  *
282
287
  * - Return type is `readonly GadgetDescriptor[]` — the same shape the
283
- * wire push-time resolution + downstream consumers (boilerplate
288
+ * wire render-time resolution + downstream consumers (boilerplate
284
289
  * generator, CSP builder, Permissions-Policy deriver, system
285
290
  * prompt builder) already speak.
286
291
  *
287
292
  * - Errors propagate. Adapters MUST throw on retrieval failure
288
293
  * rather than returning an empty array — silent "no gadgets"
289
- * would let pushes through with broken gadget refs and surface
294
+ * would let renders through with broken gadget refs and surface
290
295
  * as render-time hook-resolution failures. The caller's job is
291
- * to decide whether the push fails (gate fires) or proceeds
296
+ * to decide whether the render fails (gate fires) or proceeds
292
297
  * ungated.
293
298
  *
294
299
  * ## Deployment-specific adapters
@@ -303,9 +308,9 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
303
308
  /**
304
309
  * Per-deployment source of registered gadget descriptors.
305
310
  *
306
- * Named parties: caller (push-time resolution / dev tools) ↔ adapter
307
- * (deployment-specific descriptor backing store, e.g., JSON, DynamoDB,
308
- * in-memory).
311
+ * Named parties: caller (render-time resolution / dev tools) ↔ adapter
312
+ * (deployment-specific descriptor backing store, e.g., JSON, a
313
+ * database, in-memory).
309
314
  *
310
315
  * Obligations:
311
316
  * - `list(appId)` MUST return the full set of descriptors registered
@@ -315,7 +320,7 @@ declare function defineGadgetPackage(spec: GadgetPackageSpec): GadgetDescriptor;
315
320
  * returning `[]` is forbidden (it would mask broken catalogs).
316
321
  *
317
322
  * Failure mode: thrown error propagates to caller. Caller decides
318
- * whether to fail the push (strict) or fall back to a default set
323
+ * whether to fail the render (strict) or fall back to a default set
319
324
  * (lenient).
320
325
  *
321
326
  * Observable violation: caller observes a thrown error or a
@@ -349,8 +354,8 @@ declare class InMemoryGadgetCatalog implements GadgetCatalogAdapter {
349
354
  /**
350
355
  * Decorator adapter — wraps any {@link GadgetCatalogAdapter} with
351
356
  * per-appId TTL caching + single-flight deduplication. Right for
352
- * production paths where the inner adapter hits DynamoDB / a registry
353
- * service and per-push fetches would dominate latency.
357
+ * production paths where the inner adapter hits a database / a
358
+ * registry service and per-render fetches would dominate latency.
354
359
  *
355
360
  * Concurrent `list(appId)` calls during a cache miss share ONE
356
361
  * inflight Promise — no thundering herd against the inner adapter.
@@ -424,23 +429,23 @@ declare class CachingGadgetCatalog implements GadgetCatalogAdapter {
424
429
  * without leaking the values themselves.
425
430
  * - Pass `{ optional: true }` to get `undefined` for a missing key
426
431
  * instead of throwing. Use when the wrapper has a sensible
427
- * fallback (e.g., a default origin); the push gate enforces that
432
+ * fallback (e.g., a default origin); the render gate enforces that
428
433
  * declared `requires` keys are present, so the typical wrapper
429
434
  * path uses the throwing default.
430
435
  * - Empty-string values are returned verbatim (the operator may
431
436
  * have intentionally configured a key with no value).
432
437
  *
433
- * The push gate (`assertPublicEnvSatisfied`) verifies the
438
+ * The render gate (`assertPublicEnvSatisfied`) verifies the
434
439
  * `App.publicEnv` satisfies every declared wrapper's `requires` BEFORE
435
440
  * the iframe boots. So in well-configured deployments, the only
436
441
  * `getPublicEnv` throws are gadget authoring bugs (typoed key, key
437
- * not declared in `requires`). In production, the push gate catches
442
+ * not declared in `requires`). In production, the render gate catches
438
443
  * the misconfiguration upstream.
439
444
  */
440
445
  interface GetPublicEnvOptions {
441
446
  /**
442
447
  * When true, returns `undefined` for a missing key instead of
443
- * throwing. Use sparingly — the push gate enforces declared
448
+ * throwing. Use sparingly — the render gate enforces declared
444
449
  * `requires`, so a missing key usually indicates a wrapper bug
445
450
  * (key not in `requires` array). The throwing default is the
446
451
  * right call for keys that ARE declared in `requires`.
@@ -511,7 +516,8 @@ declare const useGeolocation: GadgetHook<GeolocationCoords, GeolocationOptions>;
511
516
  * the system clipboard via `navigator.clipboard.writeText`. Satisfies
512
517
  * `GadgetHook<string, ClipboardWriteOptions>`.
513
518
  *
514
- * One-shot semantics: call `start({text})` to write; status moves
519
+ * One-shot semantics: pass `{text}` at hook-call time and call
520
+ * `start()` to write; status moves
515
521
  * `idle → prompting → completed` on success or `idle → prompting →
516
522
  * denied/error` on failure. The hook's `value` carries the most
517
523
  * recently written text so component code can confirm what landed
@@ -523,7 +529,9 @@ declare const useGeolocation: GadgetHook<GeolocationCoords, GeolocationOptions>;
523
529
  */
524
530
 
525
531
  interface ClipboardWriteOptions {
526
- /** Text to write. Required at call site, not at hook construction. */
532
+ /** Text to write. Supplied at hook-call time; read when `start()`
533
+ * fires, so component code re-renders the hook call with the
534
+ * latest text rather than passing arguments to `start()`. */
527
535
  readonly text: string;
528
536
  }
529
537
  declare const useClipboardWrite: GadgetHook<string, ClipboardWriteOptions>;
package/dist/index.js CHANGED
@@ -59,7 +59,6 @@ function createGguiGadget(spec) {
59
59
  example,
60
60
  gotchas,
61
61
  permission,
62
- required,
63
62
  ...packageFields
64
63
  } = spec;
65
64
  const violations = [];
@@ -75,8 +74,7 @@ function createGguiGadget(spec) {
75
74
  usage,
76
75
  example,
77
76
  ...gotchas !== void 0 ? { gotchas } : {},
78
- ...permission !== void 0 ? { permission } : {},
79
- ...required !== void 0 ? { required } : {}
77
+ ...permission !== void 0 ? { permission } : {}
80
78
  };
81
79
  const descriptorDraft = {
82
80
  ...packageFields,
@@ -131,8 +129,7 @@ function defineGadgetPackage(spec) {
131
129
  usage: entry.usage,
132
130
  example: entry.example,
133
131
  ...entry.gotchas !== void 0 ? { gotchas: entry.gotchas } : {},
134
- ...entry.permission !== void 0 ? { permission: entry.permission } : {},
135
- ...entry.required !== void 0 ? { required: entry.required } : {}
132
+ ...entry.permission !== void 0 ? { permission: entry.permission } : {}
136
133
  };
137
134
  return "hook" in entry ? { hook: entry.hook, ...teaching } : { component: entry.component, ...teaching };
138
135
  });
@@ -254,7 +251,7 @@ function getPublicEnv(key, opts, target = globalThis) {
254
251
  if (opts?.optional) return void 0;
255
252
  const available = Object.keys(env);
256
253
  throw new Error(
257
- `getPublicEnv('${key}'): not provided in App.publicEnv. Available: [${available.join(", ") || "(none)"}]. Operators set this on the App record; gadget authors declare the key in 'requires' so the push gate verifies it before mount.`
254
+ `getPublicEnv('${key}'): not provided in App.publicEnv. Available: [${available.join(", ") || "(none)"}]. Operators set this on the App record; gadget authors declare the key in 'requires' so the render gate verifies it before mount.`
258
255
  );
259
256
  }
260
257
 
package/dist/index.mjs CHANGED
@@ -23,7 +23,6 @@ function createGguiGadget(spec) {
23
23
  example,
24
24
  gotchas,
25
25
  permission,
26
- required,
27
26
  ...packageFields
28
27
  } = spec;
29
28
  const violations = [];
@@ -39,8 +38,7 @@ function createGguiGadget(spec) {
39
38
  usage,
40
39
  example,
41
40
  ...gotchas !== void 0 ? { gotchas } : {},
42
- ...permission !== void 0 ? { permission } : {},
43
- ...required !== void 0 ? { required } : {}
41
+ ...permission !== void 0 ? { permission } : {}
44
42
  };
45
43
  const descriptorDraft = {
46
44
  ...packageFields,
@@ -97,8 +95,7 @@ function defineGadgetPackage(spec) {
97
95
  usage: entry.usage,
98
96
  example: entry.example,
99
97
  ...entry.gotchas !== void 0 ? { gotchas: entry.gotchas } : {},
100
- ...entry.permission !== void 0 ? { permission: entry.permission } : {},
101
- ...entry.required !== void 0 ? { required: entry.required } : {}
98
+ ...entry.permission !== void 0 ? { permission: entry.permission } : {}
102
99
  };
103
100
  return "hook" in entry ? { hook: entry.hook, ...teaching } : { component: entry.component, ...teaching };
104
101
  });
@@ -220,7 +217,7 @@ function getPublicEnv(key, opts, target = globalThis) {
220
217
  if (opts?.optional) return void 0;
221
218
  const available = Object.keys(env);
222
219
  throw new Error(
223
- `getPublicEnv('${key}'): not provided in App.publicEnv. Available: [${available.join(", ") || "(none)"}]. Operators set this on the App record; gadget authors declare the key in 'requires' so the push gate verifies it before mount.`
220
+ `getPublicEnv('${key}'): not provided in App.publicEnv. Available: [${available.join(", ") || "(none)"}]. Operators set this on the App record; gadget authors declare the key in 'requires' so the render gate verifies it before mount.`
224
221
  );
225
222
  }
226
223
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ggui-ai/gadgets",
3
- "version": "0.2.0-alpha.4",
3
+ "version": "0.4.0-rc.0",
4
4
  "description": "Browser-capability gadget hooks for ggui — declared via DataContract.clientCapabilities.gadgets, mounted by the UI generator's component code.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -57,10 +57,10 @@
57
57
  "react-dom": "^19.0.0",
58
58
  "tsup": "^8.0.0",
59
59
  "typescript": "^5.0.0",
60
- "vitest": "^2.0.0"
60
+ "vitest": "^3.2.6"
61
61
  },
62
62
  "dependencies": {
63
- "@ggui-ai/protocol": "0.2.0-alpha.4"
63
+ "@ggui-ai/protocol": "0.4.0-rc.0"
64
64
  },
65
65
  "engines": {
66
66
  "node": ">=20.0.0"