@compilr-dev/sdk 0.18.3 → 0.18.4
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.
|
@@ -243,10 +243,11 @@ export const CAPABILITY_PACKS = {
|
|
|
243
243
|
'canvas_get',
|
|
244
244
|
'canvas_delete',
|
|
245
245
|
'canvas_validate',
|
|
246
|
+
'canvas_screenshot',
|
|
246
247
|
],
|
|
247
248
|
readOnly: false,
|
|
248
249
|
promptModules: ['platform-tool-hints'],
|
|
249
|
-
promptSnippet:
|
|
250
|
+
promptSnippet: 'Visual canvases (infographic/carousel/board) rendered from sandboxed HTML/SVG. Create/replace with canvas_write (raw HTML only — host injects the CSP; inline <style>/<script> only, no network/remote assets; optional Tweaks controls manifest). EDIT via canvas_get (outline=true or startLine/maxLines) then canvas_edit (str_replace/append/prepend) — never re-send the whole document. After authoring, canvas_validate (static) then canvas_screenshot to SEE the render (vision models) — fix overflow/readability with canvas_edit.',
|
|
250
251
|
estimatedPromptTokens: 150,
|
|
251
252
|
estimatedToolTokens: 1500,
|
|
252
253
|
},
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* underlying storage backend (SQLite in CLI, PostgreSQL in web/API).
|
|
6
6
|
*/
|
|
7
7
|
import type { IProjectRepository, IWorkItemRepository, IDocumentRepository, IPlanRepository, ICommentRepository, ICanvasRepository } from './repositories.js';
|
|
8
|
-
import type { IAnchorService, IArtifactService, IEpisodeService } from './services.js';
|
|
8
|
+
import type { IAnchorService, IArtifactService, IEpisodeService, ICanvasRenderer } from './services.js';
|
|
9
9
|
export interface PlatformContext {
|
|
10
10
|
readonly projects: IProjectRepository;
|
|
11
11
|
readonly workItems: IWorkItemRepository;
|
|
@@ -17,6 +17,8 @@ export interface PlatformContext {
|
|
|
17
17
|
readonly episodes?: IEpisodeService;
|
|
18
18
|
readonly canvases?: ICanvasRepository;
|
|
19
19
|
readonly comments?: ICommentRepository;
|
|
20
|
+
/** Host-provided canvas → image renderer (for canvas_screenshot). */
|
|
21
|
+
readonly canvasRenderer?: ICanvasRenderer;
|
|
20
22
|
}
|
|
21
23
|
export interface PlatformHooks {
|
|
22
24
|
/** Called when a project is resolved/selected as the current project */
|
|
@@ -80,3 +80,27 @@ export interface IEpisodeService {
|
|
|
80
80
|
getRecent(count: number): Promise<WorkEpisode[]>;
|
|
81
81
|
getWorkSummary(): Promise<ProjectWorkSummary>;
|
|
82
82
|
}
|
|
83
|
+
/** A rendered canvas image, for the agent's visual self-review. */
|
|
84
|
+
export interface RenderedCanvasImage {
|
|
85
|
+
/** Base64-encoded image data (no `data:` prefix). */
|
|
86
|
+
data: string;
|
|
87
|
+
/** MIME type, e.g. "image/png". */
|
|
88
|
+
mediaType: string;
|
|
89
|
+
width?: number;
|
|
90
|
+
height?: number;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Renders a canvas's HTML/SVG to a raster image so a vision-capable agent can
|
|
94
|
+
* SEE what it authored (`canvas_screenshot`). Host-provided — the SDK can't
|
|
95
|
+
* render HTML (the host does it via, e.g., an offscreen Electron window +
|
|
96
|
+
* capturePage). Absent in hosts that can't render canvases (e.g. the CLI),
|
|
97
|
+
* in which case canvas_screenshot degrades to a "not available here" note.
|
|
98
|
+
*/
|
|
99
|
+
export interface ICanvasRenderer {
|
|
100
|
+
renderToImage(input: {
|
|
101
|
+
/** Raw canvas HTML/SVG (the stored content). */
|
|
102
|
+
content: string;
|
|
103
|
+
/** Canvas type — the host sizes/wraps accordingly. */
|
|
104
|
+
type: 'infographic' | 'carousel' | 'board';
|
|
105
|
+
}): Promise<RenderedCanvasImage>;
|
|
106
|
+
}
|
|
@@ -576,6 +576,55 @@ export function createCanvasTools(config) {
|
|
|
576
576
|
}
|
|
577
577
|
},
|
|
578
578
|
});
|
|
579
|
+
// ---------------------------------------------------------------------------
|
|
580
|
+
// canvas_screenshot — render + SEE the canvas (visual self-review)
|
|
581
|
+
// ---------------------------------------------------------------------------
|
|
582
|
+
const canvasScreenshotTool = defineTool({
|
|
583
|
+
name: 'canvas_screenshot',
|
|
584
|
+
description: 'RENDER a canvas and SEE it — a visual self-review that static checks can’t do. Renders the stored canvas ' +
|
|
585
|
+
'to an image and returns it so you can inspect how it ACTUALLY looks: content overflow / cut-off, unreadable ' +
|
|
586
|
+
'or low-contrast text, cramped or empty areas, misaligned or broken layout. Run it after canvas_write / ' +
|
|
587
|
+
'canvas_edit (and canvas_validate) — if something is off, fix it with canvas_edit and screenshot again. ' +
|
|
588
|
+
'Only useful on a vision-capable model; unavailable in hosts that can’t render canvases.',
|
|
589
|
+
inputSchema: {
|
|
590
|
+
type: 'object',
|
|
591
|
+
properties: {
|
|
592
|
+
canvas_id: { type: 'number', description: 'The stored canvas to render and view.' },
|
|
593
|
+
},
|
|
594
|
+
required: ['canvas_id'],
|
|
595
|
+
},
|
|
596
|
+
execute: async (input) => {
|
|
597
|
+
try {
|
|
598
|
+
const renderer = ctx.canvasRenderer;
|
|
599
|
+
if (!renderer) {
|
|
600
|
+
return createSuccessResult('Canvas rendering is not available in this environment — a visual self-review can’t be produced here. ' +
|
|
601
|
+
'Rely on canvas_validate (static checks) instead.');
|
|
602
|
+
}
|
|
603
|
+
const c = await canvases.getById(input.canvas_id);
|
|
604
|
+
if (!c)
|
|
605
|
+
return createErrorResult(`Canvas ${String(input.canvas_id)} not found.`);
|
|
606
|
+
const img = await renderer.renderToImage({ content: c.content, type: c.type });
|
|
607
|
+
return {
|
|
608
|
+
success: true,
|
|
609
|
+
result: `Rendered "${c.title}" (${c.type}). Review the image below — check for overflow / cut-off content, ` +
|
|
610
|
+
'unreadable or low-contrast text, cramped or empty areas, and broken layout. If anything is off, fix it ' +
|
|
611
|
+
'with canvas_edit and screenshot again.',
|
|
612
|
+
imageBlocks: [
|
|
613
|
+
{
|
|
614
|
+
data: img.data,
|
|
615
|
+
mediaType: img.mediaType,
|
|
616
|
+
filename: `canvas-${String(c.id)}.png`,
|
|
617
|
+
width: img.width,
|
|
618
|
+
height: img.height,
|
|
619
|
+
},
|
|
620
|
+
],
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
catch (error) {
|
|
624
|
+
return createErrorResult(`Failed to screenshot canvas: ${error instanceof Error ? error.message : String(error)}`);
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
});
|
|
579
628
|
return [
|
|
580
629
|
canvasWriteTool,
|
|
581
630
|
canvasEditTool,
|
|
@@ -583,5 +632,6 @@ export function createCanvasTools(config) {
|
|
|
583
632
|
canvasGetTool,
|
|
584
633
|
canvasDeleteTool,
|
|
585
634
|
canvasValidateTool,
|
|
635
|
+
canvasScreenshotTool,
|
|
586
636
|
];
|
|
587
637
|
}
|
|
@@ -67,9 +67,11 @@ export const canvasSkill = defineSkill({
|
|
|
67
67
|
|
|
68
68
|
4. **To EDIT an existing canvas, do NOT re-send the whole document.** First call \`canvas_get\` with \`outline=true\` (or a \`startLine\`/\`maxLines\` slice) to find the exact snippet, then \`canvas_edit\` with \`operation=str_replace\` (old_str must be unique — include surrounding context — or set replace_all=true), or append/prepend. Reserve \`canvas_write\` with \`canvas_id\` for a full intentional rewrite.
|
|
69
69
|
|
|
70
|
-
5. **Validate before you hand it off.** Once the canvas is composed, call \`canvas_validate\` (canvas_id) — a fast static check that catches content that won't render (Mermaid/Markdown/CDN), a board missing its \`data-board\` bounds or with nodes off-canvas, sparse output, and hardcoded colors that ignore the theme tokens. Fix any **errors** (they render broken) and address applicable **warnings**, then move on.
|
|
70
|
+
5. **Validate before you hand it off.** Once the canvas is composed, call \`canvas_validate\` (canvas_id) — a fast static check that catches content that won't render (Mermaid/Markdown/CDN), a board missing its \`data-board\` bounds or with nodes off-canvas, sparse output, and hardcoded colors that ignore the theme tokens. Fix any **errors** (they render broken) and address applicable **warnings**, then move on.
|
|
71
71
|
|
|
72
|
-
6. **
|
|
72
|
+
6. **See it before you trust it (if you can).** If you're vision-capable, call \`canvas_screenshot\` (canvas_id) — it renders the canvas and returns the image so you can catch what static checks can't: overflow / cut-off content, unreadable or low-contrast text, cramped or empty areas, broken layout. If something's off, fix it with \`canvas_edit\` and screenshot again. (No-op on text-only models / hosts that can't render.)
|
|
73
|
+
|
|
74
|
+
7. **After writing, tell the user what you made in one line** and point them at the Tweaks they can adjust. The canvas opens in its own tab.
|
|
73
75
|
|
|
74
76
|
## Rules
|
|
75
77
|
- CALL THE TOOL — don't describe the HTML you "would" write and stop. A canvas only exists once the tool succeeds.
|
package/dist/team/tool-config.js
CHANGED