agentic-canvas 0.4.0 → 0.6.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/dist/live.js CHANGED
@@ -2,12 +2,13 @@ import {
2
2
  Board,
3
3
  CanvasError,
4
4
  drawFlow,
5
- principalSchema,
6
5
  readBoard,
7
6
  toSvg
8
- } from "./chunk-JZA525X5.js";
7
+ } from "./chunk-JCYNPYYJ.js";
8
+ import "./chunk-SPP6PINW.js";
9
9
 
10
10
  // src/live.ts
11
+ import { parsePrincipal } from "agentic-identity";
11
12
  import { SyncClient } from "agentic-realtime/client";
12
13
  var CODES = ["INVALID", "DUPLICATE_ID", "NOT_FOUND", "BAD_REFERENCE", "LIMIT", "UNAVAILABLE", "FORBIDDEN"];
13
14
  var base = (server) => server.replace(/\/$/, "") + "/api/v1/canvas";
@@ -31,9 +32,13 @@ async function whoAmI(server, token) {
31
32
  const response = await call(server, token, "/me");
32
33
  if (!response.ok) throw await refusal(response, "the server refused the token");
33
34
  const { actor, kind, role } = await json(response);
34
- const principal = principalSchema.safeParse({ kind, id: actor });
35
- if (!principal.success || role !== "editor" && role !== "viewer") throw new CanvasError("INVALID", "the server sent an identity this client does not know");
36
- return { actor: principal.data, role };
35
+ let principal;
36
+ try {
37
+ principal = parsePrincipal({ kind, id: actor });
38
+ } catch {
39
+ }
40
+ if (!principal || role !== "editor" && role !== "viewer") throw new CanvasError("INVALID", "the server sent an identity this client does not know");
41
+ return { actor: principal, role };
37
42
  }
