@sapiom/harness 0.1.6 → 0.2.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.
Files changed (185) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/dist/cli/args.d.ts +16 -0
  3. package/dist/cli/args.d.ts.map +1 -0
  4. package/dist/cli/args.js +80 -0
  5. package/dist/cli/args.js.map +1 -0
  6. package/dist/cli/bin.js +12 -65
  7. package/dist/cli/bin.js.map +1 -1
  8. package/dist/cli/settings.d.ts.map +1 -1
  9. package/dist/cli/settings.js +33 -1
  10. package/dist/cli/settings.js.map +1 -1
  11. package/dist/core/adapters/claude-code.d.ts +60 -2
  12. package/dist/core/adapters/claude-code.d.ts.map +1 -1
  13. package/dist/core/adapters/claude-code.js +119 -32
  14. package/dist/core/adapters/claude-code.js.map +1 -1
  15. package/dist/core/adapters/codex.d.ts +21 -2
  16. package/dist/core/adapters/codex.d.ts.map +1 -1
  17. package/dist/core/adapters/codex.js +53 -2
  18. package/dist/core/adapters/codex.js.map +1 -1
  19. package/dist/core/adapters/detect.d.ts +9 -0
  20. package/dist/core/adapters/detect.d.ts.map +1 -1
  21. package/dist/core/adapters/detect.js +9 -0
  22. package/dist/core/adapters/detect.js.map +1 -1
  23. package/dist/core/canvas-body.d.ts +28 -28
  24. package/dist/core/canvas-body.d.ts.map +1 -1
  25. package/dist/core/canvas-body.js +117 -55
  26. package/dist/core/canvas-body.js.map +1 -1
  27. package/dist/core/canvas-derive.d.ts +43 -0
  28. package/dist/core/canvas-derive.d.ts.map +1 -0
  29. package/dist/core/canvas-derive.js +95 -0
  30. package/dist/core/canvas-derive.js.map +1 -0
  31. package/dist/core/canvas-enrichment.d.ts +52 -127
  32. package/dist/core/canvas-enrichment.d.ts.map +1 -1
  33. package/dist/core/canvas-enrichment.js +17 -178
  34. package/dist/core/canvas-enrichment.js.map +1 -1
  35. package/dist/core/canvas-graph.d.ts +40 -1
  36. package/dist/core/canvas-graph.d.ts.map +1 -1
  37. package/dist/core/canvas-graph.js +71 -9
  38. package/dist/core/canvas-graph.js.map +1 -1
  39. package/dist/core/canvas-interconnections.d.ts +26 -8
  40. package/dist/core/canvas-interconnections.d.ts.map +1 -1
  41. package/dist/core/canvas-interconnections.js +132 -24
  42. package/dist/core/canvas-interconnections.js.map +1 -1
  43. package/dist/core/canvas-manifest-check.d.ts.map +1 -1
  44. package/dist/core/canvas-manifest-check.js +15 -2
  45. package/dist/core/canvas-manifest-check.js.map +1 -1
  46. package/dist/core/canvas-render.d.ts +8 -15
  47. package/dist/core/canvas-render.d.ts.map +1 -1
  48. package/dist/core/canvas-render.js +29 -41
  49. package/dist/core/canvas-render.js.map +1 -1
  50. package/dist/core/canvas-run-state.d.ts +41 -0
  51. package/dist/core/canvas-run-state.d.ts.map +1 -1
  52. package/dist/core/canvas-run-state.js +136 -0
  53. package/dist/core/canvas-run-state.js.map +1 -1
  54. package/dist/core/canvas-svg.d.ts +9 -4
  55. package/dist/core/canvas-svg.d.ts.map +1 -1
  56. package/dist/core/canvas-svg.js +84 -13
  57. package/dist/core/canvas-svg.js.map +1 -1
  58. package/dist/core/canvas-template.d.ts +9 -10
  59. package/dist/core/canvas-template.d.ts.map +1 -1
  60. package/dist/core/canvas-template.js +57 -20
  61. package/dist/core/canvas-template.js.map +1 -1
  62. package/dist/core/canvas-watcher.d.ts +22 -1
  63. package/dist/core/canvas-watcher.d.ts.map +1 -1
  64. package/dist/core/canvas-watcher.js +111 -30
  65. package/dist/core/canvas-watcher.js.map +1 -1
  66. package/dist/core/collector/normalizer.d.ts +8 -0
  67. package/dist/core/collector/normalizer.d.ts.map +1 -1
  68. package/dist/core/collector/normalizer.js +8 -0
  69. package/dist/core/collector/normalizer.js.map +1 -1
  70. package/dist/core/collector/store.d.ts +75 -1
  71. package/dist/core/collector/store.d.ts.map +1 -1
  72. package/dist/core/collector/store.js +334 -2
  73. package/dist/core/collector/store.js.map +1 -1
  74. package/dist/core/errors.d.ts +10 -4
  75. package/dist/core/errors.d.ts.map +1 -1
  76. package/dist/core/errors.js +11 -5
  77. package/dist/core/errors.js.map +1 -1
  78. package/dist/core/example-seed.d.ts +8 -0
  79. package/dist/core/example-seed.d.ts.map +1 -1
  80. package/dist/core/example-seed.js +47 -10
  81. package/dist/core/example-seed.js.map +1 -1
  82. package/dist/core/inject/system-prompt.d.ts +8 -0
  83. package/dist/core/inject/system-prompt.d.ts.map +1 -1
  84. package/dist/core/inject/system-prompt.js +3 -1
  85. package/dist/core/inject/system-prompt.js.map +1 -1
  86. package/dist/core/macros.d.ts.map +1 -1
  87. package/dist/core/macros.js +5 -6
  88. package/dist/core/macros.js.map +1 -1
  89. package/dist/core/paths.d.ts +1 -0
  90. package/dist/core/paths.d.ts.map +1 -1
  91. package/dist/core/paths.js +1 -0
  92. package/dist/core/paths.js.map +1 -1
  93. package/dist/core/record-archive.d.ts +187 -0
  94. package/dist/core/record-archive.d.ts.map +1 -0
  95. package/dist/core/record-archive.js +465 -0
  96. package/dist/core/record-archive.js.map +1 -0
  97. package/dist/core/rehydration.d.ts +72 -0
  98. package/dist/core/rehydration.d.ts.map +1 -0
  99. package/dist/core/rehydration.js +72 -0
  100. package/dist/core/rehydration.js.map +1 -0
  101. package/dist/core/resume-brief.d.ts +130 -0
  102. package/dist/core/resume-brief.d.ts.map +1 -0
  103. package/dist/core/resume-brief.js +404 -0
  104. package/dist/core/resume-brief.js.map +1 -0
  105. package/dist/core/rolling-summary.d.ts +130 -0
  106. package/dist/core/rolling-summary.d.ts.map +1 -0
  107. package/dist/core/rolling-summary.js +227 -0
  108. package/dist/core/rolling-summary.js.map +1 -0
  109. package/dist/core/session-manager.d.ts +11 -3
  110. package/dist/core/session-manager.d.ts.map +1 -1
  111. package/dist/core/session-manager.js +56 -7
  112. package/dist/core/session-manager.js.map +1 -1
  113. package/dist/core/session-record.d.ts +165 -0
  114. package/dist/core/session-record.d.ts.map +1 -0
  115. package/dist/core/session-record.js +470 -0
  116. package/dist/core/session-record.js.map +1 -0
  117. package/dist/core/spawn-target.d.ts +12 -0
  118. package/dist/core/spawn-target.d.ts.map +1 -0
  119. package/dist/core/spawn-target.js +187 -0
  120. package/dist/core/spawn-target.js.map +1 -0
  121. package/dist/core/task-manager.d.ts.map +1 -1
  122. package/dist/core/task-manager.js +9 -1
  123. package/dist/core/task-manager.js.map +1 -1
  124. package/dist/core/template-catalog.d.ts +48 -0
  125. package/dist/core/template-catalog.d.ts.map +1 -0
  126. package/dist/core/template-catalog.js +338 -0
  127. package/dist/core/template-catalog.js.map +1 -0
  128. package/dist/core/workflow-registry.d.ts.map +1 -1
  129. package/dist/core/workflow-registry.js +2 -2
  130. package/dist/core/workflow-registry.js.map +1 -1
  131. package/dist/core/workspace-watcher.d.ts.map +1 -1
  132. package/dist/core/workspace-watcher.js +4 -3
  133. package/dist/core/workspace-watcher.js.map +1 -1
  134. package/dist/index.d.ts +12 -0
  135. package/dist/index.d.ts.map +1 -1
  136. package/dist/index.js +21 -0
  137. package/dist/index.js.map +1 -1
  138. package/dist/profiles/default.d.ts.map +1 -1
  139. package/dist/profiles/default.js +9 -14
  140. package/dist/profiles/default.js.map +1 -1
  141. package/dist/server/canvas.d.ts.map +1 -1
  142. package/dist/server/canvas.js +7 -7
  143. package/dist/server/canvas.js.map +1 -1
  144. package/dist/server/fs.d.ts.map +1 -1
  145. package/dist/server/fs.js +17 -1
  146. package/dist/server/fs.js.map +1 -1
  147. package/dist/server/index.d.ts +12 -3
  148. package/dist/server/index.d.ts.map +1 -1
  149. package/dist/server/index.js +321 -50
  150. package/dist/server/index.js.map +1 -1
  151. package/dist/server/ingest.d.ts +11 -0
  152. package/dist/server/ingest.d.ts.map +1 -1
  153. package/dist/server/ingest.js +1 -0
  154. package/dist/server/ingest.js.map +1 -1
  155. package/dist/server/macros.d.ts +4 -6
  156. package/dist/server/macros.d.ts.map +1 -1
  157. package/dist/server/macros.js.map +1 -1
  158. package/dist/server/rest.d.ts +18 -6
  159. package/dist/server/rest.d.ts.map +1 -1
  160. package/dist/server/rest.js +185 -48
  161. package/dist/server/rest.js.map +1 -1
  162. package/dist/server/templates.d.ts +24 -0
  163. package/dist/server/templates.d.ts.map +1 -0
  164. package/dist/server/templates.js +54 -0
  165. package/dist/server/templates.js.map +1 -0
  166. package/dist/shared/types.d.ts +477 -29
  167. package/dist/shared/types.d.ts.map +1 -1
  168. package/dist/shared/types.js +19 -11
  169. package/dist/shared/types.js.map +1 -1
  170. package/dist/web/assets/index-DC65cskq.js +446 -0
  171. package/dist/web/assets/index-xtD-3FFa.css +32 -0
  172. package/dist/web/index.html +2 -2
  173. package/package.json +5 -4
  174. package/dist/core/canvas-enrich.d.ts +0 -115
  175. package/dist/core/canvas-enrich.d.ts.map +0 -1
  176. package/dist/core/canvas-enrich.js +0 -186
  177. package/dist/core/canvas-enrich.js.map +0 -1
  178. package/dist/profiles/canvas-guidelines.d.ts +0 -20
  179. package/dist/profiles/canvas-guidelines.d.ts.map +0 -1
  180. package/dist/profiles/canvas-guidelines.js +0 -48
  181. package/dist/profiles/canvas-guidelines.js.map +0 -1
  182. package/dist/web/assets/index-DCtyI4VW.css +0 -32
  183. package/dist/web/assets/index-WSw5RvYR.js +0 -445
  184. package/dist/web/welcome-hero-dark.png +0 -0
  185. 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
