@ikenga/contract 0.6.0 → 0.9.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.
Files changed (74) hide show
  1. package/README.md +56 -11
  2. package/dist/canvas/Canvas.d.ts +7 -0
  3. package/dist/canvas/Canvas.d.ts.map +1 -0
  4. package/dist/canvas/Canvas.js +115 -0
  5. package/dist/canvas/Canvas.js.map +1 -0
  6. package/dist/canvas/canvas.css +579 -0
  7. package/dist/canvas/index.d.ts +7 -0
  8. package/dist/canvas/index.d.ts.map +1 -0
  9. package/dist/canvas/index.js +4 -0
  10. package/dist/canvas/index.js.map +1 -0
  11. package/dist/canvas/types.d.ts +45 -0
  12. package/dist/canvas/types.d.ts.map +1 -0
  13. package/dist/canvas/types.js +2 -0
  14. package/dist/canvas/types.js.map +1 -0
  15. package/dist/canvas/use-drag-snap.d.ts +33 -0
  16. package/dist/canvas/use-drag-snap.d.ts.map +1 -0
  17. package/dist/canvas/use-drag-snap.js +73 -0
  18. package/dist/canvas/use-drag-snap.js.map +1 -0
  19. package/dist/canvas/use-pan-zoom.d.ts +32 -0
  20. package/dist/canvas/use-pan-zoom.d.ts.map +1 -0
  21. package/dist/canvas/use-pan-zoom.js +161 -0
  22. package/dist/canvas/use-pan-zoom.js.map +1 -0
  23. package/dist/engine/index.d.ts +2 -0
  24. package/dist/engine/index.d.ts.map +1 -1
  25. package/dist/engine/index.js +2 -0
  26. package/dist/engine/index.js.map +1 -1
  27. package/dist/engine/portability.d.ts +113 -0
  28. package/dist/engine/portability.d.ts.map +1 -0
  29. package/dist/engine/portability.js +17 -0
  30. package/dist/engine/portability.js.map +1 -0
  31. package/dist/engine/subagent-transcoder.d.ts +24 -0
  32. package/dist/engine/subagent-transcoder.d.ts.map +1 -0
  33. package/dist/engine/subagent-transcoder.js +341 -0
  34. package/dist/engine/subagent-transcoder.js.map +1 -0
  35. package/dist/engine.d.ts +574 -0
  36. package/dist/engine.d.ts.map +1 -0
  37. package/dist/engine.js +85 -0
  38. package/dist/engine.js.map +1 -0
  39. package/dist/host-verbs.d.ts +194 -0
  40. package/dist/host-verbs.d.ts.map +1 -0
  41. package/dist/host-verbs.js +15 -0
  42. package/dist/host-verbs.js.map +1 -0
  43. package/dist/index.d.ts +1 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +1 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/manifest.d.ts +376 -19
  48. package/dist/manifest.d.ts.map +1 -1
  49. package/dist/manifest.js +95 -4
  50. package/dist/manifest.js.map +1 -1
  51. package/dist/registry.d.ts +364 -36
  52. package/dist/registry.d.ts.map +1 -1
  53. package/dist/registry.js +9 -0
  54. package/dist/registry.js.map +1 -1
  55. package/dist/scopes.js +1 -1
  56. package/dist/scopes.js.map +1 -1
  57. package/package.json +36 -10
  58. package/schemas/registry/index-v1.json +11 -0
  59. package/src/canvas/Canvas.tsx +161 -0
  60. package/src/canvas/canvas.css +579 -0
  61. package/src/canvas/index.ts +14 -0
  62. package/src/canvas/types.ts +48 -0
  63. package/src/canvas/use-drag-snap.ts +107 -0
  64. package/src/canvas/use-pan-zoom.ts +211 -0
  65. package/src/engine/index.ts +2 -0
  66. package/src/engine/portability.ts +123 -0
  67. package/src/engine/subagent-transcoder.test.ts +306 -0
  68. package/src/engine/subagent-transcoder.ts +333 -0
  69. package/src/host-verbs.ts +207 -0
  70. package/src/index.ts +1 -0
  71. package/src/manifest.test.ts +97 -0
  72. package/src/manifest.ts +109 -4
  73. package/src/registry.ts +9 -0
  74. package/src/scopes.ts +1 -1
package/README.md CHANGED
@@ -1,38 +1,83 @@
1
1
  # @ikenga/contract
2
2
 