38
43
  var LiveBoard = class _LiveBoard {
39
44
  constructor(board, me, client, id, options, refusedAtStart) {
@@ -5,11 +5,11 @@ declare const principalSchema: z.ZodObject<{
5
5
  kind: z.ZodEnum<["human", "agent_of_human", "agent_of_agent", "agent", "user_token"]>;
6
6
  id: z.ZodString;
7
7
  }, "strict", z.ZodTypeAny, {
8
- id: string;
9
8
  kind: "human" | "agent_of_human" | "agent_of_agent" | "agent" | "user_token";
10
- }, {
11
9
  id: string;
10
+ }, {
12
11
  kind: "human" | "agent_of_human" | "agent_of_agent" | "agent" | "user_token";
12
+ id: string;
13
13
  }>;
14
14
  type Principal = z.infer<typeof principalSchema>;
15
15
 
@@ -173,4 +173,4 @@ interface BoardData {
173
173
  /** The board as plain data for an agent. Reads only. Embedded image bytes are left out. */
174
174
  declare function readBoard(board: Board): BoardData;
175
175
 
176
- export { type BoardData as B, type Connector as C, type ErrorCode as E, type Group as G, MAX_ELEMENTS as M, type NodeData as N, type Principal as P, type ShapeType as S, type Shape as a, type Endpoint as b, Board as c, type CanvasElement as d, CanvasError as e, type EdgeData as f, MAX_TEXT as g, SHAPE_TYPES as h, principalSchema as p, readBoard as r };
176
+ export { Board as B, type Connector as C, type ErrorCode as E, type Group as G, MAX_ELEMENTS as M, type NodeData as N, type Principal as P, type Shape as S, type BoardData as a, type CanvasElement as b, type ShapeType as c, type Endpoint as d, CanvasError as e, type EdgeData as f, MAX_TEXT as g, SHAPE_TYPES as h, principalSchema as p, readBoard as r };
@@ -1,4 +1,4 @@
1
- import { S as ShapeType, c as Board, P as Principal, B as BoardData, a as Shape, C as Connector, d as CanvasElement } from './read-Bdg1uiFC.js';
1
+ import { c as ShapeType, B as Board, P as Principal, a as BoardData, S as Shape, C as Connector, b as CanvasElement } from './read-BupIJSPJ.js';
2
2
  import { Store } from 'agentic-identity';
3
3
 
4
4
  declare const MAX_FLOW_NODES = 500;
package/dist/ui.css ADDED
@@ -0,0 +1,38 @@
1
+ /* Every rule is nested under .cv-root, so the styles do not reach the host page. */
2
+ .cv-root {
3
+ .row { display: flex; align-items: center; justify-content: space-between; gap: var(--ad-space-4); flex-wrap: wrap; }
4
+ .failure { border: 1px solid var(--ad-color-danger); border-radius: var(--ad-radius-md); padding: var(--ad-space-4); color: var(--ad-color-danger-text); background: var(--ad-color-danger-subtle); display: grid; gap: var(--ad-space-3); justify-items: start; }
5
+ .note { color: var(--ad-color-text-muted); }
6
+ .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
7
+
8
+ .board { display: grid; gap: var(--ad-space-3); }
9
+ .stage { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) 16rem; gap: var(--ad-space-3); height: 65vh; min-height: 22rem; }
10
+ @media (max-width: 48rem) { .stage { grid-template-columns: 1fr; height: auto; } .canvas { height: 55vh; } }
11
+ .canvas { background: var(--ad-color-surface-sunken); border: 1px solid var(--ad-color-border); border-radius: var(--ad-radius-md); overflow: hidden; touch-action: none; min-height: 18rem; }
12
+ .canvas:focus-visible { outline: 3px solid var(--ad-color-focus); outline-offset: 2px; }
13
+ .canvas svg { display: block; cursor: grab; font-family: var(--ad-font-family-sans); font-size: 14px; }
14
+ .item { outline: none; cursor: pointer; }
15
+ .shape { fill: var(--ad-color-surface-raised); stroke: var(--ad-color-border-strong); stroke-width: 1.5; }
16
+ .shape.text { fill: transparent; stroke: none; }
17
+ .shape.frame, .shape.image { fill: none; stroke-dasharray: 6 4; pointer-events: visiblePainted; }
18
+ .shape.sticky { fill: #ffe08a; stroke: #7a5b00; }
19
+ .label { fill: var(--ad-color-text); pointer-events: none; }
20
+ .sticky-label { fill: #1b1b1b; }
21
+ .edge { stroke: var(--ad-color-text-muted); stroke-width: 2; fill: none; pointer-events: none; }
22
+ .hit { stroke: transparent; stroke-width: 14; }
23
+ .arrowhead { fill: var(--ad-color-text-muted); }
24
+ .edge-text { fill: var(--ad-color-text); paint-order: stroke; stroke: var(--ad-color-surface-sunken); stroke-width: 4px; pointer-events: none; }
25
+ .ring, .ring-line { fill: none; stroke: none; stroke-width: 3; pointer-events: none; }
26
+ .item.selected .ring, .item.selected .ring-line, .item:focus-visible .ring, .item:focus-visible .ring-line { stroke: var(--ad-color-focus); }
27
+ .item:focus-visible .ring, .item:focus-visible .ring-line { stroke-width: 4; }
28
+ .handle { fill: var(--ad-color-focus); stroke: var(--ad-color-bg); stroke-width: 2; cursor: nwse-resize; }
29
+ .agent-badge rect { fill: var(--ad-color-agent-subtle); stroke: var(--ad-color-agent); }
30
+ .agent-badge text { fill: var(--ad-color-agent-text); font-size: 11px; font-weight: 600; pointer-events: none; }
31
+ .empty-overlay { position: absolute; inset: 0 16rem 0 0; display: grid; place-items: center; pointer-events: none; }
32
+ @media (max-width: 48rem) { .empty-overlay { inset: 0; bottom: auto; height: 55vh; } }
33
+ .inspector { border: 1px solid var(--ad-color-border); border-radius: var(--ad-radius-md); padding: var(--ad-space-3); background: var(--ad-color-surface); display: grid; gap: var(--ad-space-3); align-content: start; overflow: auto; }
34
+ .inspector h2 { margin: 0; font-size: var(--ad-font-size-lg); }
35
+ .inspector form { display: grid; gap: var(--ad-space-3); }
36
+ .inspector .by { margin: 0; color: var(--ad-color-text-muted); font-size: var(--ad-font-size-sm); }
37
+ .sizes { display: grid; grid-template-columns: 1fr 1fr; gap: var(--ad-space-2); }
38
+ }
package/dist/worker.d.ts CHANGED
@@ -2,8 +2,8 @@ import { Blobs } from 'agentic-identity';
2
2
  import { Realtime } from 'agentic-realtime';
3
3
  import { D1Like, R2Like } from 'agentic-identity/cloudflare';
4
4
  import { Hono } from 'hono';
5
- import { P as Principal } from './read-Bdg1uiFC.js';
6
- import { C as CanvasService } from './service-Cim7TWnJ.js';
5
+ import { P as Principal } from './read-BupIJSPJ.js';
6
+ import { C as CanvasService } from './service-CR4-r1yx.js';
7
7
  import 'yjs';
8
8
  import 'zod';
9
9
 
@@ -40,13 +40,13 @@ interface AppOptions {
40
40
  /** Makes the live-room server from the Worker bindings. Without it, the ws route answers 404. */
41
41
  live?: (env: WorkerEnv) => Realtime;
42
42
  }
43
- /** A browser cannot set a header on a WebSocket. It offers the token as the sub-protocols `agentic-canvas.bearer` and the token in base64url. */
44
- declare const WS_PROTOCOL = "agentic-canvas.bearer";
43
+ /** A browser cannot set a header on a WebSocket. It offers the sub-protocols `agentic-canvas` and `agentic-canvas.bearer.<token in base64url>`. */
44
+ declare const WS_PROTOCOL = "agentic-canvas";
45
45
  /** The principal and role for a bearer token, or null. The kind is never defaulted: a grant without a valid kind gets null. */
46
- declare function authenticate(request: Request, env: WorkerEnv): {
46
+ declare function authenticate(request: Request, env: WorkerEnv): Promise<{
47
47
  actor: Principal;
48
48
  role: Role;
49
- } | null;
49
+ } | null>;
50
50
  /** The image types we accept, found by their first bytes. The client's claim of a type is not trusted. */
51
51
  declare function sniffImage(bytes: Uint8Array): string | null;
52
52
  declare function createApp(options?: AppOptions): Hono<App>;
package/dist/worker.js CHANGED
@@ -4,10 +4,11 @@ import {
4
4
  createApp,
5
5
  sniffImage,
6
6
  worker_default
7
- } from "./chunk-HPUYT5TC.js";
8
- import "./chunk-J52RPFRP.js";
9
- import "./chunk-JZA525X5.js";
7
+ } from "./chunk-BIIC2DPZ.js";
8
+ import "./chunk-G4YTESPS.js";
10
9
  import "./chunk-NWQED42L.js";
10
+ import "./chunk-JCYNPYYJ.js";
11
+ import "./chunk-SPP6PINW.js";
11
12
  export {
12
13
  WS_PROTOCOL,
13
14
  authenticate,
package/llms.txt CHANGED
@@ -5,11 +5,13 @@ A shared whiteboard for diagrams, drawn by people and agents.
5
5
  Keywords: whiteboard,canvas,diagrams,drawing,collaboration,agents,mcp,cli.
6
6
 
7
7
  - SDK: import { Board, drawFlow, readBoard, toSvg } from "agentic-canvas".
8
+ - Exports: the README "Exports" section lists every name of each entry point: agentic-canvas, /client, /file-store, /live, /worker and /live-worker.
8
9
  - CLI: agentic-canvas new|list|read|add|connect|update|move|rm|flow|export.
9
10
  - UI: the Worker serves a web UI at its root (run `npm run build`, then `wrangler dev`). A person signs in with a bearer token.
10
11
  - Live: set CANVAS_SERVER and CANVAS_TOKEN, and the CLI and `agentic-canvas mcp` edit the board in its live room.
11
12
  - SDK: import { LiveBoard, LiveService } from "agentic-canvas/live".
12
13
  - SDK: import { createClient, CanvasApiError } from "agentic-canvas/client". It calls the Worker API with fetch. Methods: me, listBoards, createBoard, readBoard, exportSvg, addShape, addConnector, drawFlow, update, move, remove, uploadImage, getImage, state, checkpoint. A failure throws CanvasApiError with `code` and `status`. No retries.
14
+ - UI: import { mount } from "agentic-canvas/ui"; import "agentic-canvas/ui.css" (with agentic-design/styles.css). mount(element, { boardId, client, principal: { kind, name, role }, readOnly?, room?: { baseUrl, token } }) renders the board and returns { update(options), unmount() }. BoardEditor is the same as a React component. React 19 is a peer dependency.
13
15
 
14
16
  ## Docs
15
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-canvas",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "A shared whiteboard for diagrams, drawn by people and agents.",
5
5
  "keywords": [
6
6
  "whiteboard",
@@ -58,13 +58,18 @@
58
58
  "./file-store": {
59
59
  "types": "./dist/store-file.d.ts",
60
60
  "import": "./dist/store-file.js"
61
- }
61
+ },
62
+ "./ui": {
63
+ "types": "./dist/embed.d.ts",
64
+ "import": "./dist/embed.js"
65
+ },
66
+ "./ui.css": "./dist/ui.css"
62
67
  },
63
68
  "bin": {
64
69
  "agentic-canvas": "./dist/cli.js"
65
70
  },
66
71
  "scripts": {
67
- "build": "tsup && vite build",
72
+ "build": "tsup && vite build && node ui/build-css.mjs",
68
73
  "typecheck": "tsc --noEmit && tsc --noEmit -p ui",
69
74
  "test": "vitest run",
70
75
  "clean": "rm -rf dist",
@@ -75,28 +80,38 @@
75
80
  "dependencies": {
76
81
  "@dagrejs/dagre": "^3.1.3",
77
82
  "@modelcontextprotocol/sdk": "^1.12.0",
78
- "agentic-identity": "^0.5.0",
83
+ "agentic-design": "^0.2.0",
84
+ "agentic-identity": "^0.6.0",
79
85
  "agentic-realtime": "^0.3.0",
80
86
  "yjs": "^13.6.0",
81
87
  "zod": "^3.25.0"
82
88
  },
83
89
  "peerDependencies": {
84
- "playwright-core": ">=1.40.0"
90
+ "playwright-core": ">=1.40.0",
91
+ "react": ">=19",
92
+ "react-dom": ">=19"
85
93
  },
86
94
  "peerDependenciesMeta": {
87
95
  "playwright-core": {
88
96
  "optional": true
97
+ },
98
+ "react": {
99
+ "optional": true
100
+ },
101
+ "react-dom": {
102
+ "optional": true
89
103
  }
90
104
  },
91
105
  "devDependencies": {
92
106
  "@axe-core/playwright": "^4.14.0",
93
107
  "@playwright/test": "^1.64.1",
108
+ "@types/jsdom": "^21.1.7",
94
109
  "@types/node": "^22.0.0",
95
110
  "@types/react": "^19.3.0",
96
111
  "@types/react-dom": "^19.3.0",
97
112
  "@vitejs/plugin-react": "^5.2.0",
98
- "agentic-design": "^0.2.0",
99
113
  "hono": "^4.13.14",
114
+ "jsdom": "^26.0.0",
100
115
  "miniflare": "^4.20260730.0",
101
116
  "playwright-core": "^1.64.1",
102
117
  "react": "^19.3.1",