@claudexor/orchestrator 2.1.3 → 3.0.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 (67) hide show
  1. package/dist/candidateEvidence.d.ts.map +1 -1
  2. package/dist/candidateEvidence.js +4 -6
  3. package/dist/candidateEvidence.js.map +1 -1
  4. package/dist/candidateOutputs.d.ts +13 -0
  5. package/dist/candidateOutputs.d.ts.map +1 -1
  6. package/dist/candidateOutputs.js +71 -8
  7. package/dist/candidateOutputs.js.map +1 -1
  8. package/dist/continuity-facts.d.ts +37 -0
  9. package/dist/continuity-facts.d.ts.map +1 -0
  10. package/dist/continuity-facts.js +100 -0
  11. package/dist/continuity-facts.js.map +1 -0
  12. package/dist/continuity-summary.d.ts +45 -0
  13. package/dist/continuity-summary.d.ts.map +1 -0
  14. package/dist/continuity-summary.js +113 -0
  15. package/dist/continuity-summary.js.map +1 -0
  16. package/dist/continuity.d.ts +119 -0
  17. package/dist/continuity.d.ts.map +1 -0
  18. package/dist/continuity.js +220 -0
  19. package/dist/continuity.js.map +1 -0
  20. package/dist/contract-gates.d.ts +2 -3
  21. package/dist/contract-gates.d.ts.map +1 -1
  22. package/dist/contract-gates.js +2 -3
  23. package/dist/contract-gates.js.map +1 -1
  24. package/dist/council.d.ts +57 -0
  25. package/dist/council.d.ts.map +1 -0
  26. package/dist/council.js +98 -0
  27. package/dist/council.js.map +1 -0
  28. package/dist/credential-profiles.d.ts +26 -0
  29. package/dist/credential-profiles.d.ts.map +1 -1
  30. package/dist/credential-profiles.js +21 -0
  31. package/dist/credential-profiles.js.map +1 -1
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +1 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/orchestrator.d.ts +218 -57
  37. package/dist/orchestrator.d.ts.map +1 -1
  38. package/dist/orchestrator.js +968 -1077
  39. package/dist/orchestrator.js.map +1 -1
  40. package/dist/planQuestions.d.ts +11 -0
  41. package/dist/planQuestions.d.ts.map +1 -0
  42. package/dist/planQuestions.js +119 -0
  43. package/dist/planQuestions.js.map +1 -0
  44. package/dist/planRun.d.ts +114 -0
  45. package/dist/planRun.d.ts.map +1 -0
  46. package/dist/planRun.js +346 -0
  47. package/dist/planRun.js.map +1 -0
  48. package/dist/runSupport.d.ts +31 -80
  49. package/dist/runSupport.d.ts.map +1 -1
  50. package/dist/runSupport.js +33 -106
  51. package/dist/runSupport.js.map +1 -1
  52. package/dist/runTerminals.d.ts.map +1 -1
  53. package/dist/runTerminals.js +18 -7
  54. package/dist/runTerminals.js.map +1 -1
  55. package/package.json +18 -19
  56. package/dist/orchestrateExecutor.d.ts +0 -43
  57. package/dist/orchestrateExecutor.d.ts.map +0 -1
  58. package/dist/orchestrateExecutor.js +0 -207
  59. package/dist/orchestrateExecutor.js.map +0 -1
  60. package/dist/orchestratePlanner.d.ts +0 -12
  61. package/dist/orchestratePlanner.d.ts.map +0 -1
  62. package/dist/orchestratePlanner.js +0 -91
  63. package/dist/orchestratePlanner.js.map +0 -1
  64. package/dist/outcomeReducer.d.ts +0 -25
  65. package/dist/outcomeReducer.d.ts.map +0 -1
  66. package/dist/outcomeReducer.js +0 -121
  67. package/dist/outcomeReducer.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"candidateEvidence.d.ts","sourceRoot":"","sources":["../src/candidateEvidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,UAAU,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACtC;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,aAAa,EAAE,EACzB,gBAAgB,EAAE,OAAO,EACzB,cAAc,UAAQ,GACrB,iBAAiB,CAwCnB"}