3
- The single source of truth for how the **Ikenga shell**, **pkgs**, and **engines** talk to each other.
3
+ [![Build](https://img.shields.io/badge/build-passing-brightgreen.svg)](https://github.com/Royalti-io/ikenga-contract/actions)
4
+ [![Version](https://img.shields.io/badge/version-v0.2.0-blue.svg)](https://github.com/Royalti-io/ikenga-contract/releases)
5
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
6
+ [![Discussions](https://img.shields.io/badge/community-discussions-5865F2.svg)](https://github.com/Royalti-io/ikenga-contract/discussions)
4
7
 
5
- This package is intentionally small and stable. Bumping its major version is an event coordinated across the shell + every published pkg.
8
+ > The single source of truth for how the Ikenga shell, pkgs, and engines talk to each
9
+ > other.
10
+
11
+ ## What it is
12
+
13
+ `@ikenga/contract` is the shared TypeScript package that defines the wire between the
14
+ [Ikenga shell](https://github.com/Royalti-io/ikenga), its packages, and its engine
15
+ adapters: the manifest schema, the RPC envelope, the Engine interface, and the capability
16
+ scope catalogue. It's intentionally small and stable — bumping its major version is an
17
+ event coordinated across the shell and every published pkg.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pnpm add @ikenga/contract
23
+ ```
24
+
25
+ In the workspace, this resolves as `workspace:*`.
6
26
 
7
27
  ## What's in here
8
28
 
9
29
  | Module | Exports |
10
30
  |--------|---------|
11
- | `@ikenga/contract/manifest` | `ikenga-pkg.toml` schema (zod) — `ManifestSchema`, `Manifest` type |
31
+ | `@ikenga/contract/manifest` | `ikenga-pkg.toml` schema (Zod) — `ManifestSchema`, `Manifest` type |
12
32
  | `@ikenga/contract/rpc` | Shell ↔ pkg postMessage RPC envelope, request/response types |
13
33
  | `@ikenga/contract/engine` | `Engine` interface, `Session`, `EngineEvent` types |
14
34
  | `@ikenga/contract/scopes` | Capability scope catalogue (`tasks:read`, `engine:invoke`, …) |
15
- | `@ikenga/contract/artifact` | Ikenga artifact manifest schema (zod) — `ArtifactManifestSchema`, `ArtifactManifest` type, refresh / data-source / fallback sub-schemas |
35
+ | `@ikenga/contract/artifact` | Artifact manifest schema (Zod) — `ArtifactManifestSchema`, `ArtifactManifest` type, refresh / data-source / fallback sub-schemas |
16
36
 
17
37
  ## Artifact manifest
18
38
 
19
- The artifact manifest is the JSON block embedded in `<script type="application/json" id="ikenga-manifest">…</script>` (single-file artifacts) or in `manifest.json` (folder mode). It's a separate concept from the pkg manifest — pkgs are heavyweight Tauri-side mini-apps; artifacts are portable HTML docs that render anywhere and light up with live data inside the Ikenga shell.
39
+ The artifact manifest is the JSON block embedded in
40
+ `<script type="application/json" id="ikenga-manifest">…</script>` (single-file artifacts) or
41
+ in `manifest.json` (folder mode). It's a separate concept from the pkg manifest — pkgs are
42
+ heavyweight Tauri-side mini-apps; artifacts are portable HTML docs that render anywhere and
43
+ light up with live data inside the shell.
20
44
 
21
45
  - Source of truth: `src/artifact.ts` (Zod).
22
46
  - Generated JSON Schema: `schemas/artifact/v0.json` — regenerate with `pnpm generate:schemas` after schema edits.
23
- - Published at: `https://royalti-io.github.io/ikenga-contract/schemas/artifact/v0.json` (`$id` is stamped at generation time).
47
+ - Published at: `https://royalti-io.github.io/ikenga-contract/schemas/artifact/v0.json` (`$id` stamped at generation time).
24
48
  - Fixtures (the three v0 example artifacts) live in `src/artifact-fixtures/` and are gated by `pnpm test`.
25
49
 
26
50
  ## Versioning
27
51
 
28
- Strict semver. Pkgs declare `"contract": "^1"` and the kernel checks compatibility at install time.
52
+ Strict semver. Pkgs declare `"contract": "^1"` and the kernel checks compatibility at
53
+ install time.
29
54
 
30
55
  ## Source of truth
31
56
 
32
- The `Manifest` schema **mirrors** the Rust struct in `royalti-io/ikenga` at `src-tauri/src/pkg/manifest.rs`. The Rust kernel parses pkg `manifest.json` files; this package is a TS-side validator and types-only mirror for tooling (CLI, registry build).
33
-
34
- If you need to change the manifest, change the Rust struct first and update this schema in lockstep.
57
+ The `Manifest` schema **mirrors** the Rust struct in
58
+ [`Royalti-io/ikenga`](https://github.com/Royalti-io/ikenga) at
59
+ `src-tauri/src/pkg/manifest.rs`. The Rust kernel parses pkg `manifest.json` files; this
60
+ package is a TS-side validator and types-only mirror for tooling (CLI, registry build). To
61
+ change the manifest, change the Rust struct first and update this schema in lockstep.
35
62
 
36
63
  ## Status
37
64
 
38
- `v0.2.0` — manifest realigned to the real Rust schema (was a speculative parallel in v0.1.0). RPC method catalogue, engine interface, and capability scopes still in place but unused by the kernel today; treat them as forward-looking.
65
+ `v0.2.0` — manifest realigned to the real Rust schema (was a speculative parallel in
66
+ v0.1.0). RPC method catalogue, engine interface, and capability scopes are still in place
67
+ but unused by the kernel today; treat them as forward-looking.
68
+
69
+ ## Links
70
+
71
+ - [ikenga.dev](https://ikenga.dev) — site + docs
72
+ - [`ikenga`](https://github.com/Royalti-io/ikenga) — the desktop shell (owns the Rust source of truth)
73
+ - [`ikenga-pkgs`](https://github.com/Royalti-io/ikenga-pkgs) — first-party packages
74
+
75
+ ## License
76
+
77
+ Apache-2.0 — see [`LICENSE`](LICENSE).
78
+
79
+ ## Contributing & community
80
+
81
+ Issues and PRs welcome. Start a thread in
82
+ [Discussions](https://github.com/Royalti-io/ikenga-contract/discussions).
83
+ <!-- VERIFY: link CONTRIBUTING.md / CODE_OF_CONDUCT.md once the org .github defaults or per-repo copies exist. -->
@@ -0,0 +1,7 @@
1
+ import { type ReactElement } from 'react';
2
+ import './canvas.css';
3
+ import type { CanvasHandle, CanvasProps } from './types.js';
4
+ export declare const Canvas: <T>(props: CanvasProps<T> & {
5
+ ref?: React.Ref<CanvasHandle>;
6
+ }) => ReactElement;
7
+ //# sourceMappingURL=Canvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Canvas.d.ts","sourceRoot":"","sources":["../../src/canvas/Canvas.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,OAAO,CAAC;AACf,OAAO,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAA2B,MAAM,YAAY,CAAC;AAmIrF,eAAO,MAAM,MAAM,EAA8B,CAAC,CAAC,EACjD,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;CAAE,KACtD,YAAY,CAAC"}
@@ -0,0 +1,115 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // <Canvas> — the reusable free-form pan/zoom/grid-snap surface extracted from
3
+ // the shell home page. Composes usePanZoom + useDragSnap and renders the
4
+ // stage + items; the consumer supplies item content via `renderItem` and owns
5
+ // `layout` / `editMode` / `selectedId` (all controlled props).
6
+ //
7
+ // Item DOM: Canvas does NOT wrap items in an extra positioned div. It clones
8
+ // the element `renderItem` returns and injects `data-id`, the canvas-space
9
+ // left/top/width geometry, and the `is-selected` class onto it. So the
10
+ // consumer's own card element stays the positioned box — DOM shape matches the
11
+ // pre-extraction home exactly. The cloned element must carry its base class
12
+ // (e.g. `home-widget` / `home-greeting`) and `position: absolute` (the bundled
13
+ // canvas.css supplies the latter for the home classes).
14
+ //
15
+ // CSS: canvas.css is imported as a side effect here, so any bundler following
16
+ // the import graph (Vite in a pkg, the shell's build) inlines it. Its
17
+ // var(--*) tokens resolve against the host document — inside a Vite/iframe pkg
18
+ // the consumer must import @ikenga/tokens at entry (Round 8 / G21).
19
+ import { cloneElement, forwardRef, isValidElement, useImperativeHandle, } from 'react';
20
+ import './canvas.css';
21
+ import { usePanZoom } from './use-pan-zoom.js';
22
+ import { useDragSnap } from './use-drag-snap.js';
23
+ // Hit-test class roots Canvas owns. Anything matching these inside the canvas
24
+ // counts as a draggable item; the bar/palette are excluded from gestures.
25
+ const ITEM_SELECTOR = '.home-widget, .home-greeting, [data-canvas-item]';
26
+ const BAR_SELECTOR = '.ikenga-canvas-bar';
27
+ const PALETTE_SELECTOR = '.home-palette';
28
+ function CanvasInner(props, ref) {
29
+ const { items, itemId, itemKind, layout, viewport, editMode, selectedId = null, gridSnap = 12, renderItem, onLayoutChange, onViewportChange, onEditModeChange, onSelectionChange, autoFitOnResize = true, className, } = props;
30
+ const { pan, autoFit, canvasRef, stageRef, spaceDown, beginPan, isPanning } = usePanZoom({
31
+ layout,
32
+ editMode,
33
+ autoFitOnResize,
34
+ onViewportChange,
35
+ onEditModeChange,
36
+ onSelectionChange,
37
+ });
38
+ const { beginDrag } = useDragSnap({
39
+ layout,
40
+ gridSnap,
41
+ scale: viewport.scale,
42
+ onLayoutChange,
43
+ stageRef,
44
+ });
45
+ useImperativeHandle(ref, () => ({ autoFit }), [autoFit]);
46
+ function onMouseDown(e) {
47
+ const target = e.target;
48
+ if (target.closest(BAR_SELECTOR) || target.closest(PALETTE_SELECTOR))
49
+ return;
50
+ const middle = e.button === 1;
51
+ const itemEl = target.closest(ITEM_SELECTOR);
52
+ if (editMode && itemEl && !middle && !spaceDown.current) {
53
+ const id = itemEl.getAttribute('data-id');
54
+ if (!id)
55
+ return;
56
+ onSelectionChange?.(id);
57
+ beginDrag(id, e.clientX, e.clientY);
58
+ e.preventDefault();
59
+ return;
60
+ }
61
+ if (middle || spaceDown.current || (!editMode && !itemEl)) {
62
+ beginPan(e.clientX, e.clientY);
63
+ e.preventDefault();
64
+ }
65
+ if (editMode && !itemEl)
66
+ onSelectionChange?.(null);
67
+ }
68
+ function onDoubleClick(e) {
69
+ const t = e.target;
70
+ if (t.closest(ITEM_SELECTOR) || t.closest(BAR_SELECTOR) || t.closest(PALETTE_SELECTOR))
71
+ return;
72
+ autoFit(true);
73
+ }
74
+ const transform = `translate(${pan.x}px, ${pan.y}px) scale(${pan.scale})`;
75
+ return (_jsxs("div", { ref: canvasRef, className: className ? `ikenga-canvas ${className}` : 'ikenga-canvas', "data-mode-edit": editMode ? 'true' : 'false', onMouseDown: onMouseDown, onDoubleClick: onDoubleClick, children: [_jsx("div", { className: "ikenga-canvas-grain" }), _jsx("div", { ref: stageRef, className: "ikenga-canvas-stage", style: { transform }, children: items.map((item) => {
76
+ const id = itemId(item);
77
+ const placement = layout[id];
78
+ if (!placement)
79
+ return null;
80
+ const isSelected = selectedId === id;
81
+ const state = {
82
+ id,
83
+ kind: itemKind(item),
84
+ placement,
85
+ isSelected,
86
+ isEditMode: editMode,
87
+ };
88
+ const node = renderItem(item, state);
89
+ if (!isValidElement(node))
90
+ return node;
91
+ const el = node;
92
+ // Inject geometry under the consumer's own style so renderItem can
93
+ // still override (e.g. minHeight vs height for the naked greeting).
94
+ const injected = {
95
+ left: placement.x,
96
+ top: placement.y,
97
+ width: placement.w,
98
+ ...el.props.style,
99
+ };
100
+ // Append the selection class without clobbering the consumer's.
101
+ const baseClass = el.props.className ?? '';
102
+ const className = isSelected ? `${baseClass} is-selected`.trim() : baseClass;
103
+ return cloneElement(el, {
104
+ key: id,
105
+ 'data-id': id,
106
+ style: injected,
107
+ className,
108
+ });
109
+ }) }), props.children] }));
110
+ }
111
+ // forwardRef can't preserve the <T> generic through its typing, so we cast the
112
+ // wrapped component back to a generic-aware signature. Callers get full
113
+ // inference on CanvasProps<T>.
114
+ export const Canvas = forwardRef(CanvasInner);
115
+ //# sourceMappingURL=Canvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Canvas.js","sourceRoot":"","sources":["../../src/canvas/Canvas.tsx"],"names":[],"mappings":"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"}