pmx-canvas 0.1.26 → 0.1.28

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 (64) hide show
  1. package/.github/extensions/pmx-canvas/extension.mjs +191 -0
  2. package/CHANGELOG.md +110 -0
  3. package/Readme.md +74 -27
  4. package/dist/canvas/index.js +82 -82
  5. package/dist/json-render/index.css +1 -1
  6. package/dist/json-render/index.js +944 -164
  7. package/dist/types/json-render/catalog.d.ts +195 -20
  8. package/dist/types/json-render/charts/components.d.ts +17 -0
  9. package/dist/types/json-render/charts/definitions.d.ts +13 -1
  10. package/dist/types/json-render/charts/tufte-components.d.ts +65 -0
  11. package/dist/types/json-render/charts/tufte-definitions.d.ts +164 -0
  12. package/dist/types/json-render/directives.d.ts +33 -0
  13. package/dist/types/json-render/renderer/index.d.ts +1 -0
  14. package/dist/types/json-render/server.d.ts +32 -1
  15. package/dist/types/mcp/canvas-access.d.ts +62 -0
  16. package/dist/types/server/ax-state.d.ts +170 -0
  17. package/dist/types/server/canvas-db.d.ts +17 -1
  18. package/dist/types/server/canvas-operations.d.ts +53 -0
  19. package/dist/types/server/canvas-schema.d.ts +5 -1
  20. package/dist/types/server/canvas-state.d.ts +95 -4
  21. package/dist/types/server/index.d.ts +120 -3
  22. package/dist/types/server/mutation-history.d.ts +1 -1
  23. package/docs/cli.md +42 -0
  24. package/docs/http-api.md +64 -0
  25. package/docs/mcp.md +23 -5
  26. package/docs/node-types.md +1 -1
  27. package/docs/screenshots/codex-app.png +0 -0
  28. package/docs/screenshots/github-copilot-app.png +0 -0
  29. package/docs/sdk.md +23 -5
  30. package/package.json +10 -7
  31. package/skills/control-session-orchestrator/SKILL.md +359 -0
  32. package/skills/control-session-orchestrator/evals/evals.json +75 -0
  33. package/skills/data-analysis/SKILL.md +6 -0
  34. package/skills/pmx-canvas/SKILL.md +50 -4
  35. package/skills/pmx-canvas/references/github-copilot-app-adapter.md +6 -0
  36. package/skills/tufte-viz/SKILL.md +157 -0
  37. package/skills/tufte-viz/references/analytical-design.md +217 -0
  38. package/skills/tufte-viz/references/tufte-principles.md +147 -0
  39. package/src/cli/agent.ts +302 -3
  40. package/src/cli/index.ts +2 -1
  41. package/src/client/nodes/ExtAppFrame.tsx +48 -1
  42. package/src/client/nodes/McpAppNode.tsx +6 -2
  43. package/src/json-render/catalog.ts +22 -1
  44. package/src/json-render/charts/components.tsx +127 -15
  45. package/src/json-render/charts/definitions.ts +19 -2
  46. package/src/json-render/charts/extra-components.tsx +5 -4
  47. package/src/json-render/charts/tufte-components.tsx +395 -0
  48. package/src/json-render/charts/tufte-definitions.ts +128 -0
  49. package/src/json-render/directives.ts +64 -0
  50. package/src/json-render/renderer/index.css +107 -1
  51. package/src/json-render/renderer/index.tsx +33 -0
  52. package/src/json-render/server.ts +275 -5
  53. package/src/mcp/canvas-access.ts +264 -1
  54. package/src/mcp/server.ts +498 -9
  55. package/src/server/ax-context.ts +8 -3
  56. package/src/server/ax-state.ts +447 -0
  57. package/src/server/canvas-db.ts +184 -1
  58. package/src/server/canvas-operations.ts +123 -2
  59. package/src/server/canvas-schema.ts +27 -3
  60. package/src/server/canvas-state.ts +349 -2
  61. package/src/server/index.ts +259 -7
  62. package/src/server/mutation-history.ts +6 -0
  63. package/src/server/server.ts +442 -5
  64. package/src/server/web-artifacts.ts +31 -5
