@xingular/harness 1.3.1-unstable.5 → 1.3.1-unstable.9

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 (124) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +14 -9
  3. package/dist/cli.js +2592 -1760
  4. package/dist/sdk/accounts/accounts.d.ts +26 -20
  5. package/dist/sdk/accounts/accounts.js +100 -63
  6. package/dist/sdk/accounts/choices.d.ts +18 -0
  7. package/dist/sdk/accounts/choices.js +27 -0
  8. package/dist/sdk/agents/builtin.js +2 -0
  9. package/dist/sdk/cli.js +4 -0
  10. package/dist/sdk/commands/registry.d.ts +14 -0
  11. package/dist/sdk/commands/registry.js +2 -0
  12. package/dist/sdk/core/commandBudget.js +7 -2
  13. package/dist/sdk/core/workspaceWriteOperations.d.ts +24 -0
  14. package/dist/sdk/core/workspaceWriteOperations.js +21 -0
  15. package/dist/sdk/harness.d.ts +8 -0
  16. package/dist/sdk/harness.js +7 -4
  17. package/dist/sdk/hub/hub.js +1 -1
  18. package/dist/sdk/plugins/builtin.js +0 -4
  19. package/dist/sdk/prompt/compile.d.ts +3 -1
  20. package/dist/sdk/prompt/compile.js +16 -14
  21. package/dist/sdk/prompt/standard.js +2 -2
  22. package/dist/sdk/refine/host.d.ts +9 -1
  23. package/dist/sdk/refine/host.js +29 -0
  24. package/dist/sdk/refine/prompts.d.ts +15 -0
  25. package/dist/sdk/refine/prompts.js +44 -0
  26. package/dist/sdk/refine/recursion.js +4 -4
  27. package/dist/sdk/refine/runner.d.ts +2 -0
  28. package/dist/sdk/refine/runner.js +2 -1
  29. package/dist/sdk/refine/serverMethods.js +4 -1
  30. package/dist/sdk/refine/service.d.ts +31 -0
  31. package/dist/sdk/refine/service.js +119 -4
  32. package/dist/sdk/refine/types.d.ts +16 -0
  33. package/dist/sdk/server/methods.js +29 -1
  34. package/dist/sdk/sessions/checkpoint.d.ts +7 -0
  35. package/dist/sdk/sessions/checkpoint.js +41 -0
  36. package/dist/sdk/sessions/compactionCheckpoint.d.ts +8 -1
  37. package/dist/sdk/sessions/compactionCheckpoint.js +36 -36
  38. package/dist/sdk/sessions/completionCheck.d.ts +51 -0
  39. package/dist/sdk/sessions/completionCheck.js +148 -0
  40. package/dist/sdk/sessions/continuation.js +1 -1
  41. package/dist/sdk/sessions/contracts.d.ts +24 -1
  42. package/dist/sdk/sessions/contracts.js +6 -1
  43. package/dist/sdk/sessions/planMode.d.ts +32 -1
  44. package/dist/sdk/sessions/planMode.js +55 -7
  45. package/dist/sdk/sessions/registry.d.ts +6 -1
  46. package/dist/sdk/sessions/registry.js +4 -4
  47. package/dist/sdk/sessions/runStore.js +2 -1
  48. package/dist/sdk/sessions/runner.d.ts +3 -0
  49. package/dist/sdk/sessions/runner.js +64 -13
  50. package/dist/sdk/sessions/sessions.js +51 -7
  51. package/dist/sdk/sessions/stopGate.d.ts +89 -0
  52. package/dist/sdk/sessions/stopGate.js +171 -0
  53. package/dist/sdk/sessions/subagentService.d.ts +2 -0
  54. package/dist/sdk/sessions/subagentService.js +1 -1
  55. package/dist/sdk/sessions/workSlice.d.ts +59 -12
  56. package/dist/sdk/sessions/workSlice.js +102 -33
  57. package/dist/sdk/terminal/controller.d.ts +4 -2
  58. package/dist/sdk/terminal/controller.js +15 -4
  59. package/dist/sdk/terminal/credentialStore.d.ts +4 -0
  60. package/dist/sdk/terminal/credentialStore.js +33 -0
  61. package/dist/sdk/terminal/opentui/theme.d.ts +2 -0
  62. package/dist/sdk/terminal/opentui/theme.js +4 -0
  63. package/dist/sdk/terminal/piExtension.js +104 -26
  64. package/dist/sdk/terminal/standalone.d.ts +6 -1
  65. package/dist/sdk/terminal/standalone.js +30 -3
  66. package/dist/sdk/terminal/terminals.d.ts +10 -0
  67. package/dist/sdk/terminal/terminals.js +63 -3
  68. package/dist/sdk/terminal/tui/commands.js +20 -0
  69. package/dist/sdk/terminal/tui/modeChoices.d.ts +18 -0
  70. package/dist/sdk/terminal/tui/modeChoices.js +26 -1
  71. package/dist/sdk/terminal/tui/pages/textPage.d.ts +17 -0
  72. package/dist/sdk/terminal/tui/pages/textPage.js +52 -0
  73. package/dist/sdk/terminal/tui/planMode.d.ts +1 -1
  74. package/dist/sdk/terminal/tui/planMode.js +1 -1
  75. package/dist/sdk/terminal/tui/runtime.js +59 -4
  76. package/dist/sdk/terminal/tui/variantCommands.d.ts +32 -0
  77. package/dist/sdk/terminal/tui/variantCommands.js +359 -0
  78. package/dist/sdk/terminal/variantControl.d.ts +24 -0
  79. package/dist/sdk/terminal/variantControl.js +145 -0
  80. package/dist/sdk/tools/todo.js +1 -1
  81. package/dist/sdk/variant/store.d.ts +33 -1
  82. package/dist/sdk/variant/store.js +108 -3
  83. package/dist/sdk/worktrees/git.d.ts +2 -0
  84. package/dist/sdk/worktrees/git.js +8 -0
  85. package/dist/sdk/worktrees/snapshot.d.ts +16 -0
  86. package/dist/sdk/worktrees/snapshot.js +83 -0
  87. package/dist/terminal-opentui.js +1596 -634
  88. package/dist/terminal-pi.js +695 -417
  89. package/docs/architecture/02-sessions-and-runs.md +67 -22
  90. package/docs/architecture/03-variants.md +24 -3
  91. package/docs/architecture/04-prompt.md +66 -11
  92. package/docs/architecture/05-refinement.md +32 -5
  93. package/docs/architecture/07-tools-and-gate.md +4 -2
  94. package/docs/architecture/09-accounts-and-connectors.md +22 -3
  95. package/docs/architecture/10-server-protocol.md +17 -0
  96. package/docs/architecture/11-terminal.md +44 -17
  97. package/docs/architecture/12-storage.md +12 -4
  98. package/docs/architecture/README.md +1 -0
  99. package/docs/architecture/proposals/PROP-0041-bounded-work-slices.md +2 -0
  100. package/docs/architecture/proposals/PROP-0051-unfinished-run-handoff.md +110 -0
  101. package/docs/architecture/proposals/PROP-0052-terminal-refine-and-variant-switch.md +111 -0
  102. package/docs/architecture/proposals/README.md +1 -0
  103. package/docs/decisions/ADR-0032-compaction-run-checkpoints.md +3 -1
  104. package/docs/decisions/ADR-0062-shared-account-state.md +67 -0
  105. package/docs/decisions/ADR-0063-unfinished-work-handoffs.md +34 -0
  106. package/docs/decisions/ADR-0064-account-model-fallback-on-resume.md +79 -0
  107. package/docs/decisions/ADR-0065-variant-switch-at-turn-boundaries.md +31 -0
  108. package/docs/decisions/ADR-0066-guided-refinement-from-turn-snapshots.md +37 -0
  109. package/docs/decisions/ADR-0067-cache-stable-compaction-checkpoint.md +54 -0
  110. package/docs/decisions/ADR-0068-scope-and-completion-report.md +57 -0
  111. package/docs/decisions/ADR-0069-stop-gate-and-finish.md +130 -0
  112. package/docs/decisions/ADR-0070-terminal-slice-continuation.md +46 -0
  113. package/docs/decisions/ADR-0071-completion-check.md +103 -0
  114. package/docs/parity.md +2 -2
  115. package/docs/releases/1.3.1-unstable.6.md +31 -0
  116. package/docs/releases/1.3.1-unstable.7.md +17 -0
  117. package/docs/releases/1.3.1-unstable.8.md +19 -0
  118. package/docs/releases/1.3.1-unstable.9.md +54 -0
  119. package/docs/study/00-index.md +3 -0
  120. package/docs/study/STUDY-0004-turn-end-controls.md +121 -0
  121. package/docs/terminal-tui.md +33 -7
  122. package/package.json +1 -1
  123. package/dist/sdk/tools/checkpoint.d.ts +0 -27
  124. package/dist/sdk/tools/checkpoint.js +0 -154
