@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
|
@@ -3,6 +3,13 @@ import * as path from "node:path";
|
|
|
3
3
|
import { CANVAS_DIR } from "../shared/types.js";
|
|
4
4
|
const DEBOUNCE_MS = 150;
|
|
5
5
|
const POLL_INTERVAL_MS = 500;
|
|
6
|
+
/** Directories a workflow-source walk never descends into (heavy or generated)
|
|
7
|
+
* — mirrors core/canvas-interconnections.ts's `listSourceFiles`. */
|
|
8
|
+
const SKIP_DIR_NAMES = new Set(["node_modules", ".git", "dist", "build", ".sapiom"]);
|
|
9
|
+
const SOURCE_EXTENSIONS = new Set([".ts", ".tsx"]);
|
|
10
|
+
/** Bounds the polling snapshot walk — the extraction itself already caps at
|
|
11
|
+
* 200 files; this is just a defensive ceiling on the fingerprint cost. */
|
|
12
|
+
const MAX_SOURCE_FILES = 400;
|
|
6
13
|
/**
|
|
7
14
|
* Cheap change fingerprint for a directory tree: sorted `path:mtime:size`
|
|
8
15
|
* entries. Used by the polling fallback (and directly testable on its own)
|
|
@@ -28,57 +35,120 @@ export function snapshotCanvasDir(canvasDir) {
|
|
|
28
35
|
return parts.sort().join("|");
|
|
29
36
|
}
|
|
30
37
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
|
|
38
|
+
* Cheap change fingerprint over a project's own `.ts`/`.tsx` sources (skipping
|
|
39
|
+
* node_modules/dist/.git/.sapiom), the polling fallback's equivalent of
|
|
40
|
+
* `snapshotCanvasDir` for the workflow SOURCE — so an editor save on a step
|
|
41
|
+
* file is noticed on platforms without recursive `fs.watch` too. Bounded and
|
|
42
|
+
* total: an unreadable dir simply contributes nothing.
|
|
43
|
+
*/
|
|
44
|
+
export function snapshotWorkflowSources(root) {
|
|
45
|
+
const parts = [];
|
|
46
|
+
const walk = (dir) => {
|
|
47
|
+
if (parts.length >= MAX_SOURCE_FILES)
|
|
48
|
+
return;
|
|
49
|
+
let entries;
|
|
50
|
+
try {
|
|
51
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
for (const entry of entries) {
|
|
57
|
+
if (parts.length >= MAX_SOURCE_FILES)
|
|
58
|
+
return;
|
|
59
|
+
const full = path.join(dir, entry.name);
|
|
60
|
+
if (entry.isDirectory()) {
|
|
61
|
+
if (SKIP_DIR_NAMES.has(entry.name))
|
|
62
|
+
continue;
|
|
63
|
+
walk(full);
|
|
64
|
+
}
|
|
65
|
+
else if (SOURCE_EXTENSIONS.has(path.extname(entry.name))) {
|
|
66
|
+
try {
|
|
67
|
+
const stat = fs.statSync(full);
|
|
68
|
+
parts.push(`${full}:${stat.mtimeMs}:${stat.size}`);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
parts.push(`${full}:gone`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
walk(root);
|
|
77
|
+
return parts.sort().join("|");
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* One session's watcher. Watches the whole project root recursively and routes
|
|
81
|
+
* each change: a change under CANVAS_DIR is a rendered-output change (reload
|
|
82
|
+
* the iframe); a `.ts`/`.tsx` change anywhere else is a workflow-source change
|
|
83
|
+
* (re-render). No separate "wait for the dir to appear" phase, and it survives
|
|
84
|
+
* the canvas dir itself being deleted/recreated. Falls back to polling two
|
|
85
|
+
* directory-tree fingerprints (canvas output + sources) when recursive
|
|
86
|
+
* `fs.watch` isn't available (notably Linux) or the watcher errors out.
|
|
37
87
|
*/
|
|
38
88
|
class SessionCanvasWatcher {
|
|
39
|
-
constructor(cwd, harnessSessionId,
|
|
89
|
+
constructor(cwd, harnessSessionId, callbacks) {
|
|
40
90
|
this.cwd = cwd;
|
|
41
91
|
this.harnessSessionId = harnessSessionId;
|
|
42
|
-
this.
|
|
92
|
+
this.callbacks = callbacks;
|
|
43
93
|
this.watcher = null;
|
|
44
94
|
this.pollTimer = null;
|
|
45
|
-
this.
|
|
95
|
+
this.canvasDebounceTimer = null;
|
|
96
|
+
this.sourceDebounceTimer = null;
|
|
46
97
|
this.closed = false;
|
|
47
98
|
this.lastSnapshot = "";
|
|
99
|
+
this.lastSourceSnapshot = "";
|
|
48
100
|
this.canvasDir = path.join(cwd, CANVAS_DIR);
|
|
49
101
|
this.canvasPrefix = CANVAS_DIR + path.sep;
|
|
50
102
|
this.arm();
|
|
51
103
|
}
|
|
52
|
-
|
|
104
|
+
scheduleCanvasChange() {
|
|
53
105
|
if (this.closed)
|
|
54
106
|
return;
|
|
55
|
-
if (this.
|
|
56
|
-
clearTimeout(this.
|
|
57
|
-
this.
|
|
107
|
+
if (this.canvasDebounceTimer)
|
|
108
|
+
clearTimeout(this.canvasDebounceTimer);
|
|
109
|
+
this.canvasDebounceTimer = setTimeout(() => this.callbacks.onCanvasChange(this.harnessSessionId), DEBOUNCE_MS);
|
|
110
|
+
}
|
|
111
|
+
scheduleSourceChange() {
|
|
112
|
+
if (this.closed)
|
|
113
|
+
return;
|
|
114
|
+
if (this.sourceDebounceTimer)
|
|
115
|
+
clearTimeout(this.sourceDebounceTimer);
|
|
116
|
+
this.sourceDebounceTimer = setTimeout(() => this.callbacks.onSourceChange(this.harnessSessionId), DEBOUNCE_MS);
|
|
58
117
|
}
|
|
59
118
|
isCanvasPath(filename) {
|
|
60
|
-
// A `null` filename means the platform couldn't report which path
|
|
61
|
-
// changed — reload to be safe rather than miss an update.
|
|
62
|
-
if (!filename)
|
|
63
|
-
return true;
|
|
64
119
|
return filename === CANVAS_DIR || filename.startsWith(this.canvasPrefix);
|
|
65
120
|
}
|
|
121
|
+
isWorkflowSourcePath(filename) {
|
|
122
|
+
if (!SOURCE_EXTENSIONS.has(path.extname(filename)))
|
|
123
|
+
return false;
|
|
124
|
+
return !filename.split(path.sep).some((seg) => SKIP_DIR_NAMES.has(seg));
|
|
125
|
+
}
|
|
66
126
|
arm() {
|
|
67
127
|
if (this.closed)
|
|
68
128
|
return;
|
|
69
129
|
try {
|
|
70
130
|
this.watcher = fs.watch(this.cwd, { recursive: true }, (event, filename) => {
|
|
71
|
-
|
|
131
|
+
// A `null` filename means the platform couldn't report which path
|
|
132
|
+
// changed — do both (reload AND re-render) rather than miss an update.
|
|
133
|
+
if (filename === null) {
|
|
134
|
+
this.scheduleCanvasChange();
|
|
135
|
+
this.scheduleSourceChange();
|
|
72
136
|
return;
|
|
73
|
-
this.scheduleChange();
|
|
74
|
-
// A rename at (or above) the canvas dir — e.g. an editor's atomic
|
|
75
|
-
// write-then-rename, or the agent `mkdir -p`'ing it for the first
|
|
76
|
-
// time — can leave a recursive watcher no longer covering the new
|
|
77
|
-
// inode on some platforms. Re-arm defensively rather than risk
|
|
78
|
-
// silently going deaf.
|
|
79
|
-
if (event === "rename" && (filename === CANVAS_DIR || filename === path.dirname(CANVAS_DIR))) {
|
|
80
|
-
this.rearm();
|
|
81
137
|
}
|
|
138
|
+
if (this.isCanvasPath(filename)) {
|
|
139
|
+
this.scheduleCanvasChange();
|
|
140
|
+
// A rename at (or above) the canvas dir — e.g. an editor's atomic
|
|
141
|
+
// write-then-rename, or the agent `mkdir -p`'ing it for the first
|
|
142
|
+
// time — can leave a recursive watcher no longer covering the new
|
|
143
|
+
// inode on some platforms. Re-arm defensively rather than risk
|
|
144
|
+
// silently going deaf.
|
|
145
|
+
if (event === "rename" && (filename === CANVAS_DIR || filename === path.dirname(CANVAS_DIR))) {
|
|
146
|
+
this.rearm();
|
|
147
|
+
}
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (this.isWorkflowSourcePath(filename))
|
|
151
|
+
this.scheduleSourceChange();
|
|
82
152
|
});
|
|
83
153
|
this.watcher.on("error", () => this.fallBackToPolling());
|
|
84
154
|
}
|
|
@@ -98,18 +168,26 @@ class SessionCanvasWatcher {
|
|
|
98
168
|
this.watcher?.close();
|
|
99
169
|
this.watcher = null;
|
|
100
170
|
this.lastSnapshot = snapshotCanvasDir(this.canvasDir);
|
|
171
|
+
this.lastSourceSnapshot = snapshotWorkflowSources(this.cwd);
|
|
101
172
|
this.pollTimer = setInterval(() => {
|
|
102
173
|
const snapshot = snapshotCanvasDir(this.canvasDir);
|
|
103
174
|
if (snapshot !== this.lastSnapshot) {
|
|
104
175
|
this.lastSnapshot = snapshot;
|
|
105
|
-
this.
|
|
176
|
+
this.scheduleCanvasChange();
|
|
177
|
+
}
|
|
178
|
+
const sourceSnapshot = snapshotWorkflowSources(this.cwd);
|
|
179
|
+
if (sourceSnapshot !== this.lastSourceSnapshot) {
|
|
180
|
+
this.lastSourceSnapshot = sourceSnapshot;
|
|
181
|
+
this.scheduleSourceChange();
|
|
106
182
|
}
|
|
107
183
|
}, POLL_INTERVAL_MS);
|
|
108
184
|
}
|
|
109
185
|
close() {
|
|
110
186
|
this.closed = true;
|
|
111
|
-
if (this.
|
|
112
|
-
clearTimeout(this.
|
|
187
|
+
if (this.canvasDebounceTimer)
|
|
188
|
+
clearTimeout(this.canvasDebounceTimer);
|
|
189
|
+
if (this.sourceDebounceTimer)
|
|
190
|
+
clearTimeout(this.sourceDebounceTimer);
|
|
113
191
|
if (this.pollTimer)
|
|
114
192
|
clearInterval(this.pollTimer);
|
|
115
193
|
this.watcher?.close();
|
|
@@ -126,7 +204,10 @@ export class CanvasWatcherManager {
|
|
|
126
204
|
* into a different cwd). */
|
|
127
205
|
start(harnessSessionId, cwd) {
|
|
128
206
|
this.stop(harnessSessionId);
|
|
129
|
-
this.watchers.set(harnessSessionId, new SessionCanvasWatcher(cwd, harnessSessionId,
|
|
207
|
+
this.watchers.set(harnessSessionId, new SessionCanvasWatcher(cwd, harnessSessionId, {
|
|
208
|
+
onCanvasChange: (id) => this.deps.onChange(id),
|
|
209
|
+
onSourceChange: (id) => this.deps.onSourceChange(id),
|
|
210
|
+
}));
|
|
130
211
|
}
|
|
131
212
|
stop(harnessSessionId) {
|
|
132
213
|
this.watchers.get(harnessSessionId)?.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-watcher.js","sourceRoot":"","sources":["../../src/core/canvas-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAa,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;YACtD,OAAO,GAAG,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,GAAG,KAAK,OAAO,CAAC;QACzB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"canvas-watcher.js","sourceRoot":"","sources":["../../src/core/canvas-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,14 @@ export interface NormalizeContext {
|
|
|
24
24
|
}
|
|
25
25
|
/** Stringify + truncate a value so a giant tool payload can't blow up storage. */
|
|
26
26
|
export declare function truncateForPayload(value: unknown, maxLength?: number): string;
|
|
27
|
+
/**
|
|
28
|
+
* The suffix {@link truncateForPayload} leaves behind, with the omitted count
|
|
29
|
+
* captured. Exported so every consumer that has to recognize truncated text —
|
|
30
|
+
* the record fold's `responseTruncated`, the archive's re-clip — tests for the
|
|
31
|
+
* same marker this function writes, instead of keeping its own copy of the
|
|
32
|
+
* format. No `g` flag: callers use `test`/`exec` freely.
|
|
33
|
+
*/
|
|
34
|
+
export declare const PAYLOAD_TRUNCATION_MARKER: RegExp;
|
|
27
35
|
/**
|
|
28
36
|
* Normalize one Claude Code hook invocation into an AnalyticsEvent, or
|
|
29
37
|
* `null` when the hook doesn't map to an analytics event (PreToolUse, or an
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../../../src/core/collector/normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAsB,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE7F,sEAAsE;AACtE,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,kBAAkB,GAClB,YAAY,GACZ,aAAa,GACb,MAAM,GACN,YAAY,CAAC;AAEjB,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kGAAkG;IAClG,GAAG,EAAE,MAAM,CAAC;CACb;AAiBD,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAmB,GAAG,MAAM,CAIvF;AA+
|
|
1
|
+
{"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../../../src/core/collector/normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAsB,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE7F,sEAAsE;AACtE,MAAM,MAAM,eAAe,GACvB,cAAc,GACd,kBAAkB,GAClB,YAAY,GACZ,aAAa,GACb,MAAM,GACN,YAAY,CAAC;AAEjB,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,4EAA4E;IAC5E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,kGAAkG;IAClG,GAAG,EAAE,MAAM,CAAC;CACb;AAiBD,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAmB,GAAG,MAAM,CAIvF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,QAAgC,CAAC;AA+CvE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,gBAAgB,GACxB,cAAc,GAAG,IAAI,CAmBvB"}
|
|
@@ -27,6 +27,14 @@ export function truncateForPayload(value, maxLength = MAX_FIELD_LENGTH) {
|
|
|
27
27
|
return str;
|
|
28
28
|
return `${str.slice(0, maxLength)}…[truncated ${str.length - maxLength} chars]`;
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* The suffix {@link truncateForPayload} leaves behind, with the omitted count
|
|
32
|
+
* captured. Exported so every consumer that has to recognize truncated text —
|
|
33
|
+
* the record fold's `responseTruncated`, the archive's re-clip — tests for the
|
|
34
|
+
* same marker this function writes, instead of keeping its own copy of the
|
|
35
|
+
* format. No `g` flag: callers use `test`/`exec` freely.
|
|
36
|
+
*/
|
|
37
|
+
export const PAYLOAD_TRUNCATION_MARKER = /…\[truncated (\d+) chars\]$/;
|
|
30
38
|
function stringField(payload, key) {
|
|
31
39
|
const value = payload[key];
|
|
32
40
|
return typeof value === "string" ? value : undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizer.js","sourceRoot":"","sources":["../../../src/core/collector/normalizer.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"normalizer.js","sourceRoot":"","sources":["../../../src/core/collector/normalizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,8 +9,60 @@
|
|
|
9
9
|
* never overlap with an in-flight append and no appended line can be lost
|
|
10
10
|
* in a sweep's read window. Overhead is negligible — appends are low-frequency
|
|
11
11
|
* (one per hook event), and the queue never holds more than O(sessions) entries.
|
|
12
|
+
*
|
|
13
|
+
* Reads (`read`, `index`) run deliberately OUTSIDE that queue: an append is a
|
|
14
|
+
* single `appendFile` of one line, so a reader can never be left waiting out a
|
|
15
|
+
* half-written record it would otherwise have to skip — the worst case is a
|
|
16
|
+
* torn final line from a crash, which the parser drops. Blocking writers
|
|
17
|
+
* behind a 50 MB scan to buy nothing would be the wrong trade.
|
|
18
|
+
*
|
|
19
|
+
* Index: reading one session's events must not rescan the whole file (capped
|
|
20
|
+
* at 50 MB — see store-retention.ts). The index maps each harnessSessionId to
|
|
21
|
+
* the byte spans its lines occupy. It is built lazily on the first read and
|
|
22
|
+
* maintained incrementally after that: each subsequent read scans only the
|
|
23
|
+
* bytes appended since the last one — by this process or by a second harness
|
|
24
|
+
* boot writing to the same file, which is why the trigger is the file's size
|
|
25
|
+
* rather than our own append path. A shrink or an inode change means the file
|
|
26
|
+
* was rewritten underneath us (a retention sweep), which invalidates every
|
|
27
|
+
* offset, so the index is rebuilt from scratch.
|
|
12
28
|
*/
|
|
13
|
-
import { type AnalyticsEvent } from "../../shared/types.js";
|
|
29
|
+
import { type AnalyticsEvent, type AnalyticsEventType, type HarnessKind } from "../../shared/types.js";
|
|
30
|
+
/** A half-open byte range `[start, end)` of the ndjson file. */
|
|
31
|
+
export interface ByteSpan {
|
|
32
|
+
start: number;
|
|
33
|
+
end: number;
|
|
34
|
+
}
|
|
35
|
+
/** What the index knows about one harnessSessionId. */
|
|
36
|
+
export interface EventIndexEntry {
|
|
37
|
+
harnessSessionId: string;
|
|
38
|
+
/** Byte spans holding this session's lines, ascending, adjacent ones merged. */
|
|
39
|
+
spans: ByteSpan[];
|
|
40
|
+
/** Total events recorded for the session. */
|
|
41
|
+
eventCount: number;
|
|
42
|
+
/** `prompt.submitted` events — the exact human-turn count, at any file size. */
|
|
43
|
+
turnCount: number;
|
|
44
|
+
/** Agent session ids seen on this session's events, in first-seen order. */
|
|
45
|
+
agentSessionIds: string[];
|
|
46
|
+
/** Harness kind from the session's first event carrying one. */
|
|
47
|
+
harness: HarnessKind | null;
|
|
48
|
+
/** ISO-8601 `ts` of the first / last event seen for the session. */
|
|
49
|
+
firstTs: string | null;
|
|
50
|
+
lastTs: string | null;
|
|
51
|
+
}
|
|
52
|
+
export interface EventIndex {
|
|
53
|
+
/** Keyed by harnessSessionId. */
|
|
54
|
+
bySession: ReadonlyMap<string, EventIndexEntry>;
|
|
55
|
+
/** agentSessionId → harnessSessionIds that reported it, in first-seen order. */
|
|
56
|
+
byAgentSession: ReadonlyMap<string, readonly string[]>;
|
|
57
|
+
}
|
|
58
|
+
export interface EventReadFilter {
|
|
59
|
+
/** One or more harnessSessionIds. Index-accelerated: only those byte spans
|
|
60
|
+
* are read, never the whole file. */
|
|
61
|
+
harnessSessionId?: string | readonly string[];
|
|
62
|
+
/** Keep only these event types. Applied after parsing (the type isn't part
|
|
63
|
+
* of the index key, so it saves parsing work for the caller, not I/O). */
|
|
64
|
+
types?: readonly AnalyticsEventType[];
|
|
65
|
+
}
|
|
14
66
|
export interface EventStore {
|
|
15
67
|
/** Append one event as a single ndjson line, serialized through the queue. */
|
|
16
68
|
append(event: AnalyticsEvent): Promise<void>;
|
|
@@ -21,9 +73,31 @@ export interface EventStore {
|
|
|
21
73
|
*
|
|
22
74
|
* A failed `fn` never poisons the queue (later appends proceed normally).
|
|
23
75
|
* The return value of `fn` is forwarded to the caller.
|
|
76
|
+
*
|
|
77
|
+
* The byte-offset index is dropped on entry: a sweep rewrites the file, so
|
|
78
|
+
* every offset it holds is presumed stale.
|
|
24
79
|
*/
|
|
25
80
|
runExclusive<T>(fn: () => Promise<T>): Promise<T>;
|
|
81
|
+
/**
|
|
82
|
+
* Stream matching events in file order (= append order, which is only
|
|
83
|
+
* roughly `ts` order; callers needing a strict order sort by `(ts, seq)` —
|
|
84
|
+
* see core/session-record.ts).
|
|
85
|
+
*
|
|
86
|
+
* Runs outside the append queue. Unparseable lines — including a torn final
|
|
87
|
+
* line from a crash mid-append — are skipped, never thrown on. Yields
|
|
88
|
+
* nothing when the file doesn't exist yet.
|
|
89
|
+
*/
|
|
90
|
+
read(filter?: EventReadFilter): AsyncIterable<AnalyticsEvent>;
|
|
91
|
+
/**
|
|
92
|
+
* The byte-offset index, built on first call and extended on later ones by
|
|
93
|
+
* scanning only the bytes appended since. Reconciles against the file on
|
|
94
|
+
* every call, so it is always as fresh as the moment it was asked for. Empty
|
|
95
|
+
* when the file doesn't exist.
|
|
96
|
+
*/
|
|
97
|
+
index(): Promise<EventIndex>;
|
|
26
98
|
}
|
|
99
|
+
/** Minimal read surface — what session-record.ts actually needs from a store. */
|
|
100
|
+
export type EventReader = Pick<EventStore, "read" | "index">;
|
|
27
101
|
/**
|
|
28
102
|
* @param filePath Defaults to `HARNESS_PATHS.events`
|
|
29
103
|
* (`~/.sapiom/harness/events.ndjson`). Override in tests.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/core/collector/store.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/core/collector/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAQH,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAM/B,gEAAgE;AAChE,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gEAAgE;IAChE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,oEAAoE;IACpE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAChD,gFAAgF;IAChF,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;CACxD;AAED,MAAM,WAAW,eAAe;IAC9B;0CACsC;IACtC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IAC9C;+EAC2E;IAC3E,KAAK,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;;;;;;;;OAUG;IACH,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAClD;;;;;;;;OAQG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;IAC9D;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;CAC9B;AAED,iFAAiF;AACjF,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;AAmD7D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,MAA6B,GAAG,UAAU,CA8SpF"}
|