@sapiom/harness 0.1.6 → 0.2.1
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 +105 -0
- package/dist/cli/args.d.ts +16 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +80 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/bin.js +12 -65
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/settings.d.ts.map +1 -1
- package/dist/cli/settings.js +33 -1
- package/dist/cli/settings.js.map +1 -1
- package/dist/core/adapters/claude-code.d.ts +60 -2
- package/dist/core/adapters/claude-code.d.ts.map +1 -1
- package/dist/core/adapters/claude-code.js +119 -32
- package/dist/core/adapters/claude-code.js.map +1 -1
- package/dist/core/adapters/codex.d.ts +21 -2
- package/dist/core/adapters/codex.d.ts.map +1 -1
- package/dist/core/adapters/codex.js +53 -2
- package/dist/core/adapters/codex.js.map +1 -1
- package/dist/core/adapters/detect.d.ts +9 -0
- package/dist/core/adapters/detect.d.ts.map +1 -1
- package/dist/core/adapters/detect.js +9 -0
- package/dist/core/adapters/detect.js.map +1 -1
- package/dist/core/canvas-body.d.ts +28 -28
- package/dist/core/canvas-body.d.ts.map +1 -1
- package/dist/core/canvas-body.js +117 -55
- package/dist/core/canvas-body.js.map +1 -1
- package/dist/core/canvas-derive.d.ts +43 -0
- package/dist/core/canvas-derive.d.ts.map +1 -0
- package/dist/core/canvas-derive.js +95 -0
- package/dist/core/canvas-derive.js.map +1 -0
- package/dist/core/canvas-enrichment.d.ts +52 -127
- package/dist/core/canvas-enrichment.d.ts.map +1 -1
- package/dist/core/canvas-enrichment.js +17 -178
- package/dist/core/canvas-enrichment.js.map +1 -1
- package/dist/core/canvas-graph.d.ts +40 -1
- package/dist/core/canvas-graph.d.ts.map +1 -1
- package/dist/core/canvas-graph.js +71 -9
- package/dist/core/canvas-graph.js.map +1 -1
- package/dist/core/canvas-interconnections.d.ts +26 -8
- package/dist/core/canvas-interconnections.d.ts.map +1 -1
- package/dist/core/canvas-interconnections.js +132 -24
- package/dist/core/canvas-interconnections.js.map +1 -1
- package/dist/core/canvas-manifest-check.d.ts.map +1 -1
- package/dist/core/canvas-manifest-check.js +15 -2
- package/dist/core/canvas-manifest-check.js.map +1 -1
- package/dist/core/canvas-render.d.ts +8 -15
- package/dist/core/canvas-render.d.ts.map +1 -1
- package/dist/core/canvas-render.js +29 -41
- package/dist/core/canvas-render.js.map +1 -1
- package/dist/core/canvas-run-state.d.ts +41 -0
- package/dist/core/canvas-run-state.d.ts.map +1 -1
- package/dist/core/canvas-run-state.js +136 -0
- package/dist/core/canvas-run-state.js.map +1 -1
- package/dist/core/canvas-svg.d.ts +9 -4
- package/dist/core/canvas-svg.d.ts.map +1 -1
- package/dist/core/canvas-svg.js +84 -13
- package/dist/core/canvas-svg.js.map +1 -1
- package/dist/core/canvas-template.d.ts +9 -10
- package/dist/core/canvas-template.d.ts.map +1 -1
- package/dist/core/canvas-template.js +57 -20
- package/dist/core/canvas-template.js.map +1 -1
- package/dist/core/canvas-watcher.d.ts +22 -1
- package/dist/core/canvas-watcher.d.ts.map +1 -1
- package/dist/core/canvas-watcher.js +111 -30
- package/dist/core/canvas-watcher.js.map +1 -1
- package/dist/core/collector/normalizer.d.ts +8 -0
- package/dist/core/collector/normalizer.d.ts.map +1 -1
- package/dist/core/collector/normalizer.js +8 -0
- package/dist/core/collector/normalizer.js.map +1 -1
- package/dist/core/collector/store.d.ts +75 -1
- package/dist/core/collector/store.d.ts.map +1 -1
- package/dist/core/collector/store.js +334 -2
- package/dist/core/collector/store.js.map +1 -1
- package/dist/core/errors.d.ts +10 -4
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +11 -5
- package/dist/core/errors.js.map +1 -1
- package/dist/core/example-seed.d.ts +8 -0
- package/dist/core/example-seed.d.ts.map +1 -1
- package/dist/core/example-seed.js +47 -10
- package/dist/core/example-seed.js.map +1 -1
- package/dist/core/inject/system-prompt.d.ts +8 -0
- package/dist/core/inject/system-prompt.d.ts.map +1 -1
- package/dist/core/inject/system-prompt.js +3 -1
- package/dist/core/inject/system-prompt.js.map +1 -1
- package/dist/core/macros.d.ts.map +1 -1
- package/dist/core/macros.js +5 -6
- package/dist/core/macros.js.map +1 -1
- package/dist/core/paths.d.ts +1 -0
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +1 -0
- package/dist/core/paths.js.map +1 -1
- package/dist/core/record-archive.d.ts +187 -0
- package/dist/core/record-archive.d.ts.map +1 -0
- package/dist/core/record-archive.js +465 -0
- package/dist/core/record-archive.js.map +1 -0
- package/dist/core/rehydration.d.ts +72 -0
- package/dist/core/rehydration.d.ts.map +1 -0
- package/dist/core/rehydration.js +72 -0
- package/dist/core/rehydration.js.map +1 -0
- package/dist/core/resume-brief.d.ts +130 -0
- package/dist/core/resume-brief.d.ts.map +1 -0
- package/dist/core/resume-brief.js +404 -0
- package/dist/core/resume-brief.js.map +1 -0
- package/dist/core/rolling-summary.d.ts +130 -0
- package/dist/core/rolling-summary.d.ts.map +1 -0
- package/dist/core/rolling-summary.js +227 -0
- package/dist/core/rolling-summary.js.map +1 -0
- package/dist/core/session-manager.d.ts +11 -3
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +56 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-record.d.ts +165 -0
- package/dist/core/session-record.d.ts.map +1 -0
- package/dist/core/session-record.js +470 -0
- package/dist/core/session-record.js.map +1 -0
- package/dist/core/spawn-target.d.ts +12 -0
- package/dist/core/spawn-target.d.ts.map +1 -0
- package/dist/core/spawn-target.js +187 -0
- package/dist/core/spawn-target.js.map +1 -0
- package/dist/core/task-manager.d.ts.map +1 -1
- package/dist/core/task-manager.js +9 -1
- package/dist/core/task-manager.js.map +1 -1
- package/dist/core/template-catalog.d.ts +48 -0
- package/dist/core/template-catalog.d.ts.map +1 -0
- package/dist/core/template-catalog.js +338 -0
- package/dist/core/template-catalog.js.map +1 -0
- package/dist/core/workflow-registry.d.ts.map +1 -1
- package/dist/core/workflow-registry.js +2 -2
- package/dist/core/workflow-registry.js.map +1 -1
- package/dist/core/workspace-watcher.d.ts.map +1 -1
- package/dist/core/workspace-watcher.js +4 -3
- package/dist/core/workspace-watcher.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/profiles/default.d.ts.map +1 -1
- package/dist/profiles/default.js +9 -14
- package/dist/profiles/default.js.map +1 -1
- package/dist/server/canvas.d.ts.map +1 -1
- package/dist/server/canvas.js +7 -7
- package/dist/server/canvas.js.map +1 -1
- package/dist/server/fs.d.ts.map +1 -1
- package/dist/server/fs.js +17 -1
- package/dist/server/fs.js.map +1 -1
- package/dist/server/index.d.ts +12 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +321 -50
- package/dist/server/index.js.map +1 -1
- package/dist/server/ingest.d.ts +11 -0
- package/dist/server/ingest.d.ts.map +1 -1
- package/dist/server/ingest.js +1 -0
- package/dist/server/ingest.js.map +1 -1
- package/dist/server/macros.d.ts +4 -6
- package/dist/server/macros.d.ts.map +1 -1
- package/dist/server/macros.js.map +1 -1
- package/dist/server/rest.d.ts +18 -6
- package/dist/server/rest.d.ts.map +1 -1
- package/dist/server/rest.js +185 -48
- package/dist/server/rest.js.map +1 -1
- package/dist/server/templates.d.ts +24 -0
- package/dist/server/templates.d.ts.map +1 -0
- package/dist/server/templates.js +54 -0
- package/dist/server/templates.js.map +1 -0
- package/dist/shared/types.d.ts +477 -29
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js +19 -11
- package/dist/shared/types.js.map +1 -1
- package/dist/web/assets/index-SYpugKQ1.css +32 -0
- package/dist/web/assets/index-vYYd44hZ.js +446 -0
- package/dist/web/index.html +2 -2
- package/package.json +5 -4
- package/dist/core/canvas-enrich.d.ts +0 -115
- package/dist/core/canvas-enrich.d.ts.map +0 -1
- package/dist/core/canvas-enrich.js +0 -186
- package/dist/core/canvas-enrich.js.map +0 -1
- package/dist/profiles/canvas-guidelines.d.ts +0 -20
- package/dist/profiles/canvas-guidelines.d.ts.map +0 -1
- package/dist/profiles/canvas-guidelines.js +0 -48
- package/dist/profiles/canvas-guidelines.js.map +0 -1
- package/dist/web/assets/index-DCtyI4VW.css +0 -32
- package/dist/web/assets/index-WSw5RvYR.js +0 -445
- package/dist/web/welcome-hero-dark.png +0 -0
- package/dist/web/welcome-hero-light.png +0 -0
package/dist/web/index.html
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
document.documentElement.dataset.theme = theme;
|
|
14
14
|
})();
|
|
15
15
|
</script>
|
|
16
|
-
<script type="module" crossorigin src="/assets/index-
|
|
17
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
16
|
+
<script type="module" crossorigin src="/assets/index-vYYd44hZ.js"></script>
|
|
17
|
+
<link rel="stylesheet" crossorigin href="/assets/index-SYpugKQ1.css">
|
|
18
18
|
</head>
|
|
19
19
|
<body>
|
|
20
20
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sapiom/harness",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Sapiom Harness — a CLI-launched local web app that runs your coding agent (Claude Code, Codex) in a Sapiom-configured environment: MCP pre-wired, workflows tracked, one-click deploy/run, and a live canvas for previews.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sapiom",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
"open": "^10.1.0",
|
|
48
48
|
"ws": "^8.18.0",
|
|
49
49
|
"zod": "^3.25.0",
|
|
50
|
-
"@sapiom/agent": "^0.
|
|
51
|
-
"@sapiom/agent-core": "^0.9.
|
|
50
|
+
"@sapiom/agent": "^0.7.0",
|
|
51
|
+
"@sapiom/agent-core": "^0.9.10",
|
|
52
52
|
"@sapiom/analytics-core": "^0.2.1",
|
|
53
53
|
"@sapiom/mcp": "^0.11.3"
|
|
54
54
|
},
|
|
@@ -87,7 +87,8 @@
|
|
|
87
87
|
"dev": "tsx src/cli/bin.ts --dev",
|
|
88
88
|
"dev:web": "vite --config web/vite.config.ts",
|
|
89
89
|
"start": "node dist/cli/bin.js",
|
|
90
|
-
"test": "vitest run",
|
|
90
|
+
"test": "vitest run && vitest run --config vitest.perf.config.ts",
|
|
91
|
+
"test:perf": "vitest run --config vitest.perf.config.ts",
|
|
91
92
|
"test:watch": "vitest",
|
|
92
93
|
"test:mutation": "stryker run",
|
|
93
94
|
"test:ui": "playwright test --config web/e2e/playwright.config.ts",
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The AI enrichment runner: spawns ONE bounded, headless agent task per
|
|
3
|
-
* workflow (via TaskManager) that reads the workflow's step bodies and
|
|
4
|
-
* returns the JSON `CanvasEnrichment` contract — never HTML, never a file
|
|
5
|
-
* write. On success the validated enrichment is persisted to the workflow's
|
|
6
|
-
* cache file and the render file is rebuilt with it merged in; on any
|
|
7
|
-
* parse/validation failure the enrichment is discarded whole and the base
|
|
8
|
-
* render stands (core/canvas-enrichment.ts's contract). Task-process
|
|
9
|
-
* failures surface through the task record itself (the pane's error state +
|
|
10
|
-
* Retry), never as HTML on disk.
|
|
11
|
-
*
|
|
12
|
-
* Triggering (see server/index.ts):
|
|
13
|
-
* - bind / session create → `ensureFresh`: spawn only when no cache entry
|
|
14
|
-
* matches the current source fingerprint; every skip reason is silent.
|
|
15
|
-
* - the visualize macro → `forceRefresh`: drop the extraction + enrichment
|
|
16
|
-
* caches, re-render the base immediately, re-enrich; refusals propagate
|
|
17
|
-
* (an already-running enrichment for this workflow → 409 via the macros
|
|
18
|
-
* router, exactly like any other double-fired background macro).
|
|
19
|
-
*
|
|
20
|
-
* Dedupe is per WORKFLOW, not per session: TaskManager refuses a second
|
|
21
|
-
* running task with the same macroId + workflowPath regardless of which
|
|
22
|
-
* session asked (see TaskAlreadyRunningError) — two panes bound to the same
|
|
23
|
-
* workflow can never race its cache/render files.
|
|
24
|
-
*/
|
|
25
|
-
import type { BackgroundTask, HarnessKind } from "../shared/types.js";
|
|
26
|
-
import { type CachedExtraction } from "./canvas-cache.js";
|
|
27
|
-
import type { CanvasGraph } from "./canvas-graph.js";
|
|
28
|
-
import { type RenderableWorkflow } from "./canvas-render.js";
|
|
29
|
-
import type { RunTaskRequest } from "./task-manager.js";
|
|
30
|
-
/** The macro identity enrichment tasks run under — the pane's Retry re-fires
|
|
31
|
-
* this macro, which routes back through forceRefresh. */
|
|
32
|
-
export declare const ENRICHMENT_MACRO_ID = "visualize";
|
|
33
|
-
/** Model the enrichment task runs on — overridable per install. */
|
|
34
|
-
export declare function enrichmentModel(env?: NodeJS.ProcessEnv): string;
|
|
35
|
-
/**
|
|
36
|
-
* Builds the one-shot enrichment prompt: the extracted graph inline (the AI
|
|
37
|
-
* annotates THIS structure — it never invents nodes), pointed at the step
|
|
38
|
-
* sources for semantics, with the JSON contract and its hard limits stated
|
|
39
|
-
* verbatim so a well-behaved run needs no retry.
|
|
40
|
-
*/
|
|
41
|
-
export declare function buildEnrichmentPrompt(graph: CanvasGraph, workflowDir: string): string;
|
|
42
|
-
/**
|
|
43
|
-
* Pulls the JSON object out of a task's final result text — either fenced
|
|
44
|
-
* (\`\`\`json ... \`\`\`) or raw, tolerating prose around it by falling back to
|
|
45
|
-
* the outermost {...} span. Null when nothing parses.
|
|
46
|
-
*/
|
|
47
|
-
export declare function extractEnrichmentJson(text: string): unknown | null;
|
|
48
|
-
/** The slice of TaskManager the runner uses — injectable for tests. */
|
|
49
|
-
export interface EnrichmentTaskRunner {
|
|
50
|
-
run(req: RunTaskRequest): Promise<BackgroundTask>;
|
|
51
|
-
onStatusChange(listener: (task: BackgroundTask) => void): () => void;
|
|
52
|
-
/** Returns true when an enrichment task for this workflow is currently
|
|
53
|
-
* running — checked before cache destruction in forceRefresh so a
|
|
54
|
-
* double-click Visualize is a true no-op, not a half-destroyed cache. */
|
|
55
|
-
isRunning(macroId: string, workflowPath: string): boolean;
|
|
56
|
-
}
|
|
57
|
-
/** The session shape the coordinator needs — satisfied by HarnessSession. */
|
|
58
|
-
export interface EnrichmentSession {
|
|
59
|
-
id: string;
|
|
60
|
-
cwd: string;
|
|
61
|
-
harness: HarnessKind;
|
|
62
|
-
boundWorkflowPath: string | null;
|
|
63
|
-
}
|
|
64
|
-
export interface EnrichmentCoordinatorOptions {
|
|
65
|
-
tasks: EnrichmentTaskRunner;
|
|
66
|
-
/** Rebuilds the workflow's render file (with the just-persisted enrichment
|
|
67
|
-
* merged) after a successful run — the write alone hot-reloads any open
|
|
68
|
-
* pane via the canvas watcher. */
|
|
69
|
-
rerender?: (cwd: string, workflow: RenderableWorkflow) => Promise<void>;
|
|
70
|
-
/** Injectable for tests — defaults to the real cached extraction. */
|
|
71
|
-
extractCached?: (dir: string) => Promise<CachedExtraction>;
|
|
72
|
-
env?: NodeJS.ProcessEnv;
|
|
73
|
-
now?: () => string;
|
|
74
|
-
onError?: (message: string) => void;
|
|
75
|
-
}
|
|
76
|
-
export declare class CanvasEnrichmentCoordinator {
|
|
77
|
-
private readonly tasks;
|
|
78
|
-
private readonly rerender;
|
|
79
|
-
private readonly extractCached;
|
|
80
|
-
private readonly env;
|
|
81
|
-
private readonly now;
|
|
82
|
-
private readonly onError;
|
|
83
|
-
constructor(options: EnrichmentCoordinatorOptions);
|
|
84
|
-
/**
|
|
85
|
-
* The bind/create trigger: spawn an enrichment task unless a cached
|
|
86
|
-
* enrichment already matches the workflow's current sources. Silent on
|
|
87
|
-
* every expected refusal — unbound session, failed extraction, fresh
|
|
88
|
-
* cache, an enrichment already in flight for this workflow, a harness
|
|
89
|
-
* with no headless mode, even a spawn failure (logged) — because nothing
|
|
90
|
-
* here was user-initiated and a bind must never fail on enrichment's
|
|
91
|
-
* account.
|
|
92
|
-
*/
|
|
93
|
-
ensureFresh(session: EnrichmentSession, workflows: readonly RenderableWorkflow[]): Promise<void>;
|
|
94
|
-
/**
|
|
95
|
-
* The visualize macro: invalidate both caches, re-render the base diagram
|
|
96
|
-
* immediately (instant feedback, honest content — no leftover enrichment
|
|
97
|
-
* from sources that may have changed), then re-enrich. Refusals propagate
|
|
98
|
-
* to the macros router (TaskAlreadyRunningError → 409,
|
|
99
|
-
* TaskNotSupportedError → 400). Unbound session: just a no-op, matching
|
|
100
|
-
* the deterministic render's own unbound contract.
|
|
101
|
-
*
|
|
102
|
-
* The already-running check happens BEFORE any cache destruction so that a
|
|
103
|
-
* double-click Visualize is a true no-op: the second call rejects with
|
|
104
|
-
* TaskAlreadyRunningError and the caches and render are left exactly as
|
|
105
|
-
* the still-running enrichment will need them.
|
|
106
|
-
*/
|
|
107
|
-
forceRefresh(session: EnrichmentSession, workflows: readonly RenderableWorkflow[]): Promise<void>;
|
|
108
|
-
private resolveBound;
|
|
109
|
-
private spawn;
|
|
110
|
-
/** Completed task → parse → validate → cache file → re-render. Any parse
|
|
111
|
-
* or validation failure discards the enrichment whole; the base render
|
|
112
|
-
* already on disk stands untouched. */
|
|
113
|
-
private persist;
|
|
114
|
-
}
|
|
115
|
-
//# sourceMappingURL=canvas-enrich.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-enrich.d.ts","sourceRoot":"","sources":["../../src/core/canvas-enrich.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAyD,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACjH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASrD,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD;0DAC0D;AAC1D,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAO/C,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE5E;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAuBrF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAgBlE;AAED,uEAAuE;AACvE,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAClD,cAAc,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACrE;;8EAE0E;IAC1E,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3D;AAED,6EAA6E;AAC7E,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,WAAW,CAAC;IACrB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,oBAAoB,CAAC;IAC5B;;uCAEmC;IACnC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,qEAAqE;IACrE,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,qBAAa,2BAA2B;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+D;IACxF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6C;IAC3E,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;gBAExC,OAAO,EAAE,4BAA4B;IASjD;;;;;;;;OAQG;IACG,WAAW,CAAC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,kBAAkB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAetG;;;;;;;;;;;;OAYG;IACG,YAAY,CAAC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,SAAS,kBAAkB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAcvG,OAAO,CAAC,YAAY;YAON,KAAK;IA+BnB;;4CAEwC;YAC1B,OAAO;CAqBtB"}
|
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { extractWorkflowGraphCached, invalidateExtractionCache } from "./canvas-cache.js";
|
|
2
|
-
import { ENRICHMENT_LIMITS, normalizeCanvasEnrichmentCandidate, parseCanvasEnrichment, readEnrichmentCacheFile, removeEnrichmentCacheFile, writeEnrichmentCacheFile, } from "./canvas-enrichment.js";
|
|
3
|
-
import { enrichmentCacheFileFor, renderWorkflowRenderFile, } from "./canvas-render.js";
|
|
4
|
-
import { TaskAlreadyRunningError, TaskNotSupportedError } from "./task-manager.js";
|
|
5
|
-
/** The macro identity enrichment tasks run under — the pane's Retry re-fires
|
|
6
|
-
* this macro, which routes back through forceRefresh. */
|
|
7
|
-
export const ENRICHMENT_MACRO_ID = "visualize";
|
|
8
|
-
const ENRICHMENT_TASK_LABEL = "Visualize";
|
|
9
|
-
/** Hard turn cap: read a few step files, answer. A run that needs more than
|
|
10
|
-
* this is off the rails, not thorough. */
|
|
11
|
-
const ENRICHMENT_MAX_TURNS = 8;
|
|
12
|
-
const DEFAULT_ENRICHMENT_MODEL = "sonnet";
|
|
13
|
-
/** Model the enrichment task runs on — overridable per install. */
|
|
14
|
-
export function enrichmentModel(env = process.env) {
|
|
15
|
-
return env.SAPIOM_HARNESS_VISUALIZE_MODEL || DEFAULT_ENRICHMENT_MODEL;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Builds the one-shot enrichment prompt: the extracted graph inline (the AI
|
|
19
|
-
* annotates THIS structure — it never invents nodes), pointed at the step
|
|
20
|
-
* sources for semantics, with the JSON contract and its hard limits stated
|
|
21
|
-
* verbatim so a well-behaved run needs no retry.
|
|
22
|
-
*/
|
|
23
|
-
export function buildEnrichmentPrompt(graph, workflowDir) {
|
|
24
|
-
const L = ENRICHMENT_LIMITS;
|
|
25
|
-
return `You are annotating an already-rendered workflow diagram. The diagram's structure below is fixed — you only supply short text annotations, as one JSON object.
|
|
26
|
-
|
|
27
|
-
Extracted workflow graph:
|
|
28
|
-
${JSON.stringify(graph, null, 2)}
|
|
29
|
-
|
|
30
|
-
Read the step run() bodies in ${workflowDir} to understand what each step actually does (what it calls, what it decides, why it branches), then RETURN ONLY a JSON object matching this schema — no prose before or after, no markdown required, and DO NOT write or modify any files:
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
"summary": "what this workflow does, one line (max ${L.summary} chars)",
|
|
34
|
-
"nodeDetails": { "<nodeId>": { "sublabel": "short annotation shown in the node (max ${L.sublabel} chars)", "description": "one sentence, shown on hover (max ${L.description} chars)" } },
|
|
35
|
-
"edgeLabels": { "<fromNodeId>-><toNodeId>": "intent/condition name (max ${L.edgeLabel} chars)" },
|
|
36
|
-
"notes": ["up to ${L.noteCount} facts worth knowing, each max ${L.note} chars"],
|
|
37
|
-
"layoutHints": { "groups": [{ "label": "group name (max ${L.groupLabel} chars)", "nodeIds": ["..."] }], "laneOrder": { "<layerIndex>": ["nodeId", "..."] } },
|
|
38
|
-
"crossWorkflow": "how this workflow ties into the project's other workflows, if it does (max ${L.crossWorkflow} chars)"
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
Rules:
|
|
42
|
-
- Every field is optional — omit what you have nothing useful for (omit, don't write null). Empty strings are worse than omissions.
|
|
43
|
-
- Use ONLY node ids that appear in the graph above.
|
|
44
|
-
- Length limits are hard caps and oversize strings get truncated mid-sentence — aim comfortably under each limit.
|
|
45
|
-
- Your final message must be exactly the JSON object.`;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Pulls the JSON object out of a task's final result text — either fenced
|
|
49
|
-
* (\`\`\`json ... \`\`\`) or raw, tolerating prose around it by falling back to
|
|
50
|
-
* the outermost {...} span. Null when nothing parses.
|
|
51
|
-
*/
|
|
52
|
-
export function extractEnrichmentJson(text) {
|
|
53
|
-
const fenced = /```(?:json)?\s*([\s\S]*?)```/.exec(text);
|
|
54
|
-
const candidates = [fenced?.[1], text];
|
|
55
|
-
const first = text.indexOf("{");
|
|
56
|
-
const last = text.lastIndexOf("}");
|
|
57
|
-
if (first !== -1 && last > first)
|
|
58
|
-
candidates.push(text.slice(first, last + 1));
|
|
59
|
-
for (const candidate of candidates) {
|
|
60
|
-
if (!candidate)
|
|
61
|
-
continue;
|
|
62
|
-
try {
|
|
63
|
-
const parsed = JSON.parse(candidate.trim());
|
|
64
|
-
if (typeof parsed === "object" && parsed !== null)
|
|
65
|
-
return parsed;
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
// Try the next candidate shape.
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
export class CanvasEnrichmentCoordinator {
|
|
74
|
-
constructor(options) {
|
|
75
|
-
this.tasks = options.tasks;
|
|
76
|
-
this.rerender = options.rerender ?? (async (cwd, workflow) => void (await renderWorkflowRenderFile(cwd, workflow)));
|
|
77
|
-
this.extractCached = options.extractCached ?? extractWorkflowGraphCached;
|
|
78
|
-
this.env = options.env ?? process.env;
|
|
79
|
-
this.now = options.now ?? (() => new Date().toISOString());
|
|
80
|
-
this.onError = options.onError ?? ((message) => console.error(`[harness] ${message}`));
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* The bind/create trigger: spawn an enrichment task unless a cached
|
|
84
|
-
* enrichment already matches the workflow's current sources. Silent on
|
|
85
|
-
* every expected refusal — unbound session, failed extraction, fresh
|
|
86
|
-
* cache, an enrichment already in flight for this workflow, a harness
|
|
87
|
-
* with no headless mode, even a spawn failure (logged) — because nothing
|
|
88
|
-
* here was user-initiated and a bind must never fail on enrichment's
|
|
89
|
-
* account.
|
|
90
|
-
*/
|
|
91
|
-
async ensureFresh(session, workflows) {
|
|
92
|
-
const bound = this.resolveBound(session, workflows);
|
|
93
|
-
if (!bound)
|
|
94
|
-
return;
|
|
95
|
-
try {
|
|
96
|
-
const { result, fingerprint } = await this.extractCached(bound.path);
|
|
97
|
-
if (!result.ok)
|
|
98
|
-
return;
|
|
99
|
-
const entry = await readEnrichmentCacheFile(enrichmentCacheFileFor(session.cwd, bound.path));
|
|
100
|
-
if (entry && entry.sourceFingerprint === fingerprint)
|
|
101
|
-
return;
|
|
102
|
-
await this.spawn(session, bound, result.graph, fingerprint);
|
|
103
|
-
}
|
|
104
|
-
catch (err) {
|
|
105
|
-
if (err instanceof TaskAlreadyRunningError || err instanceof TaskNotSupportedError)
|
|
106
|
-
return;
|
|
107
|
-
this.onError(`canvas enrichment (auto) failed to start: ${err.message}`);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* The visualize macro: invalidate both caches, re-render the base diagram
|
|
112
|
-
* immediately (instant feedback, honest content — no leftover enrichment
|
|
113
|
-
* from sources that may have changed), then re-enrich. Refusals propagate
|
|
114
|
-
* to the macros router (TaskAlreadyRunningError → 409,
|
|
115
|
-
* TaskNotSupportedError → 400). Unbound session: just a no-op, matching
|
|
116
|
-
* the deterministic render's own unbound contract.
|
|
117
|
-
*
|
|
118
|
-
* The already-running check happens BEFORE any cache destruction so that a
|
|
119
|
-
* double-click Visualize is a true no-op: the second call rejects with
|
|
120
|
-
* TaskAlreadyRunningError and the caches and render are left exactly as
|
|
121
|
-
* the still-running enrichment will need them.
|
|
122
|
-
*/
|
|
123
|
-
async forceRefresh(session, workflows) {
|
|
124
|
-
const bound = this.resolveBound(session, workflows);
|
|
125
|
-
if (!bound)
|
|
126
|
-
return;
|
|
127
|
-
if (this.tasks.isRunning(ENRICHMENT_MACRO_ID, bound.path)) {
|
|
128
|
-
throw new TaskAlreadyRunningError(ENRICHMENT_TASK_LABEL);
|
|
129
|
-
}
|
|
130
|
-
invalidateExtractionCache(bound.path);
|
|
131
|
-
await removeEnrichmentCacheFile(enrichmentCacheFileFor(session.cwd, bound.path));
|
|
132
|
-
await this.rerender(session.cwd, bound);
|
|
133
|
-
const { result, fingerprint } = await this.extractCached(bound.path);
|
|
134
|
-
if (!result.ok)
|
|
135
|
-
return;
|
|
136
|
-
await this.spawn(session, bound, result.graph, fingerprint);
|
|
137
|
-
}
|
|
138
|
-
resolveBound(session, workflows) {
|
|
139
|
-
return session.boundWorkflowPath ? workflows.find((w) => w.path === session.boundWorkflowPath) : undefined;
|
|
140
|
-
}
|
|
141
|
-
async spawn(session, workflow, graph, fingerprint) {
|
|
142
|
-
const task = await this.tasks.run({
|
|
143
|
-
macroId: ENRICHMENT_MACRO_ID,
|
|
144
|
-
label: ENRICHMENT_TASK_LABEL,
|
|
145
|
-
harnessSessionId: session.id,
|
|
146
|
-
harness: session.harness,
|
|
147
|
-
cwd: session.cwd,
|
|
148
|
-
prompt: buildEnrichmentPrompt(graph, workflow.path),
|
|
149
|
-
workflowPath: workflow.path,
|
|
150
|
-
model: enrichmentModel(this.env),
|
|
151
|
-
maxTurns: ENRICHMENT_MAX_TURNS,
|
|
152
|
-
});
|
|
153
|
-
// Subscribed synchronously right after run() resolves — the process's
|
|
154
|
-
// exit can only arrive via a later event-loop turn, so the terminal
|
|
155
|
-
// status can't be missed.
|
|
156
|
-
const unsubscribe = this.tasks.onStatusChange((update) => {
|
|
157
|
-
if (update.id !== task.id || update.status === "running")
|
|
158
|
-
return;
|
|
159
|
-
unsubscribe();
|
|
160
|
-
if (update.status !== "completed")
|
|
161
|
-
return; // pane shows the failure; nothing to persist
|
|
162
|
-
void this.persist(session.cwd, workflow, graph, fingerprint, update.resultText).catch((err) => {
|
|
163
|
-
this.onError(`canvas enrichment persist failed: ${err.message}`);
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
/** Completed task → parse → validate → cache file → re-render. Any parse
|
|
168
|
-
* or validation failure discards the enrichment whole; the base render
|
|
169
|
-
* already on disk stands untouched. */
|
|
170
|
-
async persist(cwd, workflow, graph, fingerprint, resultText) {
|
|
171
|
-
const candidate = resultText ? extractEnrichmentJson(resultText) : null;
|
|
172
|
-
const enrichment = candidate ? parseCanvasEnrichment(normalizeCanvasEnrichmentCandidate(candidate)) : null;
|
|
173
|
-
if (!enrichment) {
|
|
174
|
-
this.onError(`canvas enrichment for ${workflow.path} returned invalid output — discarded, base render stands`);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
await writeEnrichmentCacheFile(enrichmentCacheFileFor(cwd, workflow.path), {
|
|
178
|
-
graph,
|
|
179
|
-
enrichment,
|
|
180
|
-
sourceFingerprint: fingerprint,
|
|
181
|
-
enrichedAt: this.now(),
|
|
182
|
-
});
|
|
183
|
-
await this.rerender(cwd, workflow);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
//# sourceMappingURL=canvas-enrich.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-enrich.js","sourceRoot":"","sources":["../../src/core/canvas-enrich.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canvas style contract: injected everywhere an agent is asked to write to
|
|
3
|
-
* `.sapiom/canvas/index.html` (the Visualize macro's inject text, and the
|
|
4
|
-
* system prompt's canvas paragraph for freeform "show me X" asks), so every
|
|
5
|
-
* generated canvas looks Sapiom-native regardless of which prompt triggered
|
|
6
|
-
* it. Kept prompt-sized on purpose — this rides in prompts, not docs.
|
|
7
|
-
*
|
|
8
|
-
* Colors are the harness's own dark-theme tokens (web/src/styles.css,
|
|
9
|
-
* `[data-theme="dark"]`) — dark is the canonical canvas look. Structural
|
|
10
|
-
* conventions (rounded nodes with a uniform glow, straight-then-curved
|
|
11
|
-
* arrowed edges, stats header, legend footer) mirror what
|
|
12
|
-
* scripts/seed-example.mjs's reference canvas already renders; this doesn't
|
|
13
|
-
* change that seed, just documents its pattern for agents generating new
|
|
14
|
-
* ones. Edge/glow/legend wording tightened after a live Visualize proof
|
|
15
|
-
* (see PR history) surfaced ambiguities two different agent runs resolved
|
|
16
|
-
* inconsistently — see git blame for the before/after if the wording here
|
|
17
|
-
* ever seems oddly specific.
|
|
18
|
-
*/
|
|
19
|
-
export declare const CANVAS_STYLE_GUIDELINES: string;
|
|
20
|
-
//# sourceMappingURL=canvas-guidelines.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-guidelines.d.ts","sourceRoot":"","sources":["../../src/profiles/canvas-guidelines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,uBAAuB,QA4B5B,CAAC"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canvas style contract: injected everywhere an agent is asked to write to
|
|
3
|
-
* `.sapiom/canvas/index.html` (the Visualize macro's inject text, and the
|
|
4
|
-
* system prompt's canvas paragraph for freeform "show me X" asks), so every
|
|
5
|
-
* generated canvas looks Sapiom-native regardless of which prompt triggered
|
|
6
|
-
* it. Kept prompt-sized on purpose — this rides in prompts, not docs.
|
|
7
|
-
*
|
|
8
|
-
* Colors are the harness's own dark-theme tokens (web/src/styles.css,
|
|
9
|
-
* `[data-theme="dark"]`) — dark is the canonical canvas look. Structural
|
|
10
|
-
* conventions (rounded nodes with a uniform glow, straight-then-curved
|
|
11
|
-
* arrowed edges, stats header, legend footer) mirror what
|
|
12
|
-
* scripts/seed-example.mjs's reference canvas already renders; this doesn't
|
|
13
|
-
* change that seed, just documents its pattern for agents generating new
|
|
14
|
-
* ones. Edge/glow/legend wording tightened after a live Visualize proof
|
|
15
|
-
* (see PR history) surfaced ambiguities two different agent runs resolved
|
|
16
|
-
* inconsistently — see git blame for the before/after if the wording here
|
|
17
|
-
* ever seems oddly specific.
|
|
18
|
-
*/
|
|
19
|
-
export const CANVAS_STYLE_GUIDELINES = `
|
|
20
|
-
Canvas style contract (.sapiom/canvas/index.html):
|
|
21
|
-
- One self-contained HTML file: inline all CSS/JS, no external stylesheets/
|
|
22
|
-
scripts or CDN fonts (the CSP blocks them) — no build step, no dependencies.
|
|
23
|
-
- Dark theme, Sapiom palette: background #0f0f0f, panel #1a1a1a, border
|
|
24
|
-
#2e2e2e, text #fafafa, dim text #a1a1aa, accent/success #6be195, escalation
|
|
25
|
-
#f59e0b, failure #f87171.
|
|
26
|
-
- Monospace throughout: ui-monospace, "SF Mono", Menlo, Consolas, monospace.
|
|
27
|
-
- Header: title + short status badge, one-line subtitle, and a stats row
|
|
28
|
-
(e.g. step count, terminal-outcome count, branch count) as label/value pairs.
|
|
29
|
-
- Render the workflow as an inline SVG graph, top-to-bottom: rounded-rect
|
|
30
|
-
nodes (12-16px radius). Every node gets the same subtle glow on its
|
|
31
|
-
border — never reserve the glow for entry/terminal nodes only; role and
|
|
32
|
-
outcome are conveyed by border/stroke color, not by which nodes glow.
|
|
33
|
-
- Edges: straight lines with arrowhead markers for a single-successor step,
|
|
34
|
-
curved paths with arrowhead markers only where a step branches into
|
|
35
|
-
multiple successors — don't curve every edge, that reads as noise on a
|
|
36
|
-
simple linear chain.
|
|
37
|
-
- Color-code terminal outcomes by meaning: accent/green = success, amber =
|
|
38
|
-
escalation/needs-attention, red = failure. Reserve those colors for actual
|
|
39
|
-
terminal branches, not regular steps.
|
|
40
|
-
- Footer legend: one visually distinct marker per node kind used (shape
|
|
41
|
-
and/or fill vs. outline — never reuse the identical marker for two
|
|
42
|
-
different kinds just because they happen to share a color) + label, plus
|
|
43
|
-
a short note that this is a static preview to regenerate after the
|
|
44
|
-
workflow changes.
|
|
45
|
-
- Prefer clarity over decoration: no motion, gradients, or ornamentation that
|
|
46
|
-
doesn't help someone understand the graph's structure in a few seconds.
|
|
47
|
-
`.trim();
|
|
48
|
-
//# sourceMappingURL=canvas-guidelines.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-guidelines.js","sourceRoot":"","sources":["../../src/profiles/canvas-guidelines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BtC,CAAC,IAAI,EAAE,CAAC"}
|