@ikenga/contract 0.7.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.
- package/README.md +56 -11
- package/dist/canvas/Canvas.d.ts +7 -0
- package/dist/canvas/Canvas.d.ts.map +1 -0
- package/dist/canvas/Canvas.js +115 -0
- package/dist/canvas/Canvas.js.map +1 -0
- package/dist/canvas/canvas.css +579 -0
- package/dist/canvas/index.d.ts +7 -0
- package/dist/canvas/index.d.ts.map +1 -0
- package/dist/canvas/index.js +4 -0
- package/dist/canvas/index.js.map +1 -0
- package/dist/canvas/types.d.ts +45 -0
- package/dist/canvas/types.d.ts.map +1 -0
- package/dist/canvas/types.js +2 -0
- package/dist/canvas/types.js.map +1 -0
- package/dist/canvas/use-drag-snap.d.ts +33 -0
- package/dist/canvas/use-drag-snap.d.ts.map +1 -0
- package/dist/canvas/use-drag-snap.js +73 -0
- package/dist/canvas/use-drag-snap.js.map +1 -0
- package/dist/canvas/use-pan-zoom.d.ts +32 -0
- package/dist/canvas/use-pan-zoom.d.ts.map +1 -0
- package/dist/canvas/use-pan-zoom.js +161 -0
- package/dist/canvas/use-pan-zoom.js.map +1 -0
- package/dist/engine.d.ts +574 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +85 -0
- package/dist/engine.js.map +1 -0
- package/dist/host-verbs.d.ts +194 -0
- package/dist/host-verbs.d.ts.map +1 -0
- package/dist/host-verbs.js +15 -0
- package/dist/host-verbs.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +376 -19
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +95 -4
- package/dist/manifest.js.map +1 -1
- package/dist/registry.d.ts +364 -36
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +9 -0
- package/dist/registry.js.map +1 -1
- package/dist/scopes.js +1 -1
- package/dist/scopes.js.map +1 -1
- package/package.json +36 -10
- package/schemas/registry/index-v1.json +11 -0
- package/src/canvas/Canvas.tsx +161 -0
- package/src/canvas/canvas.css +579 -0
- package/src/canvas/index.ts +14 -0
- package/src/canvas/types.ts +48 -0
- package/src/canvas/use-drag-snap.ts +107 -0
- package/src/canvas/use-pan-zoom.ts +211 -0
- package/src/host-verbs.ts +207 -0
- package/src/index.ts +1 -0
- package/src/manifest.test.ts +97 -0
- package/src/manifest.ts +109 -4
- package/src/registry.ts +9 -0
- package/src/scopes.ts +1 -1
package/README.md
CHANGED
|
@@ -1,38 +1,83 @@
|
|
|
1
1
|
# @ikenga/contract
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/Royalti-io/ikenga-contract/actions)
|
|
4
|
+
[](https://github.com/Royalti-io/ikenga-contract/releases)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://github.com/Royalti-io/ikenga-contract/discussions)
|
|
4
7
|
|
|
5
|
-
|
|
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 (
|
|
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` |
|
|
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
|
|
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`
|
|
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
|
|
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
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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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"}
|