- * One session's watcher. Watches the whole project root (not the canvas dir
32
- * directly) recursively and filters to CANVAS_DIR-prefixed changes — so
33
- * there's no separate "wait for the dir to appear" phase, and it naturally
34
- * survives the canvas dir itself being deleted/recreated. Falls back to
35
- * polling a directory-tree fingerprint when recursive `fs.watch` isn't
36
- * available (notably Linux) or the watcher errors out at runtime.
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, onChange) {
89
+ constructor(cwd, harnessSessionId, callbacks) {
40
90
  this.cwd = cwd;
41
91
  this.harnessSessionId = harnessSessionId;
42
- this.onChange = onChange;
92
+ this.callbacks = callbacks;
43
93
  this.watcher = null;
44
94
  this.pollTimer = null;
45
- this.debounceTimer = null;
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
- scheduleChange() {
104
+ scheduleCanvasChange() {
53
105
  if (this.closed)
54
106
  return;
55
- if (this.debounceTimer)
56
- clearTimeout(this.debounceTimer);
57
- this.debounceTimer = setTimeout(() => this.onChange(this.harnessSessionId), DEBOUNCE_MS);
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
- if (!this.isCanvasPath(filename))
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.scheduleChange();
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.debounceTimer)
112
- clearTimeout(this.debounceTimer);
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, (id) => this.deps.onChange(id)));
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":"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"}
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+CD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,gBAAgB,GACxB,cAAc,GAAG,IAAI,CAmBvB"}
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;;;;;;;;;;;GAWG;AAKH,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAG3E,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,MAAM,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C;;;;;;;OAOG;IACH,YAAY,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACnD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,MAA6B,GAAG,UAAU,CAqCpF"}
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"}