pmx-canvas 0.1.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/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/Readme.md +865 -0
- package/dist/canvas/global.css +3173 -0
- package/dist/canvas/index.js +183 -0
- package/dist/json-render/index.css +2 -0
- package/dist/json-render/index.js +389 -0
- package/dist/types/cli/agent.d.ts +13 -0
- package/dist/types/cli/index.d.ts +2 -0
- package/dist/types/cli/watch.d.ts +5 -0
- package/dist/types/client/App.d.ts +1 -0
- package/dist/types/client/canvas/AttentionHistory.d.ts +1 -0
- package/dist/types/client/canvas/AttentionToast.d.ts +1 -0
- package/dist/types/client/canvas/CanvasNode.d.ts +8 -0
- package/dist/types/client/canvas/CanvasViewport.d.ts +8 -0
- package/dist/types/client/canvas/CommandPalette.d.ts +4 -0
- package/dist/types/client/canvas/ContextMenu.d.ts +24 -0
- package/dist/types/client/canvas/ContextPinBar.d.ts +1 -0
- package/dist/types/client/canvas/ContextPinHud.d.ts +1 -0
- package/dist/types/client/canvas/DockedNode.d.ts +4 -0
- package/dist/types/client/canvas/EdgeLayer.d.ts +8 -0
- package/dist/types/client/canvas/ExpandedNodeOverlay.d.ts +1 -0
- package/dist/types/client/canvas/FocusFieldLayer.d.ts +1 -0
- package/dist/types/client/canvas/Minimap.d.ts +23 -0
- package/dist/types/client/canvas/SelectionBar.d.ts +1 -0
- package/dist/types/client/canvas/ShortcutOverlay.d.ts +3 -0
- package/dist/types/client/canvas/SnapshotPanel.d.ts +7 -0
- package/dist/types/client/canvas/snap-guides.d.ts +23 -0
- package/dist/types/client/canvas/use-node-drag.d.ts +15 -0
- package/dist/types/client/canvas/use-node-resize.d.ts +15 -0
- package/dist/types/client/canvas/use-pan-zoom.d.ts +16 -0
- package/dist/types/client/ext-app/bridge.d.ts +161 -0
- package/dist/types/client/icons.d.ts +70 -0
- package/dist/types/client/index.d.ts +1 -0
- package/dist/types/client/nodes/ContextNode.d.ts +34 -0
- package/dist/types/client/nodes/ExtAppFrame.d.ts +18 -0
- package/dist/types/client/nodes/FileNode.d.ts +5 -0
- package/dist/types/client/nodes/GroupNode.d.ts +6 -0
- package/dist/types/client/nodes/ImageNode.d.ts +10 -0
- package/dist/types/client/nodes/InlineFormatBar.d.ts +7 -0
- package/dist/types/client/nodes/InlineMarkdownEditor.d.ts +14 -0
- package/dist/types/client/nodes/LedgerNode.d.ts +4 -0
- package/dist/types/client/nodes/MarkdownNode.d.ts +6 -0
- package/dist/types/client/nodes/McpAppNode.d.ts +4 -0
- package/dist/types/client/nodes/MdFormatBar.d.ts +8 -0
- package/dist/types/client/nodes/PromptNode.d.ts +5 -0
- package/dist/types/client/nodes/ResponseNode.d.ts +5 -0
- package/dist/types/client/nodes/StatusNode.d.ts +4 -0
- package/dist/types/client/nodes/StatusSummary.d.ts +4 -0
- package/dist/types/client/nodes/TraceNode.d.ts +4 -0
- package/dist/types/client/nodes/WebpageNode.d.ts +5 -0
- package/dist/types/client/nodes/image-warnings.d.ts +6 -0
- package/dist/types/client/nodes/inline-editor-commands.d.ts +11 -0
- package/dist/types/client/nodes/md-format.d.ts +25 -0
- package/dist/types/client/state/attention-bridge.d.ts +3 -0
- package/dist/types/client/state/attention-store.d.ts +25 -0
- package/dist/types/client/state/canvas-store.d.ts +74 -0
- package/dist/types/client/state/intent-bridge.d.ts +158 -0
- package/dist/types/client/state/sse-bridge.d.ts +5 -0
- package/dist/types/client/theme/tokens.d.ts +27 -0
- package/dist/types/client/types.d.ts +40 -0
- package/dist/types/client/utils/ext-app-tool-result.d.ts +1 -0
- package/dist/types/client/utils/placement.d.ts +1 -0
- package/dist/types/client/utils/platform.d.ts +2 -0
- package/dist/types/json-render/catalog.d.ts +815 -0
- package/dist/types/json-render/charts/components.d.ts +54 -0
- package/dist/types/json-render/charts/definitions.d.ts +103 -0
- package/dist/types/json-render/charts/extra-components.d.ts +58 -0
- package/dist/types/json-render/charts/extra-definitions.d.ts +181 -0
- package/dist/types/json-render/renderer/index.d.ts +16 -0
- package/dist/types/json-render/schema.d.ts +46 -0
- package/dist/types/json-render/server.d.ts +55 -0
- package/dist/types/mcp/server.d.ts +22 -0
- package/dist/types/server/agent-context.d.ts +21 -0
- package/dist/types/server/artifact-paths.d.ts +3 -0
- package/dist/types/server/canvas-operations.d.ts +154 -0
- package/dist/types/server/canvas-provenance.d.ts +13 -0
- package/dist/types/server/canvas-schema.d.ts +49 -0
- package/dist/types/server/canvas-serialization.d.ts +25 -0
- package/dist/types/server/canvas-state.d.ts +174 -0
- package/dist/types/server/canvas-validation.d.ts +33 -0
- package/dist/types/server/chart-template.d.ts +29 -0
- package/dist/types/server/code-graph.d.ts +67 -0
- package/dist/types/server/context-cards.d.ts +24 -0
- package/dist/types/server/diagram-presets.d.ts +28 -0
- package/dist/types/server/ext-app-call-registry.d.ts +16 -0
- package/dist/types/server/ext-app-tool-result.d.ts +1 -0
- package/dist/types/server/file-watcher.d.ts +16 -0
- package/dist/types/server/index.d.ts +243 -0
- package/dist/types/server/mcp-app-candidate.d.ts +25 -0
- package/dist/types/server/mcp-app-host.d.ts +65 -0
- package/dist/types/server/mcp-app-runtime.d.ts +47 -0
- package/dist/types/server/mutation-history.d.ts +105 -0
- package/dist/types/server/placement.d.ts +37 -0
- package/dist/types/server/server.d.ts +103 -0
- package/dist/types/server/spatial-analysis.d.ts +87 -0
- package/dist/types/server/trace-manager.d.ts +48 -0
- package/dist/types/server/web-artifacts.d.ts +50 -0
- package/dist/types/server/webpage-node.d.ts +25 -0
- package/dist/types/shared/auto-arrange.d.ts +29 -0
- package/dist/types/shared/ext-app-tool-result.d.ts +9 -0
- package/dist/types/shared/placement.d.ts +26 -0
- package/dist/types/shared/semantic-attention.d.ts +97 -0
- package/package.json +109 -0
- package/skills/data-analysis/SKILL.md +324 -0
- package/skills/doc-coauthoring/SKILL.md +375 -0
- package/skills/frontend-design/SKILL.md +45 -0
- package/skills/json-render-codegen/SKILL.md +112 -0
- package/skills/json-render-core/SKILL.md +265 -0
- package/skills/json-render-ink/SKILL.md +273 -0
- package/skills/json-render-mcp/SKILL.md +132 -0
- package/skills/json-render-react/SKILL.md +264 -0
- package/skills/json-render-shadcn/SKILL.md +159 -0
- package/skills/playwright-cli/SKILL.md +67 -0
- package/skills/pmx-canvas/SKILL.md +668 -0
- package/skills/pmx-canvas/evals/evals.json +186 -0
- package/skills/pmx-canvas-testing/SKILL.md +78 -0
- package/skills/published-consumer-e2e/SKILL.md +43 -0
- package/skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh +241 -0
- package/skills/web-artifacts-builder/SKILL.md +80 -0
- package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +167 -0
- package/skills/web-artifacts-builder/scripts/init-artifact.sh +425 -0
- package/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/web-design-guidelines/SKILL.md +39 -0
- package/src/cli/agent.ts +2144 -0
- package/src/cli/index.ts +622 -0
- package/src/cli/watch.ts +88 -0
- package/src/client/App.tsx +507 -0
- package/src/client/canvas/AttentionHistory.tsx +81 -0
- package/src/client/canvas/AttentionToast.tsx +19 -0
- package/src/client/canvas/CanvasNode.tsx +363 -0
- package/src/client/canvas/CanvasViewport.tsx +590 -0
- package/src/client/canvas/CommandPalette.tsx +302 -0
- package/src/client/canvas/ContextMenu.tsx +601 -0
- package/src/client/canvas/ContextPinBar.tsx +25 -0
- package/src/client/canvas/ContextPinHud.tsx +22 -0
- package/src/client/canvas/DockedNode.tsx +66 -0
- package/src/client/canvas/EdgeLayer.tsx +280 -0
- package/src/client/canvas/ExpandedNodeOverlay.tsx +260 -0
- package/src/client/canvas/FocusFieldLayer.tsx +107 -0
- package/src/client/canvas/Minimap.tsx +301 -0
- package/src/client/canvas/SelectionBar.tsx +69 -0
- package/src/client/canvas/ShortcutOverlay.tsx +69 -0
- package/src/client/canvas/SnapshotPanel.tsx +236 -0
- package/src/client/canvas/snap-guides.ts +170 -0
- package/src/client/canvas/use-node-drag.ts +51 -0
- package/src/client/canvas/use-node-resize.ts +59 -0
- package/src/client/canvas/use-pan-zoom.ts +191 -0
- package/src/client/ext-app/bridge.ts +542 -0
- package/src/client/icons.tsx +424 -0
- package/src/client/index.tsx +7 -0
- package/src/client/nodes/ContextNode.tsx +412 -0
- package/src/client/nodes/ExtAppFrame.tsx +509 -0
- package/src/client/nodes/FileNode.tsx +256 -0
- package/src/client/nodes/GroupNode.tsx +39 -0
- package/src/client/nodes/ImageNode.tsx +160 -0
- package/src/client/nodes/InlineFormatBar.tsx +169 -0
- package/src/client/nodes/InlineMarkdownEditor.tsx +123 -0
- package/src/client/nodes/LedgerNode.tsx +37 -0
- package/src/client/nodes/MarkdownNode.tsx +359 -0
- package/src/client/nodes/McpAppNode.tsx +85 -0
- package/src/client/nodes/MdFormatBar.tsx +109 -0
- package/src/client/nodes/PromptNode.tsx +597 -0
- package/src/client/nodes/ResponseNode.tsx +153 -0
- package/src/client/nodes/StatusNode.tsx +84 -0
- package/src/client/nodes/StatusSummary.tsx +38 -0
- package/src/client/nodes/TraceNode.tsx +120 -0
- package/src/client/nodes/WebpageNode.tsx +288 -0
- package/src/client/nodes/image-warnings.ts +95 -0
- package/src/client/nodes/inline-editor-commands.ts +37 -0
- package/src/client/nodes/md-format.ts +206 -0
- package/src/client/state/attention-bridge.ts +328 -0
- package/src/client/state/attention-store.ts +73 -0
- package/src/client/state/canvas-store.ts +631 -0
- package/src/client/state/intent-bridge.ts +315 -0
- package/src/client/state/sse-bridge.ts +965 -0
- package/src/client/theme/global.css +3173 -0
- package/src/client/theme/tokens.ts +72 -0
- package/src/client/types-shims.d.ts +5 -0
- package/src/client/types.ts +81 -0
- package/src/client/utils/ext-app-tool-result.ts +4 -0
- package/src/client/utils/placement.ts +4 -0
- package/src/client/utils/platform.ts +2 -0
- package/src/json-render/catalog.ts +256 -0
- package/src/json-render/charts/components.tsx +198 -0
- package/src/json-render/charts/definitions.ts +81 -0
- package/src/json-render/charts/extra-components.tsx +267 -0
- package/src/json-render/charts/extra-definitions.ts +145 -0
- package/src/json-render/renderer/index.css +174 -0
- package/src/json-render/renderer/index.tsx +86 -0
- package/src/json-render/schema.ts +62 -0
- package/src/json-render/server.ts +597 -0
- package/src/mcp/server.ts +1377 -0
- package/src/server/agent-context.ts +242 -0
- package/src/server/artifact-paths.ts +17 -0
- package/src/server/canvas-operations.ts +1279 -0
- package/src/server/canvas-provenance.ts +243 -0
- package/src/server/canvas-schema.ts +432 -0
- package/src/server/canvas-serialization.ts +95 -0
- package/src/server/canvas-state.ts +1134 -0
- package/src/server/canvas-validation.ts +114 -0
- package/src/server/chart-template.ts +449 -0
- package/src/server/code-graph.ts +370 -0
- package/src/server/context-cards.ts +31 -0
- package/src/server/diagram-presets.ts +71 -0
- package/src/server/ext-app-call-registry.ts +77 -0
- package/src/server/ext-app-tool-result.ts +4 -0
- package/src/server/file-watcher.ts +121 -0
- package/src/server/index.ts +647 -0
- package/src/server/mcp-app-candidate.ts +174 -0
- package/src/server/mcp-app-host.ts +814 -0
- package/src/server/mcp-app-runtime.ts +459 -0
- package/src/server/mutation-history.ts +350 -0
- package/src/server/placement.ts +125 -0
- package/src/server/server.ts +3846 -0
- package/src/server/spatial-analysis.ts +356 -0
- package/src/server/trace-manager.ts +333 -0
- package/src/server/web-artifacts/scripts/bundle-artifact.sh +167 -0
- package/src/server/web-artifacts/scripts/init-artifact.sh +426 -0
- package/src/server/web-artifacts/scripts/shadcn-components.tar.gz +0 -0
- package/src/server/web-artifacts.ts +442 -0
- package/src/server/webpage-node.ts +328 -0
- package/src/shared/auto-arrange.ts +439 -0
- package/src/shared/ext-app-tool-result.ts +76 -0
- package/src/shared/placement.ts +81 -0
- package/src/shared/semantic-attention.ts +598 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import type { CanvasNodeState } from './canvas-state.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_CONTEXT_TEXT_LENGTH = 700;
|
|
4
|
+
const DEFAULT_WEBPAGE_CONTEXT_TEXT_LENGTH = 1600;
|
|
5
|
+
|
|
6
|
+
export interface AgentContextNode {
|
|
7
|
+
id: string;
|
|
8
|
+
type: CanvasNodeState['type'];
|
|
9
|
+
title: string | null;
|
|
10
|
+
content: string | null;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
position?: { x: number; y: number };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface AgentContextOptions {
|
|
16
|
+
defaultTextLength?: number;
|
|
17
|
+
webpageTextLength?: number;
|
|
18
|
+
includePosition?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function normalizeContextText(text: string): string {
|
|
22
|
+
return text
|
|
23
|
+
.replace(/\r\n?/g, '\n')
|
|
24
|
+
.replace(/[ \t\f\v]+/g, ' ')
|
|
25
|
+
.replace(/\n\s+/g, '\n')
|
|
26
|
+
.replace(/\s+\n/g, '\n')
|
|
27
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
28
|
+
.trim();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function truncateContextText(text: string, maxLength: number): string {
|
|
32
|
+
if (maxLength <= 0) return '';
|
|
33
|
+
const normalized = normalizeContextText(text);
|
|
34
|
+
if (normalized.length <= maxLength) return normalized;
|
|
35
|
+
if (maxLength <= 1) return normalized.slice(0, maxLength);
|
|
36
|
+
return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function stringifyContextValue(value: unknown, maxLength: number): string {
|
|
40
|
+
if (typeof value === 'string') return truncateContextText(value, maxLength);
|
|
41
|
+
if (value === null || value === undefined) return '';
|
|
42
|
+
try {
|
|
43
|
+
return truncateContextText(JSON.stringify(value), maxLength);
|
|
44
|
+
} catch {
|
|
45
|
+
return '';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function summarizeWebpageData(data: Record<string, unknown>, maxLength: number): string {
|
|
50
|
+
const parts: string[] = [];
|
|
51
|
+
const url = typeof data.url === 'string' ? data.url : '';
|
|
52
|
+
const pageTitle = typeof data.pageTitle === 'string' ? data.pageTitle : '';
|
|
53
|
+
const description = typeof data.description === 'string' ? data.description : '';
|
|
54
|
+
const status = typeof data.status === 'string' ? data.status : '';
|
|
55
|
+
const statusCode = typeof data.statusCode === 'number' ? data.statusCode : null;
|
|
56
|
+
const error = typeof data.error === 'string' ? data.error : '';
|
|
57
|
+
const content = typeof data.content === 'string'
|
|
58
|
+
? data.content
|
|
59
|
+
: typeof data.excerpt === 'string'
|
|
60
|
+
? data.excerpt
|
|
61
|
+
: '';
|
|
62
|
+
|
|
63
|
+
if (url) parts.push(`URL: ${url}`);
|
|
64
|
+
if (pageTitle) parts.push(`Title: ${pageTitle}`);
|
|
65
|
+
if (description) parts.push(`Description: ${description}`);
|
|
66
|
+
if (status || statusCode !== null) {
|
|
67
|
+
parts.push(`Fetch: ${status || 'unknown'}${statusCode !== null ? ` (${statusCode})` : ''}`);
|
|
68
|
+
}
|
|
69
|
+
if (error) parts.push(`Error: ${error}`);
|
|
70
|
+
|
|
71
|
+
const header = parts.join('\n');
|
|
72
|
+
const remaining = Math.max(0, maxLength - header.length - (header ? 2 : 0));
|
|
73
|
+
const body = remaining > 0 ? truncateContextText(content, remaining) : '';
|
|
74
|
+
|
|
75
|
+
if (header && body) return `${header}\n\n${body}`;
|
|
76
|
+
if (header) return truncateContextText(header, maxLength);
|
|
77
|
+
return truncateContextText(content, maxLength);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function summarizeExtAppInput(toolInput: unknown): string {
|
|
81
|
+
if (toolInput === null || toolInput === undefined) return '';
|
|
82
|
+
if (typeof toolInput !== 'object' || Array.isArray(toolInput)) return '';
|
|
83
|
+
const elements = (toolInput as Record<string, unknown>).elements;
|
|
84
|
+
if (Array.isArray(elements)) {
|
|
85
|
+
return `Diagram elements: ${elements.length}`;
|
|
86
|
+
}
|
|
87
|
+
const keys = Object.keys(toolInput as Record<string, unknown>).sort();
|
|
88
|
+
return keys.length > 0 ? `Input keys: ${keys.join(', ')}` : '';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function summarizeMcpAppData(data: Record<string, unknown>, maxLength: number): string {
|
|
92
|
+
const parts: string[] = [];
|
|
93
|
+
const title = typeof data.title === 'string' ? data.title : '';
|
|
94
|
+
const mode = typeof data.mode === 'string' ? data.mode : '';
|
|
95
|
+
const hostMode = typeof data.hostMode === 'string' ? data.hostMode : '';
|
|
96
|
+
const serverName = typeof data.serverName === 'string' ? data.serverName : '';
|
|
97
|
+
const toolName = typeof data.toolName === 'string' ? data.toolName : '';
|
|
98
|
+
const resourceUri = typeof data.resourceUri === 'string' ? data.resourceUri : '';
|
|
99
|
+
const path = typeof data.path === 'string' ? data.path : '';
|
|
100
|
+
const url = typeof data.url === 'string' ? data.url : '';
|
|
101
|
+
const sessionStatus = typeof data.sessionStatus === 'string' ? data.sessionStatus : '';
|
|
102
|
+
const inputSummary = summarizeExtAppInput(data.toolInput);
|
|
103
|
+
|
|
104
|
+
if (title) parts.push(`App: ${title}`);
|
|
105
|
+
if (mode || hostMode) {
|
|
106
|
+
parts.push(`Mode: ${[mode, hostMode].filter(Boolean).join(' / ')}`);
|
|
107
|
+
}
|
|
108
|
+
if (serverName || toolName) {
|
|
109
|
+
parts.push(`Source: ${[serverName, toolName].filter(Boolean).join(' / ')}`);
|
|
110
|
+
}
|
|
111
|
+
if (resourceUri) parts.push(`Resource: ${resourceUri}`);
|
|
112
|
+
if (path) parts.push(`Path: ${path}`);
|
|
113
|
+
if (url) parts.push(`URL: ${url}`);
|
|
114
|
+
if (sessionStatus) parts.push(`Session: ${sessionStatus}`);
|
|
115
|
+
if (inputSummary) parts.push(inputSummary);
|
|
116
|
+
|
|
117
|
+
if (parts.length === 0) return 'MCP App node';
|
|
118
|
+
return truncateContextText(parts.join('\n'), maxLength);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function metadataForNode(node: CanvasNodeState): Record<string, unknown> | undefined {
|
|
122
|
+
switch (node.type) {
|
|
123
|
+
case 'webpage': {
|
|
124
|
+
const metadata: Record<string, unknown> = {};
|
|
125
|
+
for (const key of ['url', 'pageTitle', 'description', 'imageUrl', 'fetchedAt', 'status', 'statusCode', 'contentType']) {
|
|
126
|
+
const value = node.data[key];
|
|
127
|
+
if (value !== undefined && value !== null && value !== '') metadata[key] = value;
|
|
128
|
+
}
|
|
129
|
+
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
130
|
+
}
|
|
131
|
+
case 'file': {
|
|
132
|
+
const metadata: Record<string, unknown> = {};
|
|
133
|
+
for (const key of ['path', 'updatedAt', 'lineCount']) {
|
|
134
|
+
const value = node.data[key];
|
|
135
|
+
if (value !== undefined && value !== null && value !== '') metadata[key] = value;
|
|
136
|
+
}
|
|
137
|
+
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
138
|
+
}
|
|
139
|
+
case 'image': {
|
|
140
|
+
const metadata: Record<string, unknown> = {};
|
|
141
|
+
for (const key of ['src', 'path', 'mimeType', 'validationStatus', 'validationMessage']) {
|
|
142
|
+
const value = node.data[key];
|
|
143
|
+
if (value !== undefined && value !== null && value !== '') metadata[key] = value;
|
|
144
|
+
}
|
|
145
|
+
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
146
|
+
}
|
|
147
|
+
case 'mcp-app': {
|
|
148
|
+
const metadata: Record<string, unknown> = {};
|
|
149
|
+
for (const key of ['url', 'path', 'mode', 'hostMode', 'serverName', 'toolName', 'resourceUri', 'sessionStatus']) {
|
|
150
|
+
const value = node.data[key];
|
|
151
|
+
if (value !== undefined && value !== null && value !== '') metadata[key] = value;
|
|
152
|
+
}
|
|
153
|
+
return Object.keys(metadata).length > 0 ? metadata : undefined;
|
|
154
|
+
}
|
|
155
|
+
default:
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export function summarizeNodeForAgentContext(
|
|
161
|
+
node: CanvasNodeState,
|
|
162
|
+
options: AgentContextOptions = {},
|
|
163
|
+
): string {
|
|
164
|
+
const defaultTextLength = options.defaultTextLength ?? DEFAULT_CONTEXT_TEXT_LENGTH;
|
|
165
|
+
const webpageTextLength = options.webpageTextLength ?? DEFAULT_WEBPAGE_CONTEXT_TEXT_LENGTH;
|
|
166
|
+
|
|
167
|
+
switch (node.type) {
|
|
168
|
+
case 'markdown': {
|
|
169
|
+
const content = (node.data.rendered as string) || (node.data.content as string) || '';
|
|
170
|
+
return truncateContextText(content, defaultTextLength);
|
|
171
|
+
}
|
|
172
|
+
case 'mcp-app': {
|
|
173
|
+
const chartCfg = node.data.chartConfig as Record<string, unknown> | undefined;
|
|
174
|
+
if (chartCfg) {
|
|
175
|
+
const chartTitle = (chartCfg.title as string) || 'Untitled chart';
|
|
176
|
+
const chartType = (chartCfg.type as string) || 'unknown';
|
|
177
|
+
const labels = Array.isArray(chartCfg.labels)
|
|
178
|
+
? (chartCfg.labels as string[]).join(', ')
|
|
179
|
+
: '';
|
|
180
|
+
return truncateContextText(`Chart: ${chartTitle} (${chartType}). Labels: ${labels}`, defaultTextLength);
|
|
181
|
+
}
|
|
182
|
+
return summarizeMcpAppData(node.data, defaultTextLength);
|
|
183
|
+
}
|
|
184
|
+
case 'webpage':
|
|
185
|
+
return summarizeWebpageData(node.data, webpageTextLength);
|
|
186
|
+
case 'json-render':
|
|
187
|
+
case 'graph': {
|
|
188
|
+
const graphCfg = node.data.graphConfig as Record<string, unknown> | undefined;
|
|
189
|
+
if (graphCfg) return truncateContextText(`Graph: ${JSON.stringify(graphCfg)}`, defaultTextLength);
|
|
190
|
+
return stringifyContextValue(node.data.spec ?? {}, defaultTextLength);
|
|
191
|
+
}
|
|
192
|
+
case 'prompt':
|
|
193
|
+
case 'response': {
|
|
194
|
+
const text = (node.data.text as string) || (node.data.content as string) || '';
|
|
195
|
+
return truncateContextText(text, defaultTextLength);
|
|
196
|
+
}
|
|
197
|
+
case 'file': {
|
|
198
|
+
const path = typeof node.data.path === 'string' ? node.data.path : '';
|
|
199
|
+
const fileContent = typeof node.data.fileContent === 'string'
|
|
200
|
+
? node.data.fileContent
|
|
201
|
+
: typeof node.data.content === 'string'
|
|
202
|
+
? node.data.content
|
|
203
|
+
: '';
|
|
204
|
+
const prefix = path ? `Path: ${path}\n\n` : '';
|
|
205
|
+
const remaining = Math.max(0, defaultTextLength - prefix.length);
|
|
206
|
+
return `${prefix}${truncateContextText(fileContent, remaining)}`.trim();
|
|
207
|
+
}
|
|
208
|
+
default:
|
|
209
|
+
return stringifyContextValue(node.data, defaultTextLength);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function serializeNodeForAgentContext(
|
|
214
|
+
node: CanvasNodeState,
|
|
215
|
+
options: AgentContextOptions = {},
|
|
216
|
+
): AgentContextNode {
|
|
217
|
+
const metadata = metadataForNode(node);
|
|
218
|
+
return {
|
|
219
|
+
id: node.id,
|
|
220
|
+
type: node.type,
|
|
221
|
+
title: typeof node.data.title === 'string' ? node.data.title : null,
|
|
222
|
+
content: summarizeNodeForAgentContext(node, options) || null,
|
|
223
|
+
...(metadata ? { metadata } : {}),
|
|
224
|
+
...(options.includePosition ? { position: node.position } : {}),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function buildAgentContextPreamble(
|
|
229
|
+
nodes: CanvasNodeState[],
|
|
230
|
+
options: AgentContextOptions = {},
|
|
231
|
+
): string {
|
|
232
|
+
const sections = nodes
|
|
233
|
+
.map((node) => {
|
|
234
|
+
const title = (typeof node.data.title === 'string' && node.data.title) ? node.data.title : node.id;
|
|
235
|
+
const content = summarizeNodeForAgentContext(node, options);
|
|
236
|
+
if (!content) return '';
|
|
237
|
+
return `[Context from "${title}" (${node.type})]\n${content}\n`;
|
|
238
|
+
})
|
|
239
|
+
.filter((section) => section.length > 0);
|
|
240
|
+
|
|
241
|
+
return sections.length > 0 ? `${sections.join('\n')}\n` : '';
|
|
242
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { mkdirSync } from 'node:fs';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { PMX_CANVAS_DIR } from './canvas-state.js';
|
|
4
|
+
|
|
5
|
+
export function getWorkspaceRoot(cwd?: string): string {
|
|
6
|
+
return resolve(cwd ?? process.cwd());
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getArtifactsDir(cwd?: string): string {
|
|
10
|
+
return join(getWorkspaceRoot(cwd), PMX_CANVAS_DIR, 'artifacts');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function ensureArtifactsDir(cwd?: string): string {
|
|
14
|
+
const dir = getArtifactsDir(cwd);
|
|
15
|
+
mkdirSync(dir, { recursive: true });
|
|
16
|
+
return dir;
|
|
17
|
+
}
|