@@ -28,8 +28,23 @@ export interface GraphNodeInput {
28
28
  lineKey?: string;
29
29
  aggregate?: 'sum' | 'count' | 'avg';
30
30
  color?: string;
31
+ colorBy?: 'series' | 'category' | 'value' | 'none';
32
+ highlight?: number | 'max' | 'min' | null;
31
33
  barColor?: string;
32
34
  lineColor?: string;
35
+ labelKey?: string;
36
+ beforeKey?: string;
37
+ afterKey?: string;
38
+ beforeLabel?: string;
39
+ afterLabel?: string;
40
+ targetKey?: string;
41
+ rangesKey?: string;
42
+ sort?: 'asc' | 'desc' | 'none';
43
+ fill?: boolean;
44
+ showEndDot?: boolean;
45
+ showMinMax?: boolean;
46
+ showValue?: boolean;
47
+ colorByDirection?: boolean;
33
48
  height?: number;
34
49
  showLegend?: boolean;
35
50
  showLabels?: boolean;
@@ -47,16 +62,32 @@ export declare const GRAPH_NODE_SIZE: {
47
62
  width: number;
48
63
  height: number;
49
64
  };
50
- export type GraphChartType = 'LineChart' | 'BarChart' | 'PieChart' | 'AreaChart' | 'ScatterChart' | 'RadarChart' | 'StackedBarChart' | 'ComposedChart';
65
+ export type GraphChartType = 'LineChart' | 'BarChart' | 'PieChart' | 'AreaChart' | 'ScatterChart' | 'RadarChart' | 'StackedBarChart' | 'ComposedChart' | 'Sparkline' | 'DotPlot' | 'BulletChart' | 'Slopegraph';
51
66
  export declare function inferJsonRenderNodeTitle(spec: JsonRenderSpec, fallback?: string): string;
52
67
  export declare function normalizeAndValidateJsonRenderSpec(spec: unknown): JsonRenderSpec;
53
68
  export declare function normalizeGraphType(value: string): GraphChartType;
54
69
  export declare function buildGraphSpec(input: GraphNodeInput): JsonRenderSpec;
55
70
  export declare function buildGraphConfig(input: GraphNodeInput): Record<string, unknown>;
71
+ /** The minimal spec a streaming json-render node starts from before any patches. */
72
+ export declare function emptyStreamingSpec(): JsonRenderSpec;
73
+ /**
74
+ * Apply a batch of SpecStream patches to the current spec, accumulating the
75
+ * result. The canvas is the source of truth — patches are applied server-side
76
+ * and the browser only renders the current accumulated spec, so there is no
77
+ * client-side reconciliation. Tolerant by design: malformed or inapplicable
78
+ * patches are skipped and counted, never thrown, so a partial stream keeps
79
+ * building toward the final spec.
80
+ */
81
+ export declare function applyJsonRenderStreamPatches(currentSpec: JsonRenderSpec, items: unknown[]): {
82
+ spec: JsonRenderSpec;
83
+ applied: number;
84
+ skipped: number;
85
+ };
56
86
  export declare function createJsonRenderNodeData(nodeId: string, title: string, spec: JsonRenderSpec, extra?: Record<string, unknown>): Record<string, unknown>;
57
87
  export declare function buildJsonRenderViewerHtml(options: {
58
88
  title: string;
59
89
  spec: JsonRenderSpec;
60
90
  theme?: 'dark' | 'light' | 'high-contrast';
61
91
  display?: 'expanded';
92
+ devtools?: boolean;
62
93
  }): Promise<string>;
@@ -8,6 +8,8 @@ type OpenMcpAppResult = Awaited<ReturnType<PmxCanvas['openMcpApp']>>;
8
8
  type AddDiagramInput = Parameters<PmxCanvas['addDiagram']>[0];
9
9
  type AddJsonRenderNodeInput = Parameters<PmxCanvas['addJsonRenderNode']>[0];
10
10
  type AddJsonRenderNodeResult = ReturnType<PmxCanvas['addJsonRenderNode']>;
11
+ type StreamJsonRenderNodeInput = Parameters<PmxCanvas['streamJsonRenderNode']>[0];
12
+ type StreamJsonRenderNodeResult = ReturnType<PmxCanvas['streamJsonRenderNode']>;
11
13
  type AddHtmlNodeInput = Parameters<PmxCanvas['addHtmlNode']>[0];
12
14
  type AddHtmlPrimitiveInput = Parameters<PmxCanvas['addHtmlPrimitive']>[0];
13
15
  type AddHtmlPrimitiveResult = ReturnType<PmxCanvas['addHtmlPrimitive']>;
@@ -24,6 +26,29 @@ type FitViewResult = ReturnType<PmxCanvas['fitView']>;
24
26
  type AxStateResult = ReturnType<PmxCanvas['getAxState']>;
25
27
  type AxContextResult = ReturnType<PmxCanvas['getAxContext']>;
26
28
  type SetAxFocusResult = ReturnType<PmxCanvas['setAxFocus']>;
29
+ type RecordAxEventInput = Parameters<PmxCanvas['recordAxEvent']>[0];
30
+ type RecordAxEventResult = ReturnType<PmxCanvas['recordAxEvent']>;
31
+ type SendSteeringResult = ReturnType<PmxCanvas['sendSteering']>;
32
+ type GetAxTimelineQuery = Parameters<PmxCanvas['getAxTimeline']>[0];
33
+ type GetAxTimelineResult = ReturnType<PmxCanvas['getAxTimeline']>;
34
+ type AddWorkItemInput = Parameters<PmxCanvas['addWorkItem']>[0];
35
+ type AddWorkItemResult = ReturnType<PmxCanvas['addWorkItem']>;
36
+ type UpdateWorkItemPatch = Parameters<PmxCanvas['updateWorkItem']>[1];
37
+ type UpdateWorkItemResult = ReturnType<PmxCanvas['updateWorkItem']>;
38
+ type ListWorkItemsResult = ReturnType<PmxCanvas['listWorkItems']>;
39
+ type RequestApprovalInput = Parameters<PmxCanvas['requestApproval']>[0];
40
+ type RequestApprovalResult = ReturnType<PmxCanvas['requestApproval']>;
41
+ type ResolveApprovalResult = ReturnType<PmxCanvas['resolveApproval']>;
42
+ type ListApprovalGatesResult = ReturnType<PmxCanvas['listApprovalGates']>;
43
+ type AddEvidenceInput = Parameters<PmxCanvas['addEvidence']>[0];
44
+ type AddEvidenceResult = ReturnType<PmxCanvas['addEvidence']>;
45
+ type AddReviewAnnotationInput = Parameters<PmxCanvas['addReviewAnnotation']>[0];
46
+ type AddReviewAnnotationResult = ReturnType<PmxCanvas['addReviewAnnotation']>;
47
+ type UpdateReviewAnnotationPatch = Parameters<PmxCanvas['updateReviewAnnotation']>[1];
48
+ type UpdateReviewAnnotationResult = ReturnType<PmxCanvas['updateReviewAnnotation']>;
49
+ type ListReviewAnnotationsResult = ReturnType<PmxCanvas['listReviewAnnotations']>;
50
+ type GetHostCapabilityResult = ReturnType<PmxCanvas['getHostCapability']>;
51
+ type ReportHostCapabilityResult = ReturnType<PmxCanvas['reportHostCapability']>;
27
52
  type SearchResult = ReturnType<PmxCanvas['search']>;
28
53
  type UndoRedoResult = Awaited<ReturnType<PmxCanvas['undo']>>;
29
54
  type HistoryResult = ReturnType<PmxCanvas['getHistory']>;
@@ -55,6 +80,7 @@ export interface CanvasAccess {
55
80
  openMcpApp(input: OpenMcpAppInput): Promise<OpenMcpAppResult>;
56
81
  addDiagram(input: AddDiagramInput): Promise<OpenMcpAppResult>;
57
82
  addJsonRenderNode(input: AddJsonRenderNodeInput): Promise<AddJsonRenderNodeResult>;
83
+ streamJsonRenderNode(input: StreamJsonRenderNodeInput): Promise<StreamJsonRenderNodeResult>;
58
84
  addHtmlNode(input: AddHtmlNodeInput): Promise<string>;
59
85
  addHtmlPrimitive(input: AddHtmlPrimitiveInput): Promise<AddHtmlPrimitiveResult>;
60
86
  addGraphNode(input: AddGraphNodeInput): Promise<AddGraphNodeResult>;
@@ -77,6 +103,42 @@ export interface CanvasAccess {
77
103
  setAxFocus(nodeIds: string[], options?: {
78
104
  source?: PmxAxSource;
79
105
  }): Promise<SetAxFocusResult>;
106
+ recordAxEvent(input: RecordAxEventInput, options?: {
107
+ source?: PmxAxSource;
108
+ }): Promise<RecordAxEventResult>;
109
+ sendSteering(message: string, options?: {
110
+ source?: PmxAxSource;
111
+ }): Promise<SendSteeringResult>;
112
+ getAxTimeline(query?: GetAxTimelineQuery): Promise<GetAxTimelineResult>;
113
+ addWorkItem(input: AddWorkItemInput, options?: {
114
+ source?: PmxAxSource;
115
+ }): Promise<AddWorkItemResult>;
116
+ updateWorkItem(id: string, patch: UpdateWorkItemPatch, options?: {
117
+ source?: PmxAxSource;
118
+ }): Promise<UpdateWorkItemResult>;
119
+ listWorkItems(): Promise<ListWorkItemsResult>;
120
+ requestApproval(input: RequestApprovalInput, options?: {
121
+ source?: PmxAxSource;
122
+ }): Promise<RequestApprovalResult>;
123
+ resolveApproval(id: string, decision: 'approved' | 'rejected', options?: {
124
+ resolution?: string;
125
+ source?: PmxAxSource;
126
+ }): Promise<ResolveApprovalResult>;
127
+ listApprovalGates(): Promise<ListApprovalGatesResult>;
128
+ addEvidence(input: AddEvidenceInput, options?: {
129
+ source?: PmxAxSource;
130
+ }): Promise<AddEvidenceResult>;
131
+ addReviewAnnotation(input: AddReviewAnnotationInput, options?: {
132
+ source?: PmxAxSource;
133
+ }): Promise<AddReviewAnnotationResult>;
134
+ updateReviewAnnotation(id: string, patch: UpdateReviewAnnotationPatch, options?: {
135
+ source?: PmxAxSource;
136
+ }): Promise<UpdateReviewAnnotationResult>;
137
+ listReviewAnnotations(): Promise<ListReviewAnnotationsResult>;
138
+ getHostCapability(): Promise<GetHostCapabilityResult>;
139
+ reportHostCapability(input: unknown, options?: {
140
+ source?: PmxAxSource;
141
+ }): Promise<ReportHostCapabilityResult>;
80
142
  clear(): Promise<void>;
81
143
  search(query: string): Promise<SearchResult>;
82
144
  undo(): Promise<UndoRedoResult>;
@@ -7,9 +7,121 @@ export interface PmxAxFocusState {
7
7
  updatedAt: string | null;
8
8
  source: PmxAxSource | null;
9
9
  }
10
+ export type PmxAxEventKind = 'prompt' | 'assistant-message' | 'tool-start' | 'tool-result' | 'failure' | 'approval' | 'steering';
11
+ export type PmxAxEvidenceKind = 'logs' | 'tool-result' | 'screenshot' | 'file' | 'diff' | 'test-output';
12
+ export type PmxAxWorkItemStatus = 'todo' | 'in-progress' | 'blocked' | 'done' | 'cancelled';
13
+ export type PmxAxApprovalStatus = 'pending' | 'approved' | 'rejected';
14
+ export type PmxAxReviewKind = 'comment' | 'finding';
15
+ export type PmxAxReviewSeverity = 'info' | 'warning' | 'error';
16
+ export type PmxAxReviewStatus = 'open' | 'resolved' | 'dismissed';
17
+ export type PmxAxReviewAnchorType = 'node' | 'file' | 'region';
18
+ export interface PmxAxWorkItem {
19
+ id: string;
20
+ title: string;
21
+ status: PmxAxWorkItemStatus;
22
+ detail: string | null;
23
+ nodeIds: string[];
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ source: PmxAxSource | null;
27
+ }
28
+ export interface PmxAxApprovalGate {
29
+ id: string;
30
+ title: string;
31
+ detail: string | null;
32
+ action: string | null;
33
+ status: PmxAxApprovalStatus;
34
+ nodeIds: string[];
35
+ createdAt: string;
36
+ resolvedAt: string | null;
37
+ resolution: string | null;
38
+ source: PmxAxSource | null;
39
+ }
40
+ export interface PmxAxReviewRegion {
41
+ line?: number;
42
+ endLine?: number;
43
+ label?: string;
44
+ }
45
+ export interface PmxAxReviewAnnotation {
46
+ id: string;
47
+ kind: PmxAxReviewKind;
48
+ body: string;
49
+ severity: PmxAxReviewSeverity;
50
+ status: PmxAxReviewStatus;
51
+ anchorType: PmxAxReviewAnchorType;
52
+ nodeId: string | null;
53
+ file: string | null;
54
+ region: PmxAxReviewRegion | null;
55
+ author: string | null;
56
+ createdAt: string;
57
+ updatedAt: string;
58
+ source: PmxAxSource | null;
59
+ }
60
+ export interface PmxAxEvent {
61
+ id: string;
62
+ seq: number;
63
+ kind: PmxAxEventKind;
64
+ summary: string;
65
+ detail: string | null;
66
+ nodeIds: string[];
67
+ data: Record<string, unknown> | null;
68
+ createdAt: string;
69
+ source: PmxAxSource | null;
70
+ }
71
+ export interface PmxAxEvidence {
72
+ id: string;
73
+ seq: number;
74
+ kind: PmxAxEvidenceKind;
75
+ title: string;
76
+ body: string | null;
77
+ ref: string | null;
78
+ nodeIds: string[];
79
+ data: Record<string, unknown> | null;
80
+ createdAt: string;
81
+ source: PmxAxSource | null;
82
+ }
83
+ export interface PmxAxSteeringMessage {
84
+ id: string;
85
+ seq: number;
86
+ message: string;
87
+ delivered: boolean;
88
+ createdAt: string;
89
+ source: PmxAxSource | null;
90
+ }
91
+ export interface PmxAxHostCapability {
92
+ host: string | null;
93
+ canvas: boolean;
94
+ hooks: boolean;
95
+ tools: boolean;
96
+ sessionMessaging: boolean;
97
+ permissions: boolean;
98
+ files: boolean;
99
+ uiPrompts: boolean;
100
+ reportedAt: string | null;
101
+ raw: Record<string, unknown> | null;
102
+ }
103
+ export interface PmxAxTimelineSummary {
104
+ recentEvents: PmxAxEvent[];
105
+ recentEvidence: PmxAxEvidence[];
106
+ pendingSteering: PmxAxSteeringMessage[];
107
+ counts: {
108
+ events: number;
109
+ evidence: number;
110
+ steering: number;
111
+ };
112
+ }
113
+ export declare const AX_TIMELINE_RETENTION = 500;
114
+ export declare const AX_TIMELINE_DEFAULT_LIMIT = 50;
115
+ export declare const AX_TIMELINE_MAX_LIMIT = 200;
116
+ export declare const AX_CONTEXT_EVENT_LIMIT = 20;
117
+ export declare const AX_CONTEXT_EVIDENCE_LIMIT = 10;
118
+ export declare const AX_CONTEXT_STEERING_LIMIT = 10;
10
119
  export interface PmxAxState {
11
120
  version: 1;
12
121
  focus: PmxAxFocusState;
122
+ workItems: PmxAxWorkItem[];
123
+ approvalGates: PmxAxApprovalGate[];
124
+ reviewAnnotations: PmxAxReviewAnnotation[];
13
125
  }
14
126
  export interface PmxAxPinnedContext {
15
127
  preamble: string;
@@ -29,15 +141,73 @@ export interface PmxAxContext {
29
141
  };
30
142
  pinned: PmxAxPinnedContext;
31
143
  focus: PmxAxFocusContext;
144
+ workItems: PmxAxWorkItem[];
145
+ approvalGates: PmxAxApprovalGate[];
146
+ reviewAnnotations: PmxAxReviewAnnotation[];
147
+ timeline: PmxAxTimelineSummary;
148
+ host: PmxAxHostCapability | null;
32
149
  }
150
+ export declare function isAxEventKind(value: unknown): value is PmxAxEventKind;
151
+ export declare function isAxEvidenceKind(value: unknown): value is PmxAxEvidenceKind;
33
152
  export declare function createEmptyAxFocusState(): PmxAxFocusState;
34
153
  export declare function createEmptyAxState(): PmxAxState;
154
+ export declare function createEmptyAxHostCapability(): PmxAxHostCapability;
35
155
  export declare function normalizeAxFocusState(input: unknown, validNodeIds?: Set<string>): PmxAxFocusState;
156
+ export declare function normalizeAxWorkItem(input: unknown, validNodeIds?: Set<string>): PmxAxWorkItem | null;
157
+ export declare function normalizeAxApprovalGate(input: unknown, validNodeIds?: Set<string>): PmxAxApprovalGate | null;
158
+ export declare function normalizeAxReviewAnnotation(input: unknown, validNodeIds?: Set<string>): PmxAxReviewAnnotation | null;
159
+ export declare function normalizeAxHostCapability(input: unknown): PmxAxHostCapability | null;
160
+ export declare function normalizeAxEvent(input: unknown): PmxAxEvent | null;
161
+ export declare function normalizeAxEvidence(input: unknown): PmxAxEvidence | null;
162
+ export declare function normalizeAxSteeringMessage(input: unknown): PmxAxSteeringMessage | null;
163
+ export declare function createAxWorkItem(input: {
164
+ title: string;
165
+ status?: PmxAxWorkItemStatus;
166
+ detail?: string | null;
167
+ nodeIds?: string[];
168
+ }, source: PmxAxSource | null, validNodeIds?: Set<string>): PmxAxWorkItem;
169
+ export declare function createAxApprovalGate(input: {
170
+ title: string;
171
+ detail?: string | null;
172
+ action?: string | null;
173
+ nodeIds?: string[];
174
+ }, source: PmxAxSource | null, validNodeIds?: Set<string>): PmxAxApprovalGate;
175
+ export declare function createAxReviewAnnotation(input: {
176
+ body: string;
177
+ kind?: PmxAxReviewKind;
178
+ severity?: PmxAxReviewSeverity;
179
+ anchorType?: PmxAxReviewAnchorType;
180
+ nodeId?: string | null;
181
+ file?: string | null;
182
+ region?: PmxAxReviewRegion | null;
183
+ author?: string | null;
184
+ }, source: PmxAxSource | null): PmxAxReviewAnnotation;
185
+ export declare function createAxEvent(input: {
186
+ kind: PmxAxEventKind;
187
+ summary: string;
188
+ detail?: string | null;
189
+ nodeIds?: string[];
190
+ data?: Record<string, unknown> | null;
191
+ }, source: PmxAxSource | null): Omit<PmxAxEvent, 'seq'>;
192
+ export declare function createAxEvidence(input: {
193
+ kind: PmxAxEvidenceKind;
194
+ title: string;
195
+ body?: string | null;
196
+ ref?: string | null;
197
+ nodeIds?: string[];
198
+ data?: Record<string, unknown> | null;
199
+ }, source: PmxAxSource | null): Omit<PmxAxEvidence, 'seq'>;
200
+ export declare function createAxSteeringMessage(message: string, source: PmxAxSource | null): Omit<PmxAxSteeringMessage, 'seq'>;
36
201
  export declare function normalizeAxState(input: unknown, validNodeIds?: Set<string>): PmxAxState;
37
202
  export declare function buildAxContext(input: {
38
203
  layout: CanvasLayout;
39
204
  pinned: PmxAxPinnedContext;
40
205
  focus: PmxAxFocusState;
41
206
  focusNodes: AgentContextNode[];
207
+ workItems: PmxAxWorkItem[];
208
+ approvalGates: PmxAxApprovalGate[];
209
+ reviewAnnotations: PmxAxReviewAnnotation[];
210
+ timeline: PmxAxTimelineSummary;
211
+ host: PmxAxHostCapability | null;
42
212
  }): PmxAxContext;
43
213
  export declare function nodeSetFromLayout(nodes: CanvasNodeState[]): Set<string>;
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { Database } from 'bun:sqlite';
8
8
  import type { CanvasAnnotation, CanvasEdge, CanvasNodeState, CanvasSnapshot, CanvasSnapshotListOptions, ViewportState } from './canvas-state.js';
9
- import { type PmxAxState } from './ax-state.js';
9
+ import { type PmxAxState, type PmxAxEvent, type PmxAxEvidence, type PmxAxSteeringMessage, type PmxAxHostCapability, type PmxAxTimelineSummary } from './ax-state.js';
10
10
  export type CanvasTheme = 'dark' | 'light' | 'high-contrast';
11
11
  export declare function normalizeCanvasTheme(value: unknown, fallback?: CanvasTheme): CanvasTheme;
12
12
  export interface PersistedCanvasState {
@@ -36,3 +36,19 @@ export declare function deleteSnapshotFromDB(db: Database, id: string): boolean;
36
36
  export declare function writeBlobToDB(db: Database, sha256: string, jsonValue: string): number;
37
37
  export declare function readBlobFromDB(db: Database, sha256: string): string | null;
38
38
  export declare function hasBlobInDB(db: Database, sha256: string): boolean;
39
+ export interface AxTimelineQuery {
40
+ limit?: number;
41
+ sessionId?: string;
42
+ }
43
+ export declare function appendAxEventToDB(db: Database, ev: Omit<PmxAxEvent, 'seq'>): PmxAxEvent;
44
+ export declare function appendAxEvidenceToDB(db: Database, ev: Omit<PmxAxEvidence, 'seq'>): PmxAxEvidence;
45
+ export declare function appendAxSteeringToDB(db: Database, s: Omit<PmxAxSteeringMessage, 'seq'>): PmxAxSteeringMessage;
46
+ export declare function markAxSteeringDeliveredInDB(db: Database, id: string): boolean;
47
+ export declare function loadAxEventsFromDB(db: Database, q?: AxTimelineQuery): PmxAxEvent[];
48
+ export declare function loadAxEvidenceFromDB(db: Database, q?: AxTimelineQuery): PmxAxEvidence[];
49
+ export declare function loadAxSteeringFromDB(db: Database, q?: AxTimelineQuery & {
50
+ onlyPending?: boolean;
51
+ }): PmxAxSteeringMessage[];
52
+ export declare function loadAxTimelineSummaryFromDB(db: Database): PmxAxTimelineSummary;
53
+ export declare function upsertAxHostCapabilityToDB(db: Database, cap: PmxAxHostCapability): void;
54
+ export declare function loadAxHostCapabilityFromDB(db: Database): PmxAxHostCapability | null;
@@ -64,6 +64,14 @@ export declare const MCP_APP_NODE_DEFAULT_SIZE: {
64
64
  width: number;
65
65
  height: number;
66
66
  };
67
+ export declare const IMAGE_NODE_DEFAULT_SIZE: {
68
+ width: number;
69
+ height: number;
70
+ };
71
+ export declare const LEDGER_NODE_DEFAULT_SIZE: {
72
+ width: number;
73
+ height: number;
74
+ };
67
75
  interface CanvasCreateGroupInput {
68
76
  title?: string;
69
77
  childIds?: string[];
@@ -124,6 +132,18 @@ export declare function validateCanvasNodePatch(patch: {
124
132
  export declare function mergeTraceNodeDataFields(base: Record<string, unknown>, input: Record<string, unknown>): Record<string, unknown>;
125
133
  export declare function hasTraceNodeDataFields(input: Record<string, unknown>): boolean;
126
134
  export declare function scheduleCodeGraphRecompute(onComplete?: () => void): void;
135
+ /**
136
+ * Resolve an html-node `html` field that may be a path to a local .html/.htm file.
137
+ *
138
+ * If the string looks like a bare filesystem path to an existing HTML file
139
+ * (no markup, no newlines, short, ends in .html/.htm, exists on disk), read the
140
+ * file and return its contents. Otherwise return the string unchanged as raw HTML.
141
+ * On read failure, fall back to the raw string and warn — never throw.
142
+ *
143
+ * This is a local dev tool, so reading a user-pointed-at local file is acceptable;
144
+ * the markup/newline guards prevent misclassifying genuine HTML as a path.
145
+ */
146
+ export declare function resolveHtmlContent(html: string): string;
127
147
  export declare function addCanvasNode(input: CanvasAddNodeInput): {
128
148
  id: string;
129
149
  node: CanvasNodeState;
@@ -206,6 +226,39 @@ export declare function createCanvasJsonRenderNode(input: JsonRenderNodeInput):
206
226
  spec: JsonRenderSpec;
207
227
  node: CanvasNodeState;
208
228
  };
229
+ /**
230
+ * Create an empty streaming json-render node. Unlike createCanvasJsonRenderNode
231
+ * this does NOT validate a complete spec — the node starts blank and is filled
232
+ * in by appendCanvasJsonRenderStream as SpecStream patches arrive.
233
+ */
234
+ export declare function createCanvasStreamingJsonRenderNode(input: {
235
+ title?: string;
236
+ x?: number;
237
+ y?: number;
238
+ width?: number;
239
+ height?: number;
240
+ strictSize?: boolean;
241
+ }): {
242
+ id: string;
243
+ url: string;
244
+ spec: JsonRenderSpec;
245
+ node: CanvasNodeState;
246
+ };
247
+ /**
248
+ * Apply a batch of SpecStream patches to an existing json-render node, bumping
249
+ * its specVersion so the browser reloads the viewer with the accumulated spec.
250
+ */
251
+ export declare function appendCanvasJsonRenderStream(nodeId: string, patches: unknown[], done: boolean): {
252
+ ok: true;
253
+ applied: number;
254
+ skipped: number;
255
+ specVersion: number;
256
+ elementCount: number;
257
+ streamStatus: 'open' | 'closed';
258
+ } | {
259
+ ok: false;
260
+ error: string;
261
+ };
209
262
  export declare function createCanvasGraphNode(input: GraphNodeInput): {
210
263
  id: string;
211
264
  url: string;
@@ -33,7 +33,7 @@ export interface StructuredValidationResult {
33
33
  };
34
34
  summary: Record<string, unknown>;
35
35
  }
36
- declare const CANONICAL_GRAPH_TYPES: readonly ["line", "bar", "pie", "area", "scatter", "radar", "stacked-bar", "composed"];
36
+ declare const CANONICAL_GRAPH_TYPES: readonly ["line", "bar", "pie", "area", "scatter", "radar", "stacked-bar", "composed", "sparkline", "dot-plot", "bullet", "slopegraph"];
37
37
  type CanvasGraphType = typeof CANONICAL_GRAPH_TYPES[number];
38
38
  export declare function describeCanvasSchema(): {
39
39
  ok: true;
@@ -43,6 +43,10 @@ export declare function describeCanvasSchema(): {
43
43
  jsonRender: {
44
44
  rootShape: Record<string, string>;
45
45
  components: JsonRenderComponentDescriptor[];
46
+ directives: Array<{
47
+ name: string;
48
+ usage: string;
49
+ }>;
46
50
  };
47
51
  graph: {
48
52
  graphTypes: CanvasGraphType[];
@@ -9,8 +9,8 @@
9
9
  * in the workspace root on every mutation (debounced). Auto-loads on `loadFromDisk()`.
10
10
  * Legacy `.pmx-canvas/state.json` is auto-migrated on first boot.
11
11
  */
12
- import { type PersistedCanvasState, type CanvasTheme } from './canvas-db.js';
13
- import { type PmxAxFocusState, type PmxAxSource, type PmxAxState } from './ax-state.js';
12
+ import { type PersistedCanvasState, type CanvasTheme, type AxTimelineQuery } from './canvas-db.js';
13
+ import { type PmxAxFocusState, type PmxAxSource, type PmxAxState, type PmxAxWorkItem, type PmxAxWorkItemStatus, type PmxAxApprovalGate, type PmxAxReviewAnnotation, type PmxAxReviewKind, type PmxAxReviewSeverity, type PmxAxReviewStatus, type PmxAxReviewAnchorType, type PmxAxReviewRegion, type PmxAxEvent, type PmxAxEventKind, type PmxAxEvidence, type PmxAxEvidenceKind, type PmxAxSteeringMessage, type PmxAxHostCapability, type PmxAxTimelineSummary } from './ax-state.js';
14
14
  export declare const PMX_CANVAS_DIR = ".pmx-canvas";
15
15
  export interface PersistedBlobRef {
16
16
  __pmxCanvasBlob: 'v1';
@@ -120,9 +120,9 @@ export interface CanvasNodeUpdate {
120
120
  collapsed?: boolean;
121
121
  dockPosition?: 'left' | 'right' | null;
122
122
  }
123
- export type CanvasChangeType = 'pins' | 'nodes' | 'ax';
123
+ export type CanvasChangeType = 'pins' | 'nodes' | 'ax' | 'ax-timeline';
124
124
  export interface MutationRecordInfo {
125
- operationType: 'addNode' | 'updateNode' | 'removeNode' | 'addEdge' | 'removeEdge' | 'addAnnotation' | 'removeAnnotation' | 'clear' | 'restoreSnapshot' | 'setPins' | 'setAxFocus' | 'arrange' | 'batch' | 'groupNodes' | 'ungroupNodes' | 'viewport';
125
+ operationType: 'addNode' | 'updateNode' | 'removeNode' | 'addEdge' | 'removeEdge' | 'addAnnotation' | 'removeAnnotation' | 'clear' | 'restoreSnapshot' | 'setPins' | 'setAxFocus' | 'addWorkItem' | 'updateWorkItem' | 'requestApproval' | 'resolveApproval' | 'addReviewAnnotation' | 'updateReviewAnnotation' | 'arrange' | 'batch' | 'groupNodes' | 'ungroupNodes' | 'viewport';
126
126
  description: string;
127
127
  forward: () => void;
128
128
  inverse: () => void;
@@ -143,6 +143,7 @@ declare class CanvasStateManager {
143
143
  private _theme;
144
144
  private _contextPinnedNodeIds;
145
145
  private _axState;
146
+ private _axHostCapability;
146
147
  private _workspaceRoot;
147
148
  private _changeListeners;
148
149
  /** Register a listener for state changes. Used by MCP server to emit resource notifications. */
@@ -263,6 +264,96 @@ declare class CanvasStateManager {
263
264
  recordHistory?: boolean;
264
265
  }): PmxAxFocusState;
265
266
  clearAxFocus(): PmxAxFocusState;
267
+ getWorkItems(): PmxAxWorkItem[];
268
+ addWorkItem(input: {
269
+ title: string;
270
+ status?: PmxAxWorkItemStatus;
271
+ detail?: string | null;
272
+ nodeIds?: string[];
273
+ }, options?: {
274
+ source?: PmxAxSource;
275
+ }): PmxAxWorkItem;
276
+ updateWorkItem(id: string, patch: {
277
+ title?: string;
278
+ status?: PmxAxWorkItemStatus;
279
+ detail?: string | null;
280
+ nodeIds?: string[];
281
+ }, options?: {
282
+ source?: PmxAxSource;
283
+ }): PmxAxWorkItem | null;
284
+ getApprovalGates(): PmxAxApprovalGate[];
285
+ requestApproval(input: {
286
+ title: string;
287
+ detail?: string | null;
288
+ action?: string | null;
289
+ nodeIds?: string[];
290
+ }, options?: {
291
+ source?: PmxAxSource;
292
+ }): PmxAxApprovalGate;
293
+ resolveApproval(id: string, decision: 'approved' | 'rejected', options?: {
294
+ resolution?: string;
295
+ source?: PmxAxSource;
296
+ }): PmxAxApprovalGate | null;
297
+ getReviewAnnotations(): PmxAxReviewAnnotation[];
298
+ addReviewAnnotation(input: {
299
+ body: string;
300
+ kind?: PmxAxReviewKind;
301
+ severity?: PmxAxReviewSeverity;
302
+ anchorType?: PmxAxReviewAnchorType;
303
+ nodeId?: string | null;
304
+ file?: string | null;
305
+ region?: PmxAxReviewRegion | null;
306
+ author?: string | null;
307
+ }, options?: {
308
+ source?: PmxAxSource;
309
+ }): PmxAxReviewAnnotation | null;
310
+ updateReviewAnnotation(id: string, patch: {
311
+ body?: string;
312
+ status?: PmxAxReviewStatus;
313
+ severity?: PmxAxReviewSeverity;
314
+ kind?: PmxAxReviewKind;
315
+ }, options?: {
316
+ source?: PmxAxSource;
317
+ }): PmxAxReviewAnnotation | null;
318
+ getHostCapability(): PmxAxHostCapability | null;
319
+ setHostCapability(input: unknown, _options?: {
320
+ source?: PmxAxSource;
321
+ }): PmxAxHostCapability;
322
+ recordAxEvent(input: {
323
+ kind: PmxAxEventKind;
324
+ summary: string;
325
+ detail?: string | null;
326
+ nodeIds?: string[];
327
+ data?: Record<string, unknown> | null;
328
+ }, options?: {
329
+ source?: PmxAxSource;
330
+ }): PmxAxEvent;
331
+ addEvidence(input: {
332
+ kind: PmxAxEvidenceKind;
333
+ title: string;
334
+ body?: string | null;
335
+ ref?: string | null;
336
+ nodeIds?: string[];
337
+ data?: Record<string, unknown> | null;
338
+ }, options?: {
339
+ source?: PmxAxSource;
340
+ }): PmxAxEvidence;
341
+ recordSteeringMessage(message: string, options?: {
342
+ source?: PmxAxSource;
343
+ }): PmxAxSteeringMessage;
344
+ markSteeringDelivered(id: string): boolean;
345
+ getAxEvents(q?: AxTimelineQuery): PmxAxEvent[];
346
+ getAxEvidence(q?: AxTimelineQuery): PmxAxEvidence[];
347
+ getAxSteering(q?: AxTimelineQuery & {
348
+ onlyPending?: boolean;
349
+ }): PmxAxSteeringMessage[];
350
+ getAxTimelineSummary(): PmxAxTimelineSummary;
351
+ getAxTimeline(q?: AxTimelineQuery): {
352
+ events: PmxAxEvent[];
353
+ evidence: PmxAxEvidence[];
354
+ steering: PmxAxSteeringMessage[];
355
+ summary: PmxAxTimelineSummary;
356
+ };
266
357
  setContextPins(nodeIds: string[]): void;
267
358
  clearContextPins(): void;
268
359
  /** Move child nodes into a group. Sets data.parentGroup on children and data.children on the group. */