package/CHANGELOG.md CHANGED
@@ -2,6 +2,130 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - **A completion check replaces `finish` (ADR-0071).**
6
+ - **The check.** When a reply that did work ends with its todo list closed or absent, the run's
7
+ own model, at low effort and with a fresh context, judges the person's request against what the
8
+ reply did: `done`, `continue` (the reply is sent back with the reason and next step), or
9
+ `needs_person`. The request is the goal; there is no `/goal` command.
10
+ - **Shared cap.** It shares the stop gate's cap of three nudges per reply and its no-progress rule.
11
+ - **Usage and failure.** Its request counts in the run's usage, and any failure leaves the reply
12
+ as it was.
13
+ - **`finish` is removed.** A live GPT 6 Luna run used `needs_decision` after 23 seconds to ask
14
+ something the handoff already answered. Only the check can now decide that the person is needed.
15
+ - **Prompt.** The `role` paragraph names which decisions are the agent's own, says a document the
16
+ request points to is the request, and says a question the request or files already answer is not
17
+ a question for the person. Its budget rises from 1,500 to 2,200 characters, so it fits uncut with
18
+ the subagent paragraph.
19
+ - **Kill switches.** `XINGULAR_STOP_GATE=off` and `XINGULAR_COMPLETION_CHECK=off` at launch switch a
20
+ layer off, for experiments.
21
+ - **The model is told it has `edit` and `write`.** Pi's `createEditTool` and `createWriteTool` drop
22
+ the definition's prompt line and guidelines, and Pi lists only tools with a prompt line, so every
23
+ terminal and headless run's system prompt named only `read` and `bash`. Models edited files
24
+ through shell scripts instead: one 2-hour terminal run made 156 script edits (14 failed) and no
25
+ `edit` call. `createWorkspaceFileTools` now restores the prompt line and guidelines, as Pi's own
26
+ `createBashTool` does, for both the terminal and the runner. The stable prefix changes once.
27
+ - **A plan no longer leaks its tools into normal mode.** A terminal plan request narrows the active
28
+ tools, and Pi records the restored normal set only with the next request. A rebuild before then
29
+ (a new runtime, resume, switch, fork or tree navigation) replayed the plan set, so normal work ran
30
+ without `edit`, `write`, browser and connected-app tools. One recorded session implemented a whole
31
+ plan that way. The terminal now marks each plan request in the session and restores the normal
32
+ set after any rebuild.
33
+ - **Terminal replies continue across work slices (ADR-0070).** A terminal reply that reaches its
34
+ 320-call or 60-minute budget after doing work now continues in place as the next slice, with a
35
+ checkpoint and a notice, up to 8 slices, instead of waiting for "continue" and re-sending the
36
+ whole context uncached. Fruitless, blocked, failed, aborted and plan slices still stop.
37
+ `XINGULAR_WORK_SLICE` also accepts key=value pairs such as `maxToolCalls=15,maxSlices=3`.
38
+ - **One copy of each credential: no more `invalid_grant` from terminals.** A terminal's Pi kept the
39
+ account's tokens in `auth.json` under its own lock while the host, its subagents and usage probes
40
+ refreshed the same token in the Keychain under another, and `terminalEnd` copied the file back
41
+ over whatever the Keychain held. OpenAI rotates refresh tokens, so whichever side refreshed second
42
+ failed with `invalid_grant` and the account needed a new sign-in. A terminal now reads and refreshes
43
+ through the host store (`accounts.credentials.*`, INV-ACC-5), holding its lock for the refresh. An
44
+ `auth.json` left by an older terminal is folded in, newest token first.
45
+ - **A stalled terminal reply is recorded as `stalled`.** Pi's abort reports back through
46
+ `terminal.interrupt` like a person's Esc, which closed the run as `user_abort` before the reply
47
+ settled as `stalled`; one silent 15-minute hang was recorded as the person's abort. The interrupt
48
+ now carries the stall. An interrupt also ends a settling reply's wait for its subagents.
49
+
50
+ - **A reply can no longer quietly stop with work open (ADR-0069).**
51
+ - **Stop gate.** In attended top-level runs, terminal included, a reply that ends while its todo
52
+ list has open items is sent back to the model, naming the items, up to three times per reply,
53
+ and never after a nudge that produced no work.
54
+ - **`finish`.** Added here as the one explicit way to stop with work open; removed again by ADR-0071
55
+ above.
56
+ - **Honest stop codes.** Such a reply settles `interrupted` with the new stop codes `needs_person`
57
+ or `unfinished`, never `completed`, with a checkpoint the harness writes from the todo list,
58
+ files and checks.
59
+ - **`checkpoint_write` is removed.** A run used it as a sign-off and stopped with work open. At a
60
+ work-slice budget the harness now writes the checkpoint itself.
61
+ - **One budget per reply.** The work-slice budget now covers the whole reply: Pi's own
62
+ continuations (nudges, delivered subagent results, plan repair) no longer reset it.
63
+ - **Prompt wording.** The texts that read as permission to stop were rewritten: the todo guidance's
64
+ "final update before your final reply", and `## What would make this complete` "when the run
65
+ could be more complete".
66
+ - **Subagents.** `spawn_subagent` now returns the child's tools, and the read-only profiles say up
67
+ front when a brief needs a tool they lack.
68
+ - **Hosts.** Accept the two new stop codes and offer Continue for them.
69
+ - **Restart required.** A live terminal session keeps the code it started with, so restart it to
70
+ get the gate.
71
+ - Do the job the request implies, and report it apart from the request. A standard session's role
72
+ paragraph now sets the scope of the work — the obvious adjacent step, what the work itself exposes,
73
+ the check it needs, inside the working folder and away from what a person must decide (a deploy, a
74
+ secret, remote data, money), without asking first inside those bounds — and the reporting guidance
75
+ requires two headings when they apply: `## Beyond what you asked` and
76
+ `## What would make this complete` (ADR-0068). The reporting budget rises from 2,000 to 2,400
77
+ characters so both fit uncut. All of it is stable-prefix text, so the cached prefix changes once
78
+ per session.
79
+ - Say in the prompt when a reply may end. The standard session's role paragraph, the opening of the
80
+ reporting guidance and the todo guidance now say that an open todo item, a passing check or a
81
+ partial result is not a reason to end the turn, and name the reasons that are: the request is done,
82
+ the work-slice guard hands the reply back, a person's decision is needed, or the person interrupts.
83
+ ADR-0069 below now enforces it in the runner. A sweep of 822 runs in seven days found 207 that ended with work left
84
+ (137 within 30 tool calls, median 17, and 191 with no checkpoint), which is what the wording is
85
+ for. All three texts are in the stable prefix, so this changes the cached prefix once.
86
+ - Reword the final-reply guidance so the outcome leads and structure follows what the answer needs. The
87
+ reporting guidance is part of every request's stable prefix, so this changes the cached prefix.
88
+ - Keep the provider cache working after a compaction (ADR-0067). The compaction checkpoint now arms only
89
+ for a compaction during the running reply, is built once, and sits right after the summary instead
90
+ of being rebuilt at the end of every request. A request after a compaction is again the previous
91
+ request plus new items, so Codex WebSocket continuation and prefix caching apply. Before, every later
92
+ turn of a compacted session resent its whole context: one measured session fell from 94–99% to
93
+ 18–24% cache hits after its first compaction.
94
+ - Flag a low prompt-cache hit rate in the terminal's composer status bar. `R<percentage>%` now covers the
95
+ last 10 model responses instead of the whole session (`recentCacheUsage`, `CACHE_HIT_WINDOW`), and
96
+ gets a yellow `⚠` below 70 percent and a red one below 40 percent. Each drop to a worse level posts
97
+ one transcript notice. A window of one response, or one with no cache reads or writes, is not judged
98
+ (`cacheHitLevel`, `CACHE_HIT_WARNING_PERCENT`, `CACHE_HIT_CRITICAL_PERCENT`).
99
+
100
+ - Refine a variant from the terminal and keep checkpoints of it (PROP-0052, ADR-0065, ADR-0066).
101
+ `/refine [what to look at]` replays the latest request typed in this chat from a snapshot of the
102
+ folder as that turn found it, in throwaway shared clones, after a confirmation that shows the run
103
+ count and models; it runs in the background, and `/refine review` shows every candidate's changes
104
+ and output and adopts any of them. Guidance reaches improvers and composers only, never the blind
105
+ selector. Task runs default to this chat's model; `--model` sets the improver's, and an adopted
106
+ version records the model it was tuned on. `/variant` switches this conversation to another
107
+ version at the next turn (resuming the same conversation), restores, compares, tags, and takes
108
+ single components back from an earlier version. New methods: `refine.fromRun`,
109
+ `refine.candidateDiff`, `refine.candidateOutput`, `variants.tag|untag|tags|resolve|revert`. Run
110
+ records gain `workspaceSnapshot`, version records `tunedFor`, and scopes `tags.json`.
111
+
112
+ - Start a conversation this account cannot use on the account's newest selection. A resumed
113
+ conversation keeps its model while the account offers it and holds its provider's credentials;
114
+ otherwise the terminal starts it on the mode's choice, then normal's, then the newest selection in
115
+ any mode, with that selection's effort, writes the model change into the conversation, and says in
116
+ one notice which model it replaced. A fallback is never saved as the person's choice, and with no
117
+ usable saved model Pi's own fallback message stands (ADR-0064).
118
+
119
+ - Make unfinished-work handoffs actionable: the stable reporting guidance now names the person’s
120
+ concrete decision or the next action and its owner for each material blocker, without imposing a
121
+ fixed heading (PROP-0051, ADR-0063).
122
+
123
+ - Share the account sign-in between `npm run dev` and the installed `xagent`. A standalone launch
124
+ can now take its account identity from another state directory with `--account-state <dir>`
125
+ (`HarnessOptions.accountsDir` plus that state's `secrets.json`), and `npm run dev` passes the
126
+ installed one, so one provider sign-in serves both while development keeps its own data,
127
+ approvals and plugin trust (ADR-0062).
128
+
5
129
  - Require owner-prefixed plugin commands on terminal and structured sessions. Plugin-owned prompt
6
130
  templates join extension commands under `/<owner-prefix>:<name>`, with no bare plugin aliases.
7
131
  A package can select a root template with `harness.defaultPrompt`; owner and route collisions fail
package/README.md CHANGED
@@ -294,11 +294,13 @@ npm run dev
294
294
 
295
295
  `npm run dev` rebuilds the CLI and opens the Harness terminal in the current working directory.
296
296
  It uses separate development directories by default: `~/.xingular-harness-dev/data` and
297
- `~/.xingular-harness-dev/state`. This keeps development harness data and device settings—including
298
- accounts, Pi settings, approvals, and connections—separate from the installed command. Press
299
- `/quit`, Ctrl+C or Ctrl+D to close it. Override either directory with `--data <dir>` or
300
- `--state <dir>`; for example: `npm run dev -- --data <dir> --state <dir>`. An omitted option keeps
301
- its development specific default.
297
+ `~/.xingular-harness-dev/state`, so development harness data, approvals, plugin trust and
298
+ connections stay separate from the installed command. It signs in as the installed command's
299
+ accounts, though: one provider sign-in serves both launches. Press `/quit`, Ctrl+C or Ctrl+D to
300
+ close it. Override either directory with `--data <dir>` or `--state <dir>`; choose the accounts a
301
+ launch signs in as with `--account-state <dir>`, for example
302
+ `npm run dev -- --account-state ~/.xingular-harness-dev/state` for a fully separate identity. An
303
+ omitted option keeps its development specific default.
302
304
 
303
305
  The OpenTUI/Solid frontend is the only terminal. Install Bun 1.3.14 or newer and run
304
306
  `npm run build:tui` (or `npm run build`); without Bun the build fails rather than producing a
@@ -404,10 +406,13 @@ still be removed; that session then asks for another account the next time it st
404
406
  The installed standalone command defaults to `~/.xingular-harness/data` and
405
407
  `~/.xingular-harness/state`; `npm run dev` instead defaults to the separate
406
408
  `~/.xingular-harness-dev/data` and `~/.xingular-harness-dev/state`. Override either with
407
- `--data <dir>` and `--state <dir>`. Session history is stored per working directory and can be
408
- reopened with the terminal's `/resume` command. The explicit `terminal` command is an alias for
409
- the default launch. Use `--help` to see the commands; `serve` remains the host-facing RPC service
410
- for integrations such as Xingular Agent/App.
409
+ `--data <dir>` and `--state <dir>`. A launch signs in as the accounts kept in the state directory
410
+ it uses; `--account-state <dir>` takes them from another state directory instead (its `accounts`
411
+ folder and its `secrets.json`), which is how `npm run dev` reaches the installed command's sign-in.
412
+ Session history is stored per working directory and can be reopened with the terminal's `/resume`
413
+ command. The explicit `terminal` command is an alias for the default launch. Use `--help` to see
414
+ the commands; `serve` remains the host-facing RPC service for integrations such as Xingular
415
+ Agent/App.
411
416
 
412
417
  ## Storage
413
418