@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.
Files changed (185) hide show
  1. package/CHANGELOG.md +105 -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-SYpugKQ1.css +32 -0
  171. package/dist/web/assets/index-vYYd44hZ.js +446 -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
@@ -1 +1 @@
1
- {"version":3,"file":"macros.d.ts","sourceRoot":"","sources":["../../src/core/macros.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,eAAO,MAAM,cAAc,EAAE,QAAQ,EA4DpC,CAAC"}
1
+ {"version":3,"file":"macros.d.ts","sourceRoot":"","sources":["../../src/core/macros.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,eAAO,MAAM,cAAc,EAAE,QAAQ,EA2DpC,CAAC"}
@@ -46,12 +46,11 @@ export const DEFAULT_MACROS = [
46
46
  },
47
47
  },
48
48
  {
49
- // One-click force refresh of the bound workflow's canvas: re-runs the
50
- // deterministic, zero-LLM structure render (core/canvas-render.ts
51
- // instant, cache-invalidated) AND re-spawns the bounded AI enrichment
52
- // task (core/canvas-enrich.ts, a headless background run that returns
53
- // validated JSON annotations, never HTML) — all server-side, without
54
- // touching the session's pty. A cheap no-op when the session is unbound.
49
+ // One-click refresh of the bound workflow's canvas: drops the extraction
50
+ // cache and re-runs the fully deterministic render (core/canvas-render.ts
51
+ // — structure + derived annotations, no LLM, no user token), all
52
+ // server-side without touching the session's pty. A cheap no-op when the
53
+ // session is unbound.
55
54
  id: "visualize",
56
55
  label: "Visualize",
57
56
  icon: "Sparkles",
@@ -1 +1 @@
1
- {"version":3,"file":"macros.js","sourceRoot":"","sources":["../../src/core/macros.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,MAAM;QACZ,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,IAAI;YACZ,+EAA+E;YAC/E,yEAAyE;YACzE,qDAAqD;YACrD,IAAI,EAAE,0DAA0D;SACjE;KACF;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,OAAO;QACb,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,8CAA8C;SACrD;KACF;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,UAAU;QACjB,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,yDAAyD;SAChE;KACF;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,cAAc;QACpB,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE;YACN,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,2DAA2D;SACjE;KACF;IACD;QACE,sEAAsE;QACtE,oEAAoE;QACpE,sEAAsE;QACtE,sEAAsE;QACtE,qEAAqE;QACrE,yEAAyE;QACzE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,UAAU;QAChB,gBAAgB,EAAE,KAAK;QACvB,MAAM,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;KAClC;CACF,CAAC"}
1
+ {"version":3,"file":"macros.js","sourceRoot":"","sources":["../../src/core/macros.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,cAAc,GAAe;IACxC;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,MAAM;QACZ,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,IAAI;YACZ,+EAA+E;YAC/E,yEAAyE;YACzE,qDAAqD;YACrD,IAAI,EAAE,0DAA0D;SACjE;KACF;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,OAAO;QACb,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,8CAA8C;SACrD;KACF;IACD;QACE,EAAE,EAAE,UAAU;QACd,KAAK,EAAE,UAAU;QACjB,IAAI,EAAE,KAAK;QACX,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,yDAAyD;SAChE;KACF;IACD;QACE,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,cAAc;QACpB,gBAAgB,EAAE,IAAI;QACtB,MAAM,EAAE;YACN,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,2DAA2D;SACjE;KACF;IACD;QACE,yEAAyE;QACzE,0EAA0E;QAC1E,iEAAiE;QACjE,yEAAyE;QACzE,sBAAsB;QACtB,EAAE,EAAE,WAAW;QACf,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,UAAU;QAChB,gBAAgB,EAAE,KAAK;QACvB,MAAM,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;KAClC;CACF,CAAC"}
@@ -15,6 +15,7 @@ export interface HarnessStatePaths {
15
15
  events: string;
16
16
  settings: string;
17
17
  generated: string;
18
+ records: string;
18
19
  sampleProject: string;
19
20
  }
20
21
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;oDACoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AAUD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAYvE"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;oDACoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAUD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAavE"}
@@ -37,6 +37,7 @@ export function resolveStatePaths(stateRoot) {
37
37
  events: join(root, relativeToHome(HARNESS_PATHS.events)),
38
38
  settings: join(root, relativeToHome(HARNESS_PATHS.settings)),
39
39
  generated: join(root, relativeToHome(HARNESS_PATHS.generated)),
40
+ records: join(root, relativeToHome(HARNESS_PATHS.records)),
40
41
  sampleProject: join(root, relativeToHome(HARNESS_PATHS.sampleProject)),
41
42
  };
42
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEjE,iFAAiF;AACjF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,OAAO,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC;AAeD;;;2CAG2C;AAC3C,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAkB;IAClD,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,IAAI,YAAY,CAAC,CAAC;IACnD,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9D,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC5D,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9D,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACxD,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC5D,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9D,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;KACvE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEjE,iFAAiF;AACjF,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,OAAO,EAAE,CAAC;IACnC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC;AAgBD;;;2CAG2C;AAC3C,SAAS,cAAc,CAAC,KAAa;IACnC,OAAO,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAkB;IAClD,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,IAAI,YAAY,CAAC,CAAC;IACnD,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9D,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC5D,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9D,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACxD,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC5D,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAC9D,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC1D,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;KACvE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Durable session records — what makes session history outlive the raw event
3
+ * log it was rebuilt from.
4
+ *
5
+ * THE PROBLEM. `events.ndjson` is an analytics sink with an analytics sink's
6
+ * retention: 50 MB / 30 days, truncated oldest-first (core/collector/
7
+ * store-retention.ts). Once session history is *built on* that file
8
+ * (core/session-record.ts), the sweep silently deletes history — a session a
9
+ * user can read today is gone next month, with no way to tell "never existed"
10
+ * from "swept". A record the user can open is a product surface; a byte cap on
11
+ * an append-only debug log is not the right lifetime for it.
12
+ *
13
+ * THE FIX. At session end we fold the record once and write a compacted copy to
14
+ * `~/.sapiom/harness/records/<harnessSessionId>.json`. It is bounded (see the
15
+ * caps below), it is one file per conversation, and it survives every sweep of
16
+ * the ndjson because it isn't in it. The ndjson goes back to being what it is:
17
+ * the raw analytics sink.
18
+ *
19
+ * WHY NOT UNDER `<generated>/<sessionId>/`, which the ticket suggested and
20
+ * which already has a retention sweep: that directory is deleted the moment a
21
+ * session's pty exits (server/index.ts's "exited" handler calls
22
+ * removeGeneratedSessionDir — every file in it is regenerated on the next
23
+ * launch), and whatever survives that is swept 7 days after it goes stale.
24
+ * Both lifetimes are *shorter* than the 30 days of events the archive exists to
25
+ * outlive, so a record written there would die sooner than the log it was meant
26
+ * to survive. Records get their own root and their own policy instead.
27
+ *
28
+ * COMPACTION is lossy, on purpose, and says so. Tool inputs and tool results
29
+ * are the bulk of the bytes (`tool.call` was ~80% of observed event volume) and
30
+ * the least useful part of a record read weeks later, so they are clipped hard;
31
+ * prompts and assistant text — the conversation — are clipped only at the
32
+ * collector's own field cap, so in practice they are kept whole. Every loss
33
+ * lands in `SessionRecord.limitations` (`compacted-archive`,
34
+ * `dropped-early-turns`) and the UI renders it as prose, per this epic's rule
35
+ * that a reconstruction never gets to imply it is complete.
36
+ *
37
+ * SIZE CEILING, stated exactly: a record is compacted to at most
38
+ * {@link RECORD_MAX_BYTES} by clipping fields and then dropping whole turns
39
+ * oldest-first — but never below one turn. A single turn with hundreds of tool
40
+ * calls can therefore exceed the per-record cap; the store's total-bytes cap
41
+ * ({@link RECORDS_MAX_TOTAL_BYTES}, enforced against real file sizes) is the
42
+ * hard bound, and one outsized record just crowds out older ones sooner.
43
+ */
44
+ import type { SessionRecord } from "../shared/types.js";
45
+ /** Tool input, clipped hard: a 40 KB Edit payload is not what makes a
46
+ * months-old record worth keeping, and it is most of its bytes. */
47
+ export declare const RECORDS_MAX_TOOL_INPUT_CHARS = 512;
48
+ /** Tool result, same reasoning. The collector already caps these at 16 KB. */
49
+ export declare const RECORDS_MAX_TOOL_RESPONSE_CHARS = 512;
50
+ /** Prompts and assistant text — the conversation itself. Set at the
51
+ * collector's own field cap (normalizer.ts's MAX_FIELD_LENGTH), so this
52
+ * clips nothing the log didn't already clip. Kept as our own constant
53
+ * because the archive's contract is "the conversation survives whole". */
54
+ export declare const RECORDS_MAX_TEXT_CHARS = 4000;
55
+ /** Per-record byte ceiling — see the module header for the one case that
56
+ * legitimately exceeds it. ~64 KB holds a long session comfortably once tool
57
+ * payloads are clipped. */
58
+ export declare const RECORD_MAX_BYTES: number;
59
+ /** Whole-store byte ceiling. A third of the raw sink's 50 MB, for two orders
60
+ * of magnitude more sessions: at 64 KB worst-case per record it guarantees
61
+ * 256 archived conversations, and at realistic sizes holds thousands. */
62
+ export declare const RECORDS_MAX_TOTAL_BYTES: number;
63
+ /** Age ceiling. Deliberately far longer than the events' 30 days — the whole
64
+ * point of the archive is to outlive them — while still bounded, so an
65
+ * install that runs for years doesn't accumulate forever. */
66
+ export declare const RECORDS_MAX_AGE_MS: number;
67
+ /**
68
+ * A record that has been through the archive: identical to a {@link
69
+ * SessionRecord} except that `archivedAt` is known to be set. The distinction
70
+ * is load-bearing for the reader, which compares that stamp against the event
71
+ * log to decide which of the two sources still holds the whole conversation.
72
+ */
73
+ export type ArchivedSessionRecord = SessionRecord & {
74
+ archivedAt: string;
75
+ };
76
+ /** What the archive knows about one stored record without reading it again. */
77
+ export interface ArchivedRecordSummary {
78
+ /** Primary id the record is filed under (the conversation's first session). */
79
+ harnessSessionId: string;
80
+ /** Every id this record answers to: primary, merged sessions, agent session. */
81
+ keys: string[];
82
+ /** Human turns in the CONVERSATION (not necessarily in the stored turns —
83
+ * see `SessionRecord.turnCount`). */
84
+ turnCount: number;
85
+ /** ISO-8601 of when the record was archived. */
86
+ archivedAt: string;
87
+ /** Size of the file on disk. */
88
+ bytes: number;
89
+ /** Absolute path of the record file. */
90
+ file: string;
91
+ }
92
+ export interface RecordArchiveOptions {
93
+ /** Root the record files live in. Required — the caller resolves it from the
94
+ * server's state root so an isolated boot never writes to the real home. */
95
+ root: string;
96
+ maxRecordBytes?: number;
97
+ maxTotalBytes?: number;
98
+ maxAgeMs?: number;
99
+ /** Injectable clock (epoch ms) for tests. */
100
+ now?: () => number;
101
+ /** Diagnostics sink. Defaults to console.error. */
102
+ onError?: (err: unknown) => void;
103
+ }
104
+ export interface RecordArchive {
105
+ /**
106
+ * Compact `record` and write it, replacing any earlier archive of the same
107
+ * conversation. Returns what was written, or null when there was nothing
108
+ * worth archiving (a record with no turns) or the write failed — never
109
+ * throws: failing to archive must not take a session's exit down with it.
110
+ */
111
+ write(record: SessionRecord): Promise<ArchivedSessionRecord | null>;
112
+ /**
113
+ * The archived record for `id` — a harnessSessionId (primary or merged) or
114
+ * the agent's own session id — or null when there is none. Never throws; a
115
+ * corrupt file reads as absent.
116
+ */
117
+ read(id: string): Promise<ArchivedSessionRecord | null>;
118
+ /** True when {@link read} would find a record, without reading the file. */
119
+ has(id: string): Promise<boolean>;
120
+ /** Every stored record's summary, newest first. */
121
+ list(): Promise<ArchivedRecordSummary[]>;
122
+ /**
123
+ * Enforce the age and total-size caps, oldest-first. Returns the primary ids
124
+ * removed. Best-effort per file: one undeletable record doesn't abort the
125
+ * rest.
126
+ */
127
+ sweep(): Promise<string[]>;
128
+ }
129
+ export interface CompactionOptions {
130
+ maxBytes?: number;
131
+ maxToolInputChars?: number;
132
+ maxToolResponseChars?: number;
133
+ maxTextChars?: number;
134
+ /** ISO-8601 stamp to record as `archivedAt`. Defaults to now. */
135
+ archivedAt?: string;
136
+ }
137
+ /**
138
+ * The bounded, archivable form of a record: fields clipped, oldest turns
139
+ * dropped if it still doesn't fit, and every loss declared in `limitations`.
140
+ *
141
+ * Pure and idempotent — compacting an already-compacted record clips nothing
142
+ * further and drops nothing further, which matters because a re-archive
143
+ * (a session that ends twice, a backfill) must not shrink a record a little
144
+ * more each time.
145
+ *
146
+ * `turnCount` and `eventCount` deliberately keep their pre-compaction values:
147
+ * they describe the conversation that happened, not the excerpt that survived.
148
+ * A history row's turn count therefore doesn't change when its record is
149
+ * archived, and `dropped-early-turns` is what tells the reader that `turns`
150
+ * holds fewer than `turnCount` of them.
151
+ */
152
+ export declare function compactSessionRecord(record: SessionRecord, options?: CompactionOptions): ArchivedSessionRecord;
153
+ export declare function createRecordArchive(options: RecordArchiveOptions): RecordArchive;
154
+ export interface BackfillOptions {
155
+ /** Conversations present in the event log, newest activity first. */
156
+ conversationIds: () => Promise<string[]>;
157
+ /** Fold a conversation from the events alone (never from the archive). */
158
+ readFromEvents: (harnessSessionId: string) => Promise<SessionRecord | null>;
159
+ archive: Pick<RecordArchive, "has" | "write">;
160
+ /** A live session is still writing events; archiving it now would store a
161
+ * half-finished record and pre-empt the archive its exit will write. */
162
+ isLiveSession?: (harnessSessionId: string) => boolean;
163
+ /** Ceiling on how many conversations one pass archives. */
164
+ maxRecords?: number;
165
+ /** Called with the number of eligible conversations left unarchived when the
166
+ * cap cut the pass short — a bounded pass must say what it didn't do. */
167
+ onCapped?: (remaining: number) => void;
168
+ }
169
+ /** Default ceiling for one backfill pass. High enough to cover a typical
170
+ * install's whole history on the first boot after this shipped, low enough
171
+ * that a pathological log doesn't turn boot into a write storm. Whatever is
172
+ * left is archived by the next boot's pass. */
173
+ export declare const RECORDS_BACKFILL_MAX = 200;
174
+ /**
175
+ * Archive conversations the event log still holds but the archive doesn't.
176
+ *
177
+ * Two things need this, and neither is covered by archiving at session end:
178
+ * sessions that ended without one (the harness force-killed, the machine
179
+ * rebooted), and every session that ended *before* this feature existed — whose
180
+ * history would otherwise disappear at its 30-day mark with the archive looking
181
+ * on. Idempotent: a conversation already archived is skipped, so the steady
182
+ * state after the first pass is "nothing to do".
183
+ *
184
+ * Never throws. Returns the ids it archived.
185
+ */
186
+ export declare function backfillSessionRecords(options: BackfillOptions): Promise<string[]>;
187
+ //# sourceMappingURL=record-archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-archive.d.ts","sourceRoot":"","sources":["../../src/core/record-archive.ts"],"names":[],"mappings":"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"}