1
+ {"version":3,"file":"candidateEvidence.d.ts","sourceRoot":"","sources":["../src/candidateEvidence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG9D,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,UAAU,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACtC;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,YAAY,EACjB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,aAAa,EAAE,EACzB,gBAAgB,EAAE,OAAO,EACzB,cAAc,UAAQ,GACrB,iBAAiB,CAsCnB"}
@@ -1,10 +1,8 @@
1
- import { gatesPassed } from "@claudexor/review";
2
1
  import { toolWarnings } from "./attemptTelemetry.js";
3
2
  export function toCandidateEvidence(run, contract, findings, finalReviewClean, reviewVerified = false) {
4
- const passed = gatesPassed(run.gates) && !run.errored;
5
- const acceptanceCovered = passed && contract.success_criteria.length > 0
6
- ? contract.success_criteria.map((criterion) => criterion.id)
7
- : [];
3
+ // Success criteria were a spec-only producer (retired with the spec
4
+ // machinery); the acceptance axis is now always empty.
5
+ const acceptanceCovered = [];
8
6
  // A harness error is an explicit failed required gate — never vacuous 0/0.
9
7
  const gates = run.errored
10
8
  ? [
@@ -27,7 +25,7 @@ export function toCandidateEvidence(run, contract, findings, finalReviewClean, r
27
25
  label: run.label,
28
26
  gates,
29
27
  acceptanceCovered,
30
- acceptanceTotal: contract.success_criteria.length,
28
+ acceptanceTotal: 0,
31
29
  findings,
32
30
  testsPassed: gates.filter((gate) => gate.status === "passed").length,
33
31
  testsTotal: gates.length,
@@ -1 +1 @@
1
- {"version":3,"file":"candidateEvidence.js","sourceRoot":"","sources":["../src/candidateEvidence.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAoBrD,MAAM,UAAU,mBAAmB,CACjC,GAAiB,EACjB,QAAsB,EACtB,QAAyB,EACzB,gBAAyB,EACzB,cAAc,GAAG,KAAK;IAEtB,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;IACtD,MAAM,iBAAiB,GACrB,MAAM,IAAI,QAAQ,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAC5C,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5D,CAAC,CAAC,EAAE,CAAC;IACT,2EAA2E;IAC3E,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO;QACvB,CAAC,CAAC;YACE,GAAG,GAAG,CAAC,KAAK;YACZ;gBACE,EAAE,EAAE,SAAS;gBACb,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,CAAC;gBACZ,MAAM,EAAE,QAAiB;gBACzB,WAAW,EAAE,CAAC;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,IAAI;gBACjB,WAAW,EAAE,IAAI;gBACjB,gBAAgB,EAAE,KAAK;aACxB;SACF;QACH,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;IACd,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK;QACL,iBAAiB;QACjB,eAAe,EAAE,QAAQ,CAAC,gBAAgB,CAAC,MAAM;QACjD,QAAQ;QACR,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM;QACpE,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,gBAAgB;QAChB,cAAc;QACd,iBAAiB,EACf,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,iBAAiB,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM;QAChF,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM;QACrC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC;QAC9C,OAAO,EAAE,GAAG,CAAC,IAAI;KAClB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"candidateEvidence.js","sourceRoot":"","sources":["../src/candidateEvidence.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAoBrD,MAAM,UAAU,mBAAmB,CACjC,GAAiB,EACjB,QAAsB,EACtB,QAAyB,EACzB,gBAAyB,EACzB,cAAc,GAAG,KAAK;IAEtB,oEAAoE;IACpE,uDAAuD;IACvD,MAAM,iBAAiB,GAAa,EAAE,CAAC;IACvC,2EAA2E;IAC3E,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO;QACvB,CAAC,CAAC;YACE,GAAG,GAAG,CAAC,KAAK;YACZ;gBACE,EAAE,EAAE,SAAS;gBACb,OAAO,EAAE,SAAS;gBAClB,SAAS,EAAE,CAAC;gBACZ,MAAM,EAAE,QAAiB;gBACzB,WAAW,EAAE,CAAC;gBACd,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,IAAI;gBACjB,WAAW,EAAE,IAAI;gBACjB,gBAAgB,EAAE,KAAK;aACxB;SACF;QACH,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;IACd,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK;QACL,iBAAiB;QACjB,eAAe,EAAE,CAAC;QAClB,QAAQ;QACR,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM;QACpE,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,gBAAgB;QAChB,cAAc;QACd,iBAAiB,EACf,GAAG,CAAC,SAAS,CAAC,OAAO,EAAE,iBAAiB,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM;QAChF,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM;QACrC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC;QAC9C,OAAO,EAAE,GAAG,CAAC,IAAI;KAClB,CAAC;AACJ,CAAC"}
@@ -24,6 +24,19 @@ export declare function persistCandidateOutputs(input: {
24
24
  attemptDir: string;
25
25
  changedPaths: readonly string[];
26
26
  }): string[];
27
+ /**
28
+ * Collect media the harness saved for the USER into the claudexor-owned
29
+ * artifact dir (F4). These files are EXCLUDED from the candidate diff
30
+ * (so a screenshot-only run reads as noChanges), so they never appear in the
31
+ * diff's changed paths — this walk is how they reach the Evidence gallery.
32
+ * Returns worktree-relative paths (retaining the `.claudexor-artifacts/`
33
+ * prefix) preserved under the attempt's `produced/` plane. Symlink-safe and
34
+ * byte-bounded exactly like `persistCandidateOutputs`.
35
+ */
36
+ export declare function collectArtifactDirMedia(input: {
37
+ worktreePath: string;
38
+ attemptDir: string;
39
+ }): string[];
27
40
  export declare function rasterLinksInMarkdown(markdown: string): string[];
28
41
  export declare function writeCandidateAttemptArtifacts(input: {
29
42
  store: ArtifactStore;
@@ -1 +1 @@
1
- {"version":3,"file":"candidateOutputs.d.ts","sourceRoot":"","sources":["../src/candidateOutputs.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AA8B/D;2DAC2D;AAC3D,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAoBzF;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,UAAU,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3E,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAatC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC,GAAG,MAAM,EAAE,CAuBX;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAYhE;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE;IACpD,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,GAAG,MAAM,EAAE,CAkBX;AAED;qEACqE;AACrE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,GAAG,MAAM,EAAE,CAWX"}
1
+ {"version":3,"file":"candidateOutputs.d.ts","sourceRoot":"","sources":["../src/candidateOutputs.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AA8B/D;2DAC2D;AAC3D,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CAoBzF;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,UAAU,EAAE,SAAS;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3E,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAatC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC,GAAG,MAAM,EAAE,CAuBX;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,EAAE,CAmCX;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAYhE;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE;IACpD,KAAK,EAAE,aAAa,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,GAAG,MAAM,EAAE,CA8BX;AAED;qEACqE;AACrE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,GAAG,MAAM,EAAE,CAWX"}
@@ -1,6 +1,6 @@
1
- import { chmodSync, closeSync, constants, copyFileSync, existsSync, lstatSync, mkdirSync, openSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
2
- import { dirname, extname, join, resolve, sep } from "node:path";
3
- import { summarizeDiffPaths } from "@claudexor/core";
1
+ import { chmodSync, closeSync, constants, copyFileSync, existsSync, lstatSync, mkdirSync, openSync, readdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
2
+ import { dirname, extname, join, relative as pathRelative, resolve, sep } from "node:path";
3
+ import { CLAUDEXOR_ARTIFACT_DIR, summarizeDiffPaths } from "@claudexor/core";
4
4
  const RASTER_OUTPUT_EXTENSIONS = new Set([".png", ".jpg", ".jpeg", ".webp", ".gif"]);
5
5
  const MAX_OUTPUT_BYTES = 16 * 1024 * 1024;
6
6
  const MAX_TOTAL_BYTES = 32 * 1024 * 1024;
@@ -94,6 +94,57 @@ export function persistCandidateOutputs(input) {
94
94
  }
95
95
  return preserved;
96
96
  }
97
+ /**
98
+ * Collect media the harness saved for the USER into the claudexor-owned
99
+ * artifact dir (F4). These files are EXCLUDED from the candidate diff
100
+ * (so a screenshot-only run reads as noChanges), so they never appear in the
101
+ * diff's changed paths — this walk is how they reach the Evidence gallery.
102
+ * Returns worktree-relative paths (retaining the `.claudexor-artifacts/`
103
+ * prefix) preserved under the attempt's `produced/` plane. Symlink-safe and
104
+ * byte-bounded exactly like `persistCandidateOutputs`.
105
+ */
106
+ export function collectArtifactDirMedia(input) {
107
+ const root = resolve(input.worktreePath);
108
+ const artifactRoot = join(root, CLAUDEXOR_ARTIFACT_DIR);
109
+ if (!existsSync(artifactRoot))
110
+ return [];
111
+ let total = 0;
112
+ const preserved = [];
113
+ const walk = (dir) => {
114
+ let entries;
115
+ try {
116
+ entries = readdirSync(dir);
117
+ }
118
+ catch {
119
+ return;
120
+ }
121
+ for (const name of entries.sort()) {
122
+ const abs = join(dir, name);
123
+ const stat = lstatIfPresent(abs);
124
+ // lstat: a symlink inside the artifact dir must never copy a host file.
125
+ if (!stat || stat.isSymbolicLink())
126
+ continue;
127
+ if (stat.isDirectory()) {
128
+ walk(abs);
129
+ continue;
130
+ }
131
+ if (!stat.isFile())
132
+ continue;
133
+ if (!RASTER_OUTPUT_EXTENSIONS.has(extname(name).toLowerCase()))
134
+ continue;
135
+ if (stat.size > MAX_OUTPUT_BYTES || total + stat.size > MAX_TOTAL_BYTES)
136
+ continue;
137
+ const rel = pathRelative(root, abs).split("\\").join("/");
138
+ const target = join(input.attemptDir, "produced", rel);
139
+ mkdirSync(dirname(target), { recursive: true, mode: 0o700 });
140
+ copyFileSync(abs, target);
141
+ total += stat.size;
142
+ preserved.push(rel);
143
+ }
144
+ };
145
+ walk(artifactRoot);
146
+ return preserved;
147
+ }
97
148
  export function rasterLinksInMarkdown(markdown) {
98
149
  const paths = [];
99
150
  for (const match of markdown.matchAll(/!?\[[^\]]*\]\(\s*<?([^)\s>]+)>?(?:\s+"[^"]*")?\s*\)/g)) {
@@ -112,11 +163,23 @@ export function rasterLinksInMarkdown(markdown) {
112
163
  export function writeCandidateAttemptArtifacts(input) {
113
164
  input.store.writeText(join(input.attemptDir, "patch.diff"), input.diff);
114
165
  const stats = summarizeDiffPaths(input.diff);
115
- const produced = persistCandidateOutputs({
116
- worktreePath: input.worktreePath,
117
- attemptDir: input.attemptDir,
118
- changedPaths: [...new Set([...stats.paths, ...rasterLinksInMarkdown(input.answerText ?? "")])],
119
- });
166
+ const produced = [
167
+ ...new Set([
168
+ ...persistCandidateOutputs({
169
+ worktreePath: input.worktreePath,
170
+ attemptDir: input.attemptDir,
171
+ changedPaths: [
172
+ ...new Set([...stats.paths, ...rasterLinksInMarkdown(input.answerText ?? "")]),
173
+ ],
174
+ }),
175
+ // F4: media in the claudexor-owned artifact dir is excluded from the diff,
176
+ // so it is never in `stats.paths` — collect it into the gallery here.
177
+ ...collectArtifactDirMedia({
178
+ worktreePath: input.worktreePath,
179
+ attemptDir: input.attemptDir,
180
+ }),
181
+ ]),
182
+ ];
120
183
  input.store.writeYaml(join(input.attemptDir, "attempt.yaml"), {
121
184
  ...input.record,
122
185
  diffstat: {
@@ -1 +1 @@
1
- {"version":3,"file":"candidateOutputs.js","sourceRoot":"","sources":["../src/candidateOutputs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"candidateOutputs.js","sourceRoot":"","sources":["../src/candidateOutputs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { type CredentialProfile } from "@claudexor/schema";
2
+ import type { ArtifactStore } from "@claudexor/artifact-store";
3
+ import type { HarnessAdapter } from "@claudexor/core";
4
+ import { type ContinuityAnchor, type ContinuityPlanPointer, type ContinuityRequest, type ResolvedSummary } from "./continuity.js";
5
+ /** The thread's most recent readable plan pointer (INV-137 packet section). */
6
+ export declare function activePlanPointer(priorTurns: ReadonlyArray<{
7
+ runId: string | null;
8
+ }>, store: ArtifactStore): ContinuityPlanPointer | null;
9
+ /** HEAD sha + dirty file count for the packet's workspace anchor. Best-effort:
10
+ * a non-git or unborn tree yields a null sha / zero dirty count, never a throw. */
11
+ export declare function workspaceAnchor(repoRoot: string): Promise<ContinuityAnchor>;
12
+ export interface ContinuitySummaryInputs {
13
+ req: ContinuityRequest;
14
+ /** Present only for a thread turn; a non-thread run gets no summary. */
15
+ threadId: string | undefined;
16
+ /** Project root that keys the summary cache (matches the lane-home keying). */
17
+ projectRoot: string;
18
+ /** Read-only working directory for the bounded pass (the execution root). */
19
+ cwd: string;
20
+ /** The lane's harness adapter, or undefined when unavailable (→ fallback). */
21
+ adapter: HarnessAdapter | undefined;
22
+ credentialProfile: CredentialProfile | null;
23
+ authPreference: "subscription" | "api_key" | "auto";
24
+ /** Scoped lane-home env so the pass authenticates on the lane's own account. */
25
+ laneEnv: Record<string, string>;
26
+ envInheritance: "mirror_native" | "clean";
27
+ signal?: AbortSignal;
28
+ }
29
+ /**
30
+ * Resolve the cached-or-fresh LLM summary for a packet's collapsed prefix
31
+ * (INV-137, V9c). Returns the summary to inject, or null when the packet does
32
+ * not collapse, no adapter is available, or summarization fails/times out — in
33
+ * every null case the caller keeps the mechanical one-liner collapse. Owns its
34
+ * OWN try/catch: a summary failure must never drop the whole packet.
35
+ */
36
+ export declare function resolveContinuitySummary(inputs: ContinuitySummaryInputs): Promise<ResolvedSummary | null>;
37
+ //# sourceMappingURL=continuity-facts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"continuity-facts.d.ts","sourceRoot":"","sources":["../src/continuity-facts.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAOtD,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAGzB,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,aAAa,CAAC;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,EACnD,KAAK,EAAE,aAAa,GACnB,qBAAqB,GAAG,IAAI,CAmB9B;AAED;mFACmF;AACnF,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAcjF;AAED,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,iBAAiB,CAAC;IACvB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,GAAG,EAAE,MAAM,CAAC;IACZ,8EAA8E;IAC9E,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,cAAc,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;IACpD,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,cAAc,EAAE,eAAe,GAAG,OAAO,CAAC;IAC1C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA4BjC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Continuity FACTS (INV-137): the I/O-bearing helpers that feed the pure packet
3
+ * builder (`continuity.ts`) — the active-plan pointer, the git workspace anchor,
4
+ * and the cached-or-fresh LLM summary resolution. Split out of the orchestrator
5
+ * so the engine's chat surface stays under the readability ratchet; each is a
6
+ * free function taking explicit, already-resolved inputs (no orchestrator
7
+ * `this`), so they are directly unit-testable.
8
+ */
9
+ import { join } from "node:path";
10
+ import { PlanQuestionsArtifact, derivePlanReadiness, } from "@claudexor/schema";
11
+ import { readTextSafe } from "@claudexor/util";
12
+ import { readThreadSummary, revParse, statusPorcelain, writeThreadSummary, } from "@claudexor/workspace";
13
+ import { planContinuation, } from "./continuity.js";
14
+ import { summarizeThreadPrefix } from "./continuity-summary.js";
15
+ /** The thread's most recent readable plan pointer (INV-137 packet section). */
16
+ export function activePlanPointer(priorTurns, store) {
17
+ for (let i = priorTurns.length - 1; i >= 0; i -= 1) {
18
+ const runId = priorTurns[i].runId;
19
+ if (!runId)
20
+ continue;
21
+ const finalDir = store.runPaths(runId).finalDir;
22
+ const planText = readTextSafe(join(finalDir, "plan.md"));
23
+ if (!planText || !planText.trim())
24
+ continue;
25
+ const questions = readTextSafe(join(finalDir, "questions.json"));
26
+ let readiness = "unverified";
27
+ if (questions) {
28
+ try {
29
+ readiness = derivePlanReadiness(PlanQuestionsArtifact.parse(JSON.parse(questions))).state;
30
+ }
31
+ catch {
32
+ readiness = "unverified";
33
+ }
34
+ }
35
+ return { path: join(finalDir, "plan.md"), readiness, planRunId: runId };
36
+ }
37
+ return null;
38
+ }
39
+ /** HEAD sha + dirty file count for the packet's workspace anchor. Best-effort:
40
+ * a non-git or unborn tree yields a null sha / zero dirty count, never a throw. */
41
+ export async function workspaceAnchor(repoRoot) {
42
+ let headSha = null;
43
+ try {
44
+ headSha = await revParse(repoRoot, "HEAD");
45
+ }
46
+ catch {
47
+ headSha = null;
48
+ }
49
+ let dirtyCount = 0;
50
+ try {
51
+ dirtyCount = (await statusPorcelain(repoRoot)).split("\n").filter((l) => l.trim()).length;
52
+ }
53
+ catch {
54
+ dirtyCount = 0;
55
+ }
56
+ return { headSha, dirtyCount };
57
+ }
58
+ /**
59
+ * Resolve the cached-or-fresh LLM summary for a packet's collapsed prefix
60
+ * (INV-137, V9c). Returns the summary to inject, or null when the packet does
61
+ * not collapse, no adapter is available, or summarization fails/times out — in
62
+ * every null case the caller keeps the mechanical one-liner collapse. Owns its
63
+ * OWN try/catch: a summary failure must never drop the whole packet.
64
+ */
65
+ export async function resolveContinuitySummary(inputs) {
66
+ if (!inputs.threadId)
67
+ return null;
68
+ try {
69
+ const plan = planContinuation(inputs.req);
70
+ // Only a budget-forced collapse needs a summary; nothing to collapse → skip.
71
+ if (plan.kind !== "packet" || !plan.summaryUpToTurnId)
72
+ return null;
73
+ const { threadId, projectRoot } = inputs;
74
+ const upToTurnId = plan.summaryUpToTurnId;
75
+ // Cache hit: reuse until the collapse boundary (upToTurnId) advances.
76
+ const cached = readThreadSummary(projectRoot, threadId, upToTurnId);
77
+ if (cached)
78
+ return { upToTurnId, text: cached };
79
+ if (!inputs.adapter)
80
+ return null;
81
+ const text = await summarizeThreadPrefix({
82
+ adapter: inputs.adapter,
83
+ turns: plan.collapsedPrefix,
84
+ cwd: inputs.cwd,
85
+ env: inputs.laneEnv,
86
+ credentialProfile: inputs.credentialProfile,
87
+ authPreference: inputs.authPreference,
88
+ envInheritance: inputs.envInheritance,
89
+ signal: inputs.signal,
90
+ });
91
+ if (!text)
92
+ return null;
93
+ writeThreadSummary(projectRoot, threadId, upToTurnId, text);
94
+ return { upToTurnId, text };
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ }
100
+ //# sourceMappingURL=continuity-facts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"continuity-facts.js","sourceRoot":"","sources":["../src/continuity-facts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Bounded inline continuation summariser (INV-137, V9c).
3
+ *
4
+ * When a continuation packet must collapse an older prefix and no fresh cached
5
+ * summary covers it, the orchestrator runs ONE bounded read-only summarisation
6
+ * pass over the collapsed turns — ask-mode intent, the thread's primary harness,
7
+ * the lane's own credential route + scoped home, a hard timeout, and a single
8
+ * turn. Success replaces the mechanical one-liner collapse with real prose;
9
+ * failure/timeout/unavailable falls back to the one-liners (which always work).
10
+ *
11
+ * This is deliberately NOT a run: it opens no run dir, records no native
12
+ * session, and emits no run events — it must never masquerade as a user turn.
13
+ * It reuses the same credential-profile + scoped-home + env-inheritance route a
14
+ * real read-only thread turn uses, so it authenticates identically and consumes
15
+ * quota honestly (the disclosure's `summarized` flag already tells the user the
16
+ * prefix was condensed).
17
+ */
18
+ import { type CredentialProfile } from "@claudexor/schema";
19
+ import { type HarnessAdapter } from "@claudexor/core";
20
+ import type { ContinuityTurn } from "./continuity.js";
21
+ /** Default wall-clock ceiling for one inline summary pass. */
22
+ export declare const SUMMARY_TIMEOUT_MS = 60000;
23
+ export interface SummaryRunParams {
24
+ adapter: HarnessAdapter;
25
+ /** The collapsed older-prefix turns to summarise (oldest → newest). */
26
+ turns: ContinuityTurn[];
27
+ /** Read-only working directory (the thread's execution root). */
28
+ cwd: string;
29
+ /** Scoped lane-home env so the pass authenticates on the lane's own account. */
30
+ env: Record<string, string>;
31
+ /** Resolved credential profile for the lane (null = engine default ladder). */
32
+ credentialProfile: CredentialProfile | null;
33
+ authPreference: "subscription" | "api_key" | "auto";
34
+ envInheritance: "mirror_native" | "clean";
35
+ /** Upper bound on the pass; the caller's run signal aborts it too. */
36
+ timeoutMs?: number;
37
+ signal?: AbortSignal;
38
+ }
39
+ /**
40
+ * Run one bounded summary pass. Returns the summary text, or null on any
41
+ * failure/timeout/empty answer (the caller then keeps the mechanical collapse).
42
+ * Never throws.
43
+ */
44
+ export declare function summarizeThreadPrefix(params: SummaryRunParams): Promise<string | null>;
45
+ //# sourceMappingURL=continuity-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"continuity-summary.d.ts","sourceRoot":"","sources":["../src/continuity-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAkB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAMzC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,cAAc,CAAC;IACxB,uEAAuE;IACvE,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,+EAA+E;IAC/E,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,cAAc,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;IACpD,cAAc,EAAE,eAAe,GAAG,OAAO,CAAC;IAC1C,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA2BD;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmD5F"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Bounded inline continuation summariser (INV-137, V9c).
3
+ *
4
+ * When a continuation packet must collapse an older prefix and no fresh cached
5
+ * summary covers it, the orchestrator runs ONE bounded read-only summarisation
6
+ * pass over the collapsed turns — ask-mode intent, the thread's primary harness,
7
+ * the lane's own credential route + scoped home, a hard timeout, and a single
8
+ * turn. Success replaces the mechanical one-liner collapse with real prose;
9
+ * failure/timeout/unavailable falls back to the one-liners (which always work).
10
+ *
11
+ * This is deliberately NOT a run: it opens no run dir, records no native
12
+ * session, and emits no run events — it must never masquerade as a user turn.
13
+ * It reuses the same credential-profile + scoped-home + env-inheritance route a
14
+ * real read-only thread turn uses, so it authenticates identically and consumes
15
+ * quota honestly (the disclosure's `summarized` flag already tells the user the
16
+ * prefix was condensed).
17
+ */
18
+ import { HarnessRunSpec, } from "@claudexor/schema";
19
+ import { AnswerAssembly } from "@claudexor/core";
20
+ /** Default wall-clock ceiling for one inline summary pass. */
21
+ export const SUMMARY_TIMEOUT_MS = 60_000;
22
+ /** Bytes of each collapsed turn fed to the summariser (prompt + output halves). */
23
+ const PER_TURN_INPUT_BYTES = 4 * 1024;
24
+ /** Bytes retained from the summary answer. */
25
+ const MAX_SUMMARY_BYTES = 8 * 1024;
26
+ function boundBytes(text, maxBytes) {
27
+ const buf = Buffer.from(text, "utf8");
28
+ if (buf.length <= maxBytes)
29
+ return text;
30
+ return `${buf.subarray(0, maxBytes).toString("utf8")}…`;
31
+ }
32
+ /** Render the collapsed prefix as the summariser's input transcript. */
33
+ function transcript(turns) {
34
+ return turns
35
+ .map((t, i) => {
36
+ const prompt = boundBytes(t.prompt.trim(), PER_TURN_INPUT_BYTES / 2);
37
+ const output = t.outputText.trim()
38
+ ? boundBytes(t.outputText.trim(), PER_TURN_INPUT_BYTES / 2)
39
+ : "(no recorded answer)";
40
+ return `Turn ${i + 1}\nUser: ${prompt}\nAssistant: ${output}`;
41
+ })
42
+ .join("\n\n");
43
+ }
44
+ const SUMMARY_INSTRUCTION = "You are handing this conversation off to a successor agent that has NOT seen it. " +
45
+ "Summarize the earlier turns below for that agent: the decisions reached, the current " +
46
+ "state of the work, and the open items still to do. Be concise and factual — no preamble, " +
47
+ "no questions, no tool calls. Output only the summary.";
48
+ /**
49
+ * Run one bounded summary pass. Returns the summary text, or null on any
50
+ * failure/timeout/empty answer (the caller then keeps the mechanical collapse).
51
+ * Never throws.
52
+ */
53
+ export async function summarizeThreadPrefix(params) {
54
+ if (params.turns.length === 0)
55
+ return null;
56
+ const timeoutMs = params.timeoutMs ?? SUMMARY_TIMEOUT_MS;
57
+ const abort = new AbortController();
58
+ const onOuterAbort = () => abort.abort();
59
+ if (params.signal) {
60
+ if (params.signal.aborted)
61
+ return null;
62
+ params.signal.addEventListener("abort", onOuterAbort, { once: true });
63
+ }
64
+ const timer = setTimeout(() => abort.abort(), timeoutMs);
65
+ timer.unref?.();
66
+ const answer = new AnswerAssembly();
67
+ try {
68
+ const spec = HarnessRunSpec.parse({
69
+ session_id: `continuity-summary-${Date.now()}`,
70
+ intent: "explain",
71
+ prompt: `${SUMMARY_INSTRUCTION}\n\n---\n\n${transcript(params.turns)}`,
72
+ cwd: params.cwd,
73
+ access: "readonly",
74
+ external_context_policy: "off",
75
+ tool_permission_policy: { web: "off", allow: [], deny: [] },
76
+ model_hint: null,
77
+ effort_hint: null,
78
+ max_turns: 1,
79
+ auth_preference: params.authPreference === "auto" ? undefined : params.authPreference,
80
+ credential_profile: params.credentialProfile,
81
+ // A fresh pass: never resume — this is a side computation, not a lane turn.
82
+ resume_session_id: null,
83
+ env_inheritance: params.envInheritance,
84
+ evidence_policy: "stream_only",
85
+ env: params.env,
86
+ attachments: [],
87
+ browser: null,
88
+ stream_deltas: false,
89
+ extra: { abortSignal: abort.signal },
90
+ });
91
+ for await (const raw of params.adapter.run(spec)) {
92
+ if (abort.signal.aborted)
93
+ return null;
94
+ const event = raw;
95
+ if (event.type === "error")
96
+ return null;
97
+ if (event.type === "message")
98
+ answer.observe(event);
99
+ }
100
+ }
101
+ catch {
102
+ return null;
103
+ }
104
+ finally {
105
+ clearTimeout(timer);
106
+ params.signal?.removeEventListener("abort", onOuterAbort);
107
+ }
108
+ if (abort.signal.aborted)
109
+ return null;
110
+ const text = answer.text().trim();
111
+ return text ? boundBytes(text, MAX_SUMMARY_BYTES) : null;
112
+ }
113
+ //# sourceMappingURL=continuity-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"continuity-summary.js","sourceRoot":"","sources":["../src/continuity-summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Continuation-packet builder (INV-137, V9b) — PURE.
3
+ *
4
+ * A lane is a (thread, harness, profile) triple. When a turn runs on a lane
5
+ * whose checkpoint lags the thread head — a lane switch (A→B→A) or a gap — the
6
+ * new lane has no native memory of the missed turns, so the engine hydrates it
7
+ * with a bounded MECHANICAL continuation packet: recent delta turns verbatim,
8
+ * older ones collapsed to one-line entries when the budget is exceeded, plus
9
+ * the active plan pointer and a workspace anchor.
10
+ *
11
+ * When the budget forces a collapse, a cached LLM summary (V9c) can REPLACE the
12
+ * collapsed one-liners with real prose: the caller runs `planContinuation` to
13
+ * learn which older turns would collapse (and their boundary turn id — the
14
+ * summary cache key), resolves a summary for that prefix (cache hit or a bounded
15
+ * inline summarization pass), and passes it back as `cachedSummary`. The
16
+ * mechanical one-liner collapse is ALWAYS the fallback, so a missing/failed
17
+ * summary never loses information. Either way `summarized` stays true (the
18
+ * verbatim prefix was condensed); the packet text itself discloses which form
19
+ * was used.
20
+ *
21
+ * This module takes fully-resolved structured data (the daemon supplies thread
22
+ * facts; the orchestrator reads prior outputs + git anchor) and returns the
23
+ * disclosure + the packet body. No I/O, no clock — trivially unit-testable.
24
+ */
25
+ /** Per delta turn: verbatim budget (user prompt + primary output). */
26
+ export declare const PER_TURN_BUDGET_BYTES: number;
27
+ /** Whole-packet verbatim budget; older turns collapse past this. */
28
+ export declare const TOTAL_BUDGET_BYTES: number;
29
+ /** One-line collapsed entry keeps this many chars of each field. */
30
+ export declare const COLLAPSE_PREFIX_CHARS = 200;
31
+ export interface ContinuityTurn {
32
+ /** Turn id (checkpoint math keys off this). */
33
+ id: string;
34
+ /** The user's message for the turn (already redacted). */
35
+ prompt: string;
36
+ /** The turn's primary output text (final/answer.md), "" when none. */
37
+ outputText: string;
38
+ }
39
+ export interface ContinuityLane {
40
+ harness: string;
41
+ profileId: string | null;
42
+ }
43
+ export interface ContinuityPlanPointer {
44
+ /** Absolute path to the approved plan.md the packet points at. */
45
+ path: string;
46
+ /** derivePlanReadiness state: ready | needs_answers | unverified. */
47
+ readiness: string;
48
+ planRunId: string;
49
+ }
50
+ export interface ContinuityAnchor {
51
+ headSha: string | null;
52
+ dirtyCount: number;
53
+ }
54
+ export interface ContinuityRequest {
55
+ /** This turn's resolved lane. */
56
+ lane: ContinuityLane;
57
+ /** All prior turns of the thread, in order (EXCLUDES the current turn). */
58
+ priorTurns: ContinuityTurn[];
59
+ /** The last turn id this lane has seen, or null when the lane never ran. */
60
+ laneCheckpointTurnId: string | null;
61
+ /** True when the lane can resume its OWN native vendor session in place. */
62
+ nativeResumeAvailable: boolean;
63
+ /** The lane that produced the prior head turn, when known (for laneSwitchedFrom). */
64
+ priorHeadLane: ContinuityLane | null;
65
+ /** Active plan pointer to append, when any. */
66
+ activePlan: ContinuityPlanPointer | null;
67
+ /** Workspace anchor to append, when available. */
68
+ anchor: ContinuityAnchor | null;
69
+ /**
70
+ * A resolved LLM summary of the collapsed older prefix (V9c). Applied ONLY
71
+ * when the packet actually collapses AND `upToTurnId` equals the plan's
72
+ * `summaryUpToTurnId` (the collapse boundary) — otherwise ignored and the
73
+ * mechanical one-liner collapse renders. Absent = mechanical fallback.
74
+ */
75
+ cachedSummary?: ResolvedSummary | null;
76
+ }
77
+ /** A summary of the collapsed older prefix, keyed by its boundary turn id. */
78
+ export interface ResolvedSummary {
79
+ /** The id of the LAST turn the summary covers (the collapse boundary). */
80
+ upToTurnId: string;
81
+ /** The summary prose to render in place of the collapsed one-liners. */
82
+ text: string;
83
+ }
84
+ /**
85
+ * The mechanical collapse plan for a request — WHICH delta turns are carried and
86
+ * which would collapse under the budget — computed WITHOUT rendering so the
87
+ * caller can resolve a summary for the collapsed prefix before building the
88
+ * packet. Pure and cheap (the same math `buildContinuation` uses internally).
89
+ */
90
+ export interface ContinuityPlan {
91
+ kind: "native_resume" | "packet" | "fresh";
92
+ /** All delta turns this lane must be told about (after its checkpoint). */
93
+ delta: ContinuityTurn[];
94
+ /** The oldest delta turns that collapse under the budget (empty = none). */
95
+ collapsedPrefix: ContinuityTurn[];
96
+ /** Boundary turn id — the summary cache key; null when nothing collapses. */
97
+ summaryUpToTurnId: string | null;
98
+ }
99
+ export interface ContinuityDisclosureResult {
100
+ kind: "native_resume" | "packet" | "fresh";
101
+ packetTurns: number;
102
+ summarized: boolean;
103
+ laneSwitchedFrom: ContinuityLane | null;
104
+ }
105
+ export interface ContinuityResult {
106
+ disclosure: ContinuityDisclosureResult;
107
+ /** The THREAD.md packet body, or null when no packet is delivered. */
108
+ packetMarkdown: string | null;
109
+ }
110
+ /**
111
+ * Compute the mechanical collapse plan for a lane WITHOUT rendering: the caller
112
+ * uses `summaryUpToTurnId` to look up / generate a summary for the collapsed
113
+ * prefix, then feeds it back via `req.cachedSummary` to `buildContinuation`.
114
+ * Pure; matches `buildContinuation`'s own collapse math exactly.
115
+ */
116
+ export declare function planContinuation(req: ContinuityRequest): ContinuityPlan;
117
+ /** Compute the continuity disclosure + packet body for a resolved lane. */
118
+ export declare function buildContinuation(req: ContinuityRequest): ContinuityResult;
119
+ //# sourceMappingURL=continuity.d.ts.map