@xingular/harness 1.1.1 → 1.3.1-unstable.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 (264) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +36 -28
  3. package/dist/cli.js +10837 -6159
  4. package/dist/sdk/accounts/accounts.d.ts +27 -3
  5. package/dist/sdk/accounts/accounts.js +78 -24
  6. package/dist/sdk/accounts/secrets.d.ts +12 -0
  7. package/dist/sdk/accounts/secrets.js +114 -7
  8. package/dist/sdk/accounts/store.d.ts +26 -1
  9. package/dist/sdk/accounts/store.js +1 -1
  10. package/dist/sdk/agents/builtin.js +18 -4
  11. package/dist/sdk/agents/planResearch.d.ts +27 -0
  12. package/dist/sdk/agents/planResearch.js +82 -0
  13. package/dist/sdk/agents/profiles.d.ts +5 -1
  14. package/dist/sdk/agents/profiles.js +21 -5
  15. package/dist/sdk/annotations/pageScript.js +349 -48
  16. package/dist/sdk/annotations/part.js +34 -23
  17. package/dist/sdk/annotations/store.d.ts +7 -0
  18. package/dist/sdk/annotations/store.js +13 -5
  19. package/dist/sdk/browser/backend.d.ts +16 -0
  20. package/dist/sdk/browser/backend.js +17 -0
  21. package/dist/sdk/browser/contracts.d.ts +19 -0
  22. package/dist/sdk/browser/contracts.js +116 -0
  23. package/dist/sdk/browser/tools.d.ts +1 -4
  24. package/dist/sdk/browser/tools.js +14 -91
  25. package/dist/sdk/capabilities/runSnapshot.js +10 -4
  26. package/dist/sdk/cli.js +5 -4
  27. package/dist/sdk/commands/list.d.ts +3 -0
  28. package/dist/sdk/commands/list.js +75 -0
  29. package/dist/sdk/commands/registry.d.ts +258 -0
  30. package/dist/sdk/commands/registry.js +48 -0
  31. package/dist/sdk/commands/routes.d.ts +16 -0
  32. package/dist/sdk/commands/routes.js +33 -0
  33. package/dist/sdk/core/commandBudget.d.ts +23 -0
  34. package/dist/sdk/core/commandBudget.js +57 -0
  35. package/dist/sdk/core/index.js +17 -1
  36. package/dist/sdk/core/interactiveProfile.d.ts +46 -0
  37. package/dist/sdk/core/interactiveProfile.js +143 -0
  38. package/dist/sdk/core/shell.d.ts +20 -0
  39. package/dist/sdk/core/shell.js +73 -0
  40. package/dist/sdk/core/workspace.d.ts +13 -0
  41. package/dist/sdk/core/workspace.js +88 -0
  42. package/dist/sdk/core/workspaceBashTool.d.ts +20 -0
  43. package/dist/sdk/core/workspaceBashTool.js +50 -0
  44. package/dist/sdk/core/workspaceSandbox.d.ts +41 -0
  45. package/dist/sdk/core/workspaceSandbox.js +360 -0
  46. package/dist/sdk/core/workspaceWriteOperations.d.ts +33 -0
  47. package/dist/sdk/core/workspaceWriteOperations.js +224 -0
  48. package/dist/sdk/doctor/checks.js +71 -12
  49. package/dist/sdk/doctor/types.d.ts +2 -2
  50. package/dist/sdk/harness.d.ts +7 -0
  51. package/dist/sdk/harness.js +42 -2
  52. package/dist/sdk/hub/hub.js +5 -3
  53. package/dist/sdk/index.d.ts +8 -3
  54. package/dist/sdk/index.js +4 -1
  55. package/dist/sdk/pi/runtime.d.ts +2 -1
  56. package/dist/sdk/pi/runtime.js +2 -2
  57. package/dist/sdk/plugins/builtin.js +32 -15
  58. package/dist/sdk/plugins/builtinRegistry.d.ts +10 -3
  59. package/dist/sdk/plugins/builtinRegistry.js +30 -8
  60. package/dist/sdk/plugins/catalogue.js +2 -1
  61. package/dist/sdk/plugins/commandPrefix.d.ts +8 -0
  62. package/dist/sdk/plugins/commandPrefix.js +21 -0
  63. package/dist/sdk/plugins/firstParty.d.ts +1 -1
  64. package/dist/sdk/plugins/firstParty.js +8 -2
  65. package/dist/sdk/plugins/install.d.ts +6 -2
  66. package/dist/sdk/plugins/install.js +29 -5
  67. package/dist/sdk/plugins/inventory.js +6 -5
  68. package/dist/sdk/plugins/manifest.d.ts +2 -0
  69. package/dist/sdk/plugins/manifest.js +2 -1
  70. package/dist/sdk/plugins/surfaces.d.ts +5 -0
  71. package/dist/sdk/plugins/surfaces.js +11 -0
  72. package/dist/sdk/plugins/types.d.ts +15 -0
  73. package/dist/sdk/prompt/compile.d.ts +14 -0
  74. package/dist/sdk/prompt/compile.js +65 -31
  75. package/dist/sdk/prompt/standard.d.ts +17 -0
  76. package/dist/sdk/prompt/standard.js +21 -0
  77. package/dist/sdk/server/methods.js +22 -2
  78. package/dist/sdk/server/remote.js +36 -11
  79. package/dist/sdk/sessions/compactionCheckpoint.d.ts +11 -0
  80. package/dist/sdk/sessions/compactionCheckpoint.js +79 -0
  81. package/dist/sdk/sessions/continuation.d.ts +7 -2
  82. package/dist/sdk/sessions/continuation.js +11 -6
  83. package/dist/sdk/sessions/contracts.d.ts +190 -4
  84. package/dist/sdk/sessions/contracts.js +71 -8
  85. package/dist/sdk/sessions/control.d.ts +72 -0
  86. package/dist/sdk/sessions/control.js +158 -0
  87. package/dist/sdk/sessions/initialBash.d.ts +7 -0
  88. package/dist/sdk/sessions/initialBash.js +7 -0
  89. package/dist/sdk/sessions/planMode.d.ts +14 -3
  90. package/dist/sdk/sessions/planMode.js +74 -17
  91. package/dist/sdk/sessions/registry.d.ts +1 -1
  92. package/dist/sdk/sessions/registry.js +2 -2
  93. package/dist/sdk/sessions/runStore.d.ts +14 -0
  94. package/dist/sdk/sessions/runStore.js +38 -1
  95. package/dist/sdk/sessions/runner.d.ts +40 -2
  96. package/dist/sdk/sessions/runner.js +161 -13
  97. package/dist/sdk/sessions/sessions.d.ts +23 -3
  98. package/dist/sdk/sessions/sessions.js +225 -22
  99. package/dist/sdk/sessions/subagentService.d.ts +24 -0
  100. package/dist/sdk/sessions/subagentService.js +225 -26
  101. package/dist/sdk/sessions/subagents.d.ts +10 -1
  102. package/dist/sdk/sessions/subagents.js +4 -0
  103. package/dist/sdk/sessions/workSlice.d.ts +106 -0
  104. package/dist/sdk/sessions/workSlice.js +329 -0
  105. package/dist/sdk/sessions/workspaceBoundary.d.ts +15 -0
  106. package/dist/sdk/sessions/workspaceBoundary.js +46 -0
  107. package/dist/sdk/terminal/browserControl.js +2 -1
  108. package/dist/sdk/terminal/controller.d.ts +31 -3
  109. package/dist/sdk/terminal/controller.js +81 -29
  110. package/dist/sdk/terminal/opentui/ansi.d.ts +25 -0
  111. package/dist/sdk/terminal/opentui/ansi.js +192 -0
  112. package/dist/sdk/terminal/opentui/model.d.ts +163 -0
  113. package/dist/sdk/terminal/opentui/model.js +482 -0
  114. package/dist/sdk/terminal/opentui/subagentsWidget.d.ts +3 -3
  115. package/dist/sdk/terminal/opentui/subagentsWidget.js +7 -5
  116. package/dist/sdk/terminal/opentui/theme.d.ts +43 -0
  117. package/dist/sdk/terminal/opentui/theme.js +88 -0
  118. package/dist/sdk/terminal/piExtension.d.ts +6 -1
  119. package/dist/sdk/terminal/piExtension.js +177 -63
  120. package/dist/sdk/terminal/standalone.d.ts +7 -0
  121. package/dist/sdk/terminal/standalone.js +72 -13
  122. package/dist/sdk/terminal/subagentMonitor.d.ts +28 -6
  123. package/dist/sdk/terminal/subagentMonitor.js +61 -9
  124. package/dist/sdk/terminal/terminals.d.ts +26 -2
  125. package/dist/sdk/terminal/terminals.js +325 -43
  126. package/dist/sdk/terminal/trajectory.d.ts +6 -1
  127. package/dist/sdk/terminal/trajectory.js +8 -0
  128. package/dist/sdk/terminal/tui/annotateCommand.d.ts +1 -1
  129. package/dist/sdk/terminal/tui/annotateCommand.js +3 -3
  130. package/dist/sdk/terminal/tui/chrome.d.ts +4 -0
  131. package/dist/sdk/terminal/tui/chrome.js +13 -0
  132. package/dist/sdk/terminal/tui/commandPages.d.ts +3 -1
  133. package/dist/sdk/terminal/tui/commandPages.js +17 -4
  134. package/dist/sdk/terminal/tui/commands.d.ts +6 -0
  135. package/dist/sdk/terminal/tui/commands.js +213 -124
  136. package/dist/sdk/terminal/tui/list.d.ts +14 -1
  137. package/dist/sdk/terminal/tui/list.js +96 -14
  138. package/dist/sdk/terminal/tui/pageOverlay.js +21 -5
  139. package/dist/sdk/terminal/tui/pages/annotatePage.d.ts +1 -1
  140. package/dist/sdk/terminal/tui/pages/browserPage.js +5 -4
  141. package/dist/sdk/terminal/tui/pages/hubPage.d.ts +14 -1
  142. package/dist/sdk/terminal/tui/pages/hubPage.js +192 -28
  143. package/dist/sdk/terminal/tui/pages/notesPage.d.ts +5 -5
  144. package/dist/sdk/terminal/tui/pages/notesPage.js +18 -18
  145. package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +8 -6
  146. package/dist/sdk/terminal/tui/pages/pluginsPage.js +206 -28
  147. package/dist/sdk/terminal/tui/pages/subagentsPage.d.ts +1 -0
  148. package/dist/sdk/terminal/tui/pages/subagentsPage.js +104 -19
  149. package/dist/sdk/terminal/tui/pages/usagePage.d.ts +43 -0
  150. package/dist/sdk/terminal/tui/pages/usagePage.js +370 -0
  151. package/dist/sdk/terminal/tui/piAdapter.d.ts +1 -2
  152. package/dist/sdk/terminal/tui/piAdapter.js +3 -5
  153. package/dist/sdk/terminal/tui/pluginCommands.d.ts +2 -0
  154. package/dist/sdk/terminal/tui/pluginCommands.js +13 -9
  155. package/dist/sdk/terminal/tui/runtime.js +23 -3
  156. package/dist/sdk/terminal/tui/sessionPicker.d.ts +40 -0
  157. package/dist/sdk/terminal/tui/sessionPicker.js +141 -0
  158. package/dist/sdk/tools/checkpoint.d.ts +27 -0
  159. package/dist/sdk/tools/checkpoint.js +154 -0
  160. package/dist/sdk/tools/getCapabilities.d.ts +31 -0
  161. package/dist/sdk/tools/getCapabilities.js +34 -0
  162. package/dist/sdk/tools/sessionName.d.ts +2 -0
  163. package/dist/sdk/tools/sessionName.js +5 -3
  164. package/dist/sdk/tools/spawnSubagent.js +11 -8
  165. package/dist/sdk/tools/todo.d.ts +15 -0
  166. package/dist/sdk/tools/todo.js +64 -0
  167. package/dist/sdk/usage/analytics.d.ts +20 -0
  168. package/dist/sdk/usage/analytics.js +151 -0
  169. package/dist/sdk/usage/ledger.d.ts +38 -0
  170. package/dist/sdk/usage/ledger.js +142 -0
  171. package/dist/sdk/usage/limits/adapters.d.ts +11 -0
  172. package/dist/sdk/usage/limits/adapters.js +349 -0
  173. package/dist/sdk/usage/limits/capture.d.ts +8 -0
  174. package/dist/sdk/usage/limits/capture.js +47 -0
  175. package/dist/sdk/usage/limits/http.d.ts +12 -0
  176. package/dist/sdk/usage/limits/http.js +51 -0
  177. package/dist/sdk/usage/limits/normalize.d.ts +15 -0
  178. package/dist/sdk/usage/limits/normalize.js +211 -0
  179. package/dist/sdk/usage/limits/service.d.ts +30 -0
  180. package/dist/sdk/usage/limits/service.js +176 -0
  181. package/dist/sdk/usage/limits/types.d.ts +65 -0
  182. package/dist/sdk/usage/limits/types.js +1 -0
  183. package/dist/sdk/usage/serverMethods.d.ts +3 -0
  184. package/dist/sdk/usage/serverMethods.js +22 -0
  185. package/dist/sdk/usage/service.d.ts +32 -0
  186. package/dist/sdk/usage/service.js +66 -0
  187. package/dist/sdk/usage/settings.d.ts +7 -0
  188. package/dist/sdk/usage/settings.js +28 -0
  189. package/dist/sdk/usage/types.d.ts +60 -0
  190. package/dist/sdk/usage/types.js +4 -0
  191. package/dist/terminal-opentui.js +9204 -4812
  192. package/dist/terminal-pi.js +1848 -272
  193. package/docs/architecture/00-overview.md +1 -1
  194. package/docs/architecture/01-extension-points.md +1 -1
  195. package/docs/architecture/02-sessions-and-runs.md +169 -36
  196. package/docs/architecture/04-prompt.md +55 -15
  197. package/docs/architecture/06-plugins-and-capabilities.md +36 -15
  198. package/docs/architecture/07-tools-and-gate.md +131 -25
  199. package/docs/architecture/08-memory-and-history.md +4 -2
  200. package/docs/architecture/09-accounts-and-connectors.md +39 -3
  201. package/docs/architecture/10-server-protocol.md +71 -9
  202. package/docs/architecture/11-terminal.md +148 -60
  203. package/docs/architecture/12-storage.md +30 -2
  204. package/docs/architecture/13-world-tools.md +22 -1
  205. package/docs/architecture/14-surfaces-and-parity.md +58 -8
  206. package/docs/architecture/README.md +20 -17
  207. package/docs/architecture/proposals/PROP-0006-run-checklist.md +2 -0
  208. package/docs/architecture/proposals/PROP-0017-page-annotations.md +6 -2
  209. package/docs/architecture/proposals/PROP-0018-annotation-queue-and-app-targets.md +1 -1
  210. package/docs/architecture/proposals/PROP-0031-plugin-command-owner-namespaces.md +54 -0
  211. package/docs/architecture/proposals/PROP-0032-planning-quality.md +196 -0
  212. package/docs/architecture/proposals/PROP-0033-compaction-plan-checkpoints.md +75 -0
  213. package/docs/architecture/proposals/PROP-0034-conversation-fast-mode.md +120 -0
  214. package/docs/architecture/proposals/PROP-0035-retain-subagent-status.md +47 -0
  215. package/docs/architecture/proposals/PROP-0036-first-class-harness-commands.md +59 -0
  216. package/docs/architecture/proposals/PROP-0037-workspace-write-boundary.md +63 -0
  217. package/docs/architecture/proposals/PROP-0038-annotate-open-shadow-roots.md +73 -0
  218. package/docs/architecture/proposals/PROP-0039-workspace-boundary-hardening.md +139 -0
  219. package/docs/architecture/proposals/PROP-0040-one-launch-path.md +87 -0
  220. package/docs/architecture/proposals/PROP-0041-bounded-work-slices.md +258 -0
  221. package/docs/architecture/proposals/PROP-0042-usage-and-provider-limits.md +127 -0
  222. package/docs/architecture/proposals/PROP-0043-read-only-plan-bash.md +74 -0
  223. package/docs/architecture/proposals/PROP-0044-work-slice-defaults.md +93 -0
  224. package/docs/architecture/proposals/PROP-0045-rename-checklist-to-todo.md +132 -0
  225. package/docs/architecture/proposals/PROP-0046-progress-aware-stall-guards.md +82 -0
  226. package/docs/architecture/proposals/PROP-0047-plugins-hub-separation.md +122 -0
  227. package/docs/architecture/proposals/README.md +24 -6
  228. package/docs/decisions/ADR-0001-owned-terminal.md +1 -1
  229. package/docs/decisions/ADR-0021-required-command-namespaces.md +1 -1
  230. package/docs/decisions/ADR-0031-plugin-command-owner-namespaces.md +37 -0
  231. package/docs/decisions/ADR-0032-compaction-run-checkpoints.md +33 -0
  232. package/docs/decisions/ADR-0033-plan-mode-research-delegation.md +47 -0
  233. package/docs/decisions/ADR-0034-first-class-harness-terminal-commands.md +25 -0
  234. package/docs/decisions/ADR-0035-one-launch-path.md +40 -0
  235. package/docs/decisions/ADR-0036-workspace-write-operation-boundary.md +54 -0
  236. package/docs/decisions/ADR-0037-usage-ledger-and-provider-limits.md +44 -0
  237. package/docs/decisions/ADR-0038-plan-bash-os-read-only.md +29 -0
  238. package/docs/decisions/ADR-0039-progress-aware-stall-guards.md +39 -0
  239. package/docs/decisions/ADR-0040-architecture-change-workflow.md +31 -0
  240. package/docs/decisions/ADR-0041-plugins-hub-separation.md +41 -0
  241. package/docs/decisions/ADR-0042-windows-shell-without-sandbox.md +40 -0
  242. package/docs/decisions/ADR-0043-parents-continue-stopped-subagents.md +49 -0
  243. package/docs/doctor.md +14 -1
  244. package/docs/experiments/EXP-0003-performance-audit/data/session-runtime-replication.json +420 -0
  245. package/docs/experiments/EXP-0003-performance-audit/data/session-runtime.json +420 -0
  246. package/docs/experiments/EXP-0003-performance-audit/data/terminal-compact.json +376 -0
  247. package/docs/experiments/EXP-0003-performance-audit/data/terminal-history.json +422 -0
  248. package/docs/experiments/EXP-0003-performance-audit/data/terminal-question.json +95 -0
  249. package/docs/experiments/EXP-0003-performance-audit/data/terminal-wide.json +1036 -0
  250. package/docs/experiments/EXP-0003-performance-audit/plan.md +109 -0
  251. package/docs/experiments/EXP-0003-performance-audit/results.md +151 -0
  252. package/docs/handoff-2026-10-25-app-parity-and-solo-tabs.md +202 -0
  253. package/docs/parity.md +83 -27
  254. package/docs/releases/1.1.1.md +28 -0
  255. package/docs/releases/1.2.0.md +49 -0
  256. package/docs/releases/1.3.0.md +21 -0
  257. package/docs/releases/4.0.0.md +10 -9
  258. package/docs/releases/README.md +35 -30
  259. package/docs/study/00-index.md +3 -0
  260. package/docs/study/STUDY-0003-long-horizon-runs.md +210 -0
  261. package/docs/terminal-tui.md +162 -82
  262. package/package.json +4 -3
  263. package/dist/sdk/tools/checklist.d.ts +0 -9
  264. package/dist/sdk/tools/checklist.js +0 -54
@@ -1,6 +1,6 @@
1
1
  # Harness terminal frontend
2
2
 
3
- Status: release candidate `@xingular/harness` 4.0.0; npm publication blocked by registry authorization. Last updated: 2026-10-24.
3
+ Status: current terminal behavior, checked against `@xingular/harness` 1.3.0. Last updated: 2026-11-19.
4
4
  Decision: [ADR-0001](decisions/ADR-0001-owned-terminal.md),
5
5
  [ADR-0006](decisions/ADR-0006-opentui-only-terminal.md),
6
6
  [ADR-0009](decisions/ADR-0009-xharness-command.md),
@@ -29,12 +29,19 @@ overrides the Bun executable.
29
29
  `TerminalRuntime`, session replacement, commands, decisions, account pinning and run records. It
30
30
  projects the runtime's snapshot and transcript into an OpenCode-inspired view, with a native
31
31
  OpenTUI textarea for the prompt, `Ctrl+K` for the command palette, `Return` to send (or to queue behind a running reply),
32
- `Cmd+Return` (or `Alt+Return`) to steer a running reply, and `Shift+Return` for a newline. With an
33
- empty composer, unmodified Up recalls the latest non-empty user message from the active session.
34
- After recall, unmodified Up/Down are available for normal editor movement and do not browse history
35
- while the draft is non-empty. Ctrl+Up/Down remain explicit history shortcuts; Down past the newest
36
- entry restores a blank draft. History comes from the active Pi session's saved messages, so `/new`
37
- and `/session` (also `/resume`) switch to that session's history. Steering needs a terminal that reports Cmd with the
32
+ `Cmd+Return` (or `Alt+Return`) to steer a running reply, and `Shift+Return` for a newline. Typing `/` or `$` filters
33
+ matching commands or skills; `Tab` inserts the selected entry and leaves the cursor at the end of the inserted text.
34
+ With an empty composer, unmodified Up recalls the latest non-empty user message from the active session.
35
+ With a draft, unmodified Up browses older history and Down browses newer history when the caret is at
36
+ either absolute draft endpoint (start or end). Down past the newest entry restores the draft, cursor
37
+ and attachments that were present when history browsing began. At non-endpoint positions, Up on the
38
+ first visual line moves the cursor to the first character and Down on the last visual line moves it
39
+ to the final character; elsewhere, Up/Down move the caret normally. Ctrl+Up/Down remain explicit
40
+ history shortcuts from anywhere. History includes
41
+ user messages and Bash commands from the active Pi session; recalled Bash commands return to `!`
42
+ mode. Executed slash commands from this terminal instance are included too, across session switches.
43
+ `/new` and `/session` (also `/resume`) switch the saved-message and Bash history to that session.
44
+ Steering needs a terminal that reports Cmd with the
38
45
  kitty keyboard protocol; elsewhere `Alt+Return` steers. In the composer, `Tab` opens up to eight matching filesystem entries for the path token at the cursor, or current-folder entries when the token is empty. The list has no heading or hint row. Up/Down select; Enter or Tab inserts the selection; Escape closes the list. Directories end in `/`, and Bash mode escapes shell-special characters. Use `/effort` or Shift+Up/Down to change effort. The command palette opens above the composer under a muted (`dim`) top rule, and has no other border. Its rows align slash commands and descriptions in two columns: the command column sizes to the widest visible name, bounded to preserve description space, and both columns wrap instead of truncating. The plan-choice rule, question block's top-only divider, and `/btw` block's top rule use the same muted color as the normal composer divider. The console has no background of its own: the renderer, root surface
39
46
  and transcript are transparent, so the terminal's own background shows through, while panels,
40
47
  dialogs and the scrim stay opaque. The composer has no panel background: it is bounded by a top and
@@ -63,7 +70,9 @@ colour. A full-screen scrim dims the console behind the panel so the transcript
63
70
  visible. Centered Harness dialogs fit their rendered content, capped by the available dialog
64
71
  height, with four columns of horizontal padding and two rows of vertical padding to account for
65
72
  the terminal's taller-than-wide cells. They use a plain title with a muted `Esc` hint and
66
- omit divider rules and footer hints. Shortcut behavior remains available. Searchable lists share
73
+ omit divider rules and footer hints. Shortcut behavior remains available. Bracketed paste and the
74
+ clipboard-paste shortcut insert text into the active dialog input or search field, using that
75
+ component's input semantics; images and file attachments remain composer-only. Searchable lists share
67
76
  the same glyph, placeholder, spacing, and muted result note, with search context included on that
68
77
  row. A terminal too small for a 30-column by
69
78
  12-row dialog falls back to the full-screen page chrome. A plugin's full-screen surface stays full
@@ -84,10 +93,11 @@ The frontend is verified with a real isolated PTY and a loopback provider. Run
84
93
  `python3 scripts/verify-terminal.py --welcome-only --sizes 40x20,80x24,120x40` to check the empty
85
94
  welcome, product label, accent colors and `/help` transition. Run
86
95
  `python3 scripts/verify-terminal.py --composer-only` for recognized slash-command colors in the composer
87
- and a user bubble, unknown-command and argument colors, explicit-newline and soft-wrap checks of both
88
- prompt gutters, and normal/plan/Bash mode exclusivity. Run it with `--sizes 40x20,80x24,120x40` for
89
- compact through wide layouts. Use `--file-completion-only` for filesystem completion and insertion,
90
- `--history-only` for active-session history across `/new` and `/session`, `--help-only` for `/help` replacing the welcome screen with grouped two-column output that wraps without per-command gaps, `--questions-only` for recommended choices,
96
+ and a user bubble, enabled-skill colors in the composer, unknown-token and argument colors,
97
+ explicit-newline and soft-wrap checks of both prompt gutters, and normal/plan/Bash mode exclusivity.
98
+ Run it with `--sizes 40x20,80x24,120x40` for compact through wide layouts. Use `--dialog-paste-only` to verify bracketed paste into a centered
99
+ input dialog, `--file-completion-only` for filesystem completion and insertion,
100
+ `--history-only` for active-session history across `/new` and `/session`, `--resume-only` for the full-screen searchable, unnumbered two-line saved-session picker, `--help-only` for `/help` replacing the welcome screen with grouped two-column output that wraps without per-command gaps, `--questions-only` for multi-select marker glyphs, recommended choices,
91
101
  selected-row and Continue/Submit colors, `--jump-latest-only` for scroll-away badge visibility and click-to-latest (screen-level click assertions use optional `pyte`), and choice-backed “Something else” answers, or `--thinking-only` for `/thinking` visibility toggles. The full suite covers a complete turn, `read`, `bash` approval, `ask_user_question` approval and picker, plugin overlay/widget/status
92
102
  disposal, a completed run record with usage and decision events, `/help`, `/permissions`,
93
103
  `/settings`, `/model`, palette selection, confirm cancel, and Ctrl+D exit. `--questions-only` checks
@@ -109,16 +119,29 @@ The terminal joins outstanding children before its final reply, projects child a
109
119
  with their original run IDs, and stops descendants when interrupted or disposed. Connected apps
110
120
  need not be enabled. `TerminalPrepareInput.subagents: null` disables the capability.
111
121
 
112
- The terminal also projects the active parent's subagent descendants into live rows under the
113
- status line and a searchable `/subagents` page. The rows poll a private monitor route once per
114
- second during a turn. They sit one blank row below the status line, with no heading, and each
115
- reads: the status mark, the agent profile name in its colour (`subagent` for a copy of the
116
- parent), the title the parent gave the child (PROP-0030), and `n of m tasks` from the child's own
117
- checklist. At most three show, active first, then `+N more · /subagents`. The `/subagents` page
118
- adds status, elapsed time and the latest tool name. The projection is read-only, flat across nested
119
- descendants, and scoped to the current parent run; it keeps finished child rows until that parent
120
- settles. It never includes tool arguments (beyond the title), output or
121
- checklist item text.
122
+ The terminal also projects the latest parent's subagent descendants into rows under the status line
123
+ and a searchable `/subagents` page. The rows poll a private monitor route once per second
124
+ during a turn and make a final read at settlement. They sit one blank row below the status line, with
125
+ no heading, and each reads: the status mark, the agent profile name in its colour (`subagent` for a
126
+ copy of the parent), the title the parent gave the child (PROP-0030), and `n of m tasks` from the
127
+ child's own todo list. At most three show, active first, then `+N more · /subagents`. The
128
+ `/subagents` page uses a colored profile and normal-color title on the first line, then muted account,
129
+ effective model, effort and cumulative usage metadata on the second. One blank row separates each
130
+ two-line entry. The page also shows status, elapsed time and the latest tool name. Runtime metadata
131
+ stays in the private terminal projection.
132
+ Usage contains safe token/cache/cost/context totals, not per-request payloads or reasoning summaries.
133
+ The projection is read-only, flat across nested descendants, and scoped to the latest parent run in
134
+ this terminal session; finished rows remain visible until the next parent run starts. The page also
135
+ pins a `main` row for the parent run itself, with the same details; the rows under the status line
136
+ leave it out. Reopening a conversation (a new launch, `/resume`, or a switch) rebuilds the rows from
137
+ the branch's latest parent run and its saved child runs, with their final status, until the next run
138
+ starts. A switch to a conversation without one clears them, as does disposal. It never includes tool
139
+ arguments (beyond the title), output or todo item text.
140
+
141
+ An interrupted or failed child keeps its saved conversation. The next reply is told which children
142
+ stopped before it answers, and the parent continues one with `spawn_subagent { continue: <runId> }`,
143
+ which reopens that child's own history with its profile and tools (ADR-0043). Esc therefore does
144
+ not lose a child's progress.
122
145
 
123
146
  `/agents` opens the Agents page (PROP-0029): built-in, global, project and variant profiles with
124
147
  their tools, plugins, variant, model and instructions. Enter on a row edits a person's own profile
@@ -136,7 +159,7 @@ Harness owns its interactive terminal application in
136
159
  [`src/terminal/opentui/`](../src/terminal/opentui/). [`app.ts`](../src/terminal/opentui/app.ts)
137
160
  owns terminal lifecycle, submission, commands, decisions and run records;
138
161
  [`root.tsx`](../src/terminal/opentui/root.tsx) owns composition, the transcript, the composer,
139
- palette and dialogs. It does not construct Pi's `InteractiveMode`. Pi 1.2.0 supplies the
162
+ palette and dialogs. It does not construct Pi's `InteractiveMode`. Pi 1.4.0 supplies the
140
163
  persistent agent session, model and auth runtime, native JSONL history, tool execution and rich
141
164
  content components.
142
165
 
@@ -199,8 +222,10 @@ before the compaction (rebuilt from Pi's session history, kept messages included
199
222
  rule; then the work that followed. The summary is shown by default. Clicking either rule hides or
200
223
  shows it, and Ctrl+O shows every summary again. On a narrow screen the rule drops the click hint, then
201
224
  the token count. Earlier compactions in the same session keep their own rules and summary in place.
202
- Notices stay after the message they followed. The model still sees only the summary and the recent
203
- messages; this is presentation only.
225
+ Notices stay after the message they followed. The model sees the summary and recent messages plus a
226
+ bounded, hidden checkpoint of the active request, todo list and plan instructions when available;
227
+ the checkpoint is regenerated for each post-compaction request until the run settles. The visible
228
+ transcript remains a presentation of the full history, not the model context.
204
229
  Transcript entry ids follow positions in the displayed message list, so when a rebuilt list moves a
205
230
  different kind of entry onto an id, the renderer builds a new component for it instead of reusing the
206
231
  old layout, and each entry draws inside its own error boundary. A run therefore keeps updating live
@@ -251,13 +276,20 @@ OSC 8 support. Inline and fenced code use a subtle panel fill with syntax colors
251
276
  list markers, tables, dividers and task-list markers use the existing titanium palette. Images
252
277
  display their alt text and are not fetched or rendered as image files.
253
278
 
254
- ## Checklist block
279
+ ## Todo block
255
280
 
256
- `checklist_write` is registered in terminal sessions (PAR-001). Each call renders in the
257
- transcript as a checklist block: a status mark, `Checklist · n of m done`, then one line per item
258
- with `✓` (done, success colour), `●` (in progress, warning yellow, bold) or `○` (pending, dim). A call whose
259
- arguments are not a checklist, or that failed, stays an ordinary tool row. The prompt's Progress
260
- group asks the model to keep the list current because the user follows work from it.
281
+ `todo_write` is registered in terminal sessions (PAR-001). Each call renders in the transcript as
282
+ a todo block: a status mark, `Todo · n of m done`, then one line per item with `✓` (done, success
283
+ colour), `●` (in progress, warning yellow, bold) or `○` (pending, dim). Each row reserves a one-cell
284
+ status column and one-cell gap; item text and wrapped lines share the same starting column. A call
285
+ whose arguments are not a todo list, or that failed, stays an ordinary tool row. The prompt's
286
+ Progress group asks the model to keep the list current and write a final update before replying;
287
+ unfinished work remains unfinished rather than being marked complete.
288
+
289
+ `/todo` (alias `/checklist`) appends a snapshot of the current list: the same header and rows, with
290
+ no status mark on the header, because it is not a tool call. It reads the latest non-side-question
291
+ run of this terminal's native session and makes no model request; an empty list is a one-line
292
+ notice.
261
293
 
262
294
  ## Blocks and pages
263
295
 
@@ -282,20 +314,36 @@ frontends draw that field from the same muted-blue selection palette (`selection
282
314
  explicit high-contrast text on it instead of the accent colour, so a choice reads the same in every
283
315
  list. Rules use the theme's `warning` and `dim` colors, so a custom theme restyles them.
284
316
 
285
- The Harness resource browser (PROP-0013) unifies Overview, Foundation, Variant, Skills, Plugins,
286
- Connections, Tools and Library. `/harness` opens Overview; `/skills`, `/plugins`, `/connections`
287
- (`/mcp`) and `/tools` open sections. `/hub` selects Discover and `/components` selects Library.
288
- The existing Accounts, Permissions, Settings, Trajectory and Log pages retain their own tabs.
317
+ The broad Harness resource browser (PROP-0013) unifies Overview, Foundation, Variant, Skills,
318
+ Plugins, Connections, Tools and Library. `/harness` opens Overview; `/skills`, `/connections`
319
+ (`/mcp`), `/tools` and `/components` open sections. `/plugins` is a separate
320
+ full-screen local manager with Plugins, Trust and Packages tabs; `/hub` is a separate
321
+ full-screen Community catalog with Catalog and Installed tabs. Both keep a searchable
322
+ inventory beside selected-item details on wide terminals, stacking details below the list
323
+ on compact terminals. The existing Accounts, Permissions, Settings, Trajectory and Log
324
+ pages retain their own tabs.
289
325
 
290
326
  `/settings` includes a Browser tab with the device-local **Private address access** setting. It is
291
327
  off by default. Enabling it asks for confirmation and allows agent browsing and annotation capture
292
328
  to reach localhost and private networks.
293
329
 
294
- Resource sections share Installed/Discover and source filters. Installed includes locally present
295
- resources; current-session availability comes only from the runtime loader and active tool registry.
296
- Discover uses the existing Hub with All/Community/Official filtering and an explicit remote refresh.
297
- No matching community entries is an empty result, never replaced with built-in resources.
298
- The view preserves search across source switches and restores section selection on return.
330
+ Within the broad `/harness` browser, resource sections share Installed/Discover and source filters.
331
+ Installed includes locally present resources; current-session availability comes only from the runtime
332
+ loader and active tool registry. Discover uses the unfiltered Hub service with All/Community/Official
333
+ filters and an explicit refresh. No matching Community entries is an empty result, never replaced with
334
+ built-in resources. The view preserves search across source switches and restores section selection.
335
+
336
+ The dedicated `/hub` Catalog shows Community entries across supported types only. Its Installed tab
337
+ shows receipts from every channel with the channel labeled. On each page entry, cached/bundled entries
338
+ appear first, then the remote catalog refreshes; the status keeps the origin, last-refresh time and any
339
+ stale/error feedback visible. Manual refresh remains available. Catalog installs are pinned to the
340
+ selected version, and Hub uninstalls remove only receipt-owned resources. Registry/document entries
341
+ offer a bounded payload Preview; Pi packages have no JSON payload Preview.
342
+
343
+ The `/plugins` manager keeps local switching, code trust and settings separate from public discovery.
344
+ Its Packages tab adds local package installation, update and removal. Hub-owned packages remain pinned
345
+ to exact catalog versions; removal goes through Hub receipt cleanup, and updating requires an explicit
346
+ Hub version replacement.
299
347
 
300
348
  The browser fills the terminal (PROP-0014), with Overview, Foundation, Variant, Skills, Plugins,
301
349
  Connections, Tools and Library as persistent top tabs. The section dropdown and sidebar are removed.
@@ -310,8 +358,8 @@ Left/Right changes the focused tab or control; Enter on the tab strip returns to
310
358
  Ctrl+F focuses search. Escape returns from content to actions, returns to the list, clears search,
311
359
  then closes. Mouse clicks select tabs directly, activate resource actions and focus filters;
312
360
  wheel scrolling targets the list or inspector under the pointer. Other command pages keep their
313
- centered presentation; `/settings` and `/accounts` use full-screen page layouts. Closing the browser preserves
314
- the composer draft and attachments.
361
+ centered presentation; `/settings`, `/accounts`, `/plugins` and `/hub` use full-screen page layouts.
362
+ Closing the browser preserves the composer draft and attachments.
315
363
 
316
364
  Foundation explains fixed runtime ownership; it is read-only. Variant shows c1–c8 with the
317
365
  prepared version and current head separately. It previews pinned files from the preparation
@@ -342,7 +390,7 @@ skill import rejects symbolic links and limits bytes, files and traversal. See
342
390
 
343
391
  ## Annotate pane (PROP-0018)
344
392
 
345
- `/plugin:annotate` opens a full-screen page that works beside the window being inspected. That window is one of:
393
+ `/annotate:` opens the full-screen capture pane (equivalent to `/annotate:annotate`) beside the window being inspected. Add a page address with `/annotate:annotate [url]`. The target window is one of:
346
394
  - the visible capture browser
347
395
  - an app's own windows attached over its DevTools port (`--app`)
348
396
  - app windows that loaded the page bridge script (`--bridge`)
@@ -357,7 +405,7 @@ The header shows the target and window and whether the inspector is on. The list
357
405
  | `t` | choose a window |
358
406
  | `Enter` | the note menu |
359
407
 
360
- The page has no search row, so these letters are free for actions. `/plugin:notes` keeps the searchable list.
408
+ The page has no search row, so these letters are free for actions. `/annotate:notes` opens the searchable Web annotations list.
361
409
 
362
410
  ## Plan mode and thinking keys
363
411
 
@@ -365,11 +413,20 @@ Use `/plan <brief>` for one read-only planning request. A plan waits outside Pi'
365
413
  queue until the active response settles, then runs by itself. Later messages remain behind it, even
366
414
  when Pi's follow-up mode is `all`. During that run the session narrows to read-only inspection
367
415
  (`read`, `grep`, `find`, `ls`), web search/page reading, questions (`ask_user`, `ask_user_question`)
368
- and recall (history and Wiki reads, `memory_facts`). Normal mode omits both question tools from the
369
- active set; the plan request enables registered questions temporarily and restores the normal set
370
- when it settles, including on failure or interruption. Providers may mark individual calls as safe for
371
- research; every other call is blocked before approval. Edits, writes, shell commands, memory writes,
372
- subagents and connected-app tools remain unavailable. The plan instructions arrive as a
416
+ and recall (history and Wiki reads, `memory_facts`). The parent may also run Bash in the
417
+ OS-enforced read-only sandbox: no network and no writes except a discarded per-command temporary
418
+ directory (PROP-0043). It may delegate bounded research to a named profile whose effective tool and
419
+ plugin allowlists qualify for research; the child inherits plan mode and receives only the
420
+ intersection of the parent's frozen capabilities, profile and plan-research set. Children cannot
421
+ write, run commands, ask the user, use connectors or spawn more children; they remain bounded by the
422
+ configured work-slice policy without gaining `checkpoint_write`, and the Harness records an
423
+ evidence-derived checkpoint if the child stops at a boundary. Normal mode omits both question tools
424
+ from the active set; the plan request enables registered questions and research delegation
425
+ temporarily and restores the normal set when it settles, including on failure or interruption.
426
+ Providers may mark individual calls as safe for research; every other call is blocked before
427
+ approval. Edits, writes, memory writes and connected-app tools remain unavailable to parent and
428
+ child; generic browser controls are also blocked. Sandboxed read-only Bash is the parent's only
429
+ plan-mode shell exception; children cannot run commands. The plan instructions arrive as a
373
430
  request-scoped prompt section, which the next ordinary request withdraws.
374
431
 
375
432
  Each mode keeps its own model and effort for the account. Every selection the person makes (the model
@@ -382,7 +439,7 @@ and the App reads and writes them through `accounts.choices` and `accounts.choos
382
439
  A bare `/plan` toggles plan mode, and Shift+Tab cycles between normal and plan mode. Normal, plan
383
440
  and Bash are mutually exclusive composer modes. While plan mode is on, each submitted message is sent
384
441
  as a plan request through that same queue, and the composer's top and bottom rules take the plan colour.
385
- Commands still run as commands. Entering Bash with a leading `!` exits plan mode; Shift+Tab from Bash
442
+ Commands still run as commands. The model may run Bash during a plan request, only in the read-only sandbox scope (PROP-0043); your own `!` commands are not part of the plan. Entering Bash with a leading `!` exits plan mode; Shift+Tab from Bash
386
443
  switches to plan mode and keeps the draft text. Turning plan mode off returns to normal mode. The old
387
444
  on/off/toggle forms are rejected; a bare `/plan` is the switch.
388
445
 
@@ -417,13 +474,17 @@ the marker and rules blue; in the normal prompt, the marker matches the divider
417
474
  an empty Bash body returns to the normal prompt. Submitting while a reply is active queues
418
475
  the command as a standalone turn; it does not steer the current model request.
419
476
 
420
- The terminal extension checks Bash policy and requests approval before using Pi's native
421
- `executeBash`. Output streams into the transcript while the command runs, so browser-login URLs are
422
- visible before the command finishes; the running item shows that Escape stops the command. The
423
- native result is recorded in run activity and session history before the model is prompted to read
424
- and explain it. This does not attach interactive stdin to the shell. SDK callers may opt into this
425
- behavior with `SessionRunInput.initialBashCommand`; it is restricted to a new interactive user turn
426
- and the session runner applies the same Bash gate.
477
+ The terminal checks Bash policy before using Pi's native `executeBash`. Ordinary `!command` runs
478
+ workspace-scoped; `!outside <command>` explicitly requests human-only approval before the command
479
+ runs once with broader filesystem access. The complete command is shown as escaped, scrollable
480
+ approval details; if the terminal is too small to show both details and choices, the request is
481
+ denied. Shell output never triggers approval or replay. Output streams into the transcript while the
482
+ command runs, so browser-login URLs are visible before the
483
+ command finishes; the running item shows that Escape stops the command. The native result is
484
+ recorded in run activity and session history before the model is prompted to read and explain it.
485
+ This does not attach interactive stdin to the shell. SDK callers may opt into this behavior with
486
+ `SessionRunInput.initialBashCommand`; it is restricted to a new interactive user turn and the
487
+ session runner applies the same Bash gate and explicit outside-scope request.
427
488
 
428
489
  ## Reference and reproduced presentation
429
490
 
@@ -467,7 +528,7 @@ Full upstream copyright and MIT permission notices are in [NOTICE.md](../NOTICE.
467
528
  ## Runtime compatibility adapter
468
529
 
469
530
  Most integration uses public Pi exports. [`piAdapter.ts`](../src/terminal/tui/piAdapter.ts)
470
- contains the remaining presentation dependencies and requires exactly Pi **1.2.0** before
531
+ contains the remaining presentation dependencies and requires exactly Pi **1.4.0** before
471
532
  loading them. The shared [`runtime.ts`](../src/pi/runtime.ts) loader imports Pi first, then invokes
472
533
  the same HTTP dispatcher hook as Pi's CLI before any Harness Pi runtime is used. This reapplies
473
534
  the process `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` settings after Pi's bundled Undici has
@@ -477,7 +538,7 @@ concurrent initialization.
477
538
 
478
539
  | Internal dependency | Reason |
479
540
  |---|---|
480
- | `dist/bundle/chunks/chunk-TJXZSVTD.js:configureHttpDispatcher` | Restore Pi's environment-aware HTTP proxy dispatcher after the SDK import |
541
+ | `dist/bundle/chunks/chunk-MM3LKT73.js:configureHttpDispatcher` | Restore Pi's environment-aware HTTP proxy dispatcher after the SDK import |
481
542
  | `dist/extensions/index.js` builtin inventory | Preserve selected `llama.cpp`, `codemode`, `tool-search` and MCP builtins with the CLI's replacement semantics |
482
543
  | `dist/modes/interactive/theme/theme.js:setThemeInstance` | Keep public native rich components on the same active theme as the Harness screen |
483
544
  | `dist/core/tools/renderers/index.js:withBuiltInRenderers` | Preserve existing read/edit/bash/write formatting without replacing tool execution |
@@ -584,13 +645,16 @@ The bridge registers the shared `ask_user` batch tool alongside the single-quest
584
645
  `ask_user_question` contract; only plan requests activate them. Each question has a concise 1–2 word
585
646
  label, at least one choice, and at least one recommended choice; recommendations remain visual and
586
647
  never preselect. Choice-based questions also retain a free-text “Something else” answer. A pending
587
- question appears in a flat block immediately above the composer, not in a modal. It has only a muted
588
- top divider and separates its hint from the content by one blank line; below 60 terminal columns,
589
- it uses a compact hint. The body is height-bounded and vertically scrollable, with tabs and
590
- answer/action controls outside that region. While the dock is active, PageUp/PageDown scroll its
591
- body and Ctrl+Home/End jump to its beginning/end instead of the transcript. Focused choices and
592
- note fields are brought into view. A tab strip shows each
593
- question label above the active question title, with one blank row below the tabs and below the title;
648
+ question occupies the composer position in a flat block, not a modal, with the chat transcript
649
+ above it. The dock fits its content and grows to at most two-thirds of the terminal height; each
650
+ question tab is sized from its own content. When content overflows, its body scrolls while tabs and
651
+ answer/action controls stay outside that region.
652
+ The final choice sits one blank row above “Something else”. The block has only a muted top divider
653
+ and separates its hint from the content by one blank line; below 60 terminal columns, it uses a
654
+ compact hint. While the dock is active, PageUp/PageDown scroll its body and Ctrl+Home/End jump to
655
+ its beginning/end instead of the transcript. Focused choices and note fields are brought into view.
656
+ A tab strip shows each question label above the active question title, with one blank row below the tabs
657
+ and below the title;
594
658
  clicking a tab or using Left/Right changes questions without discarding staged answers. The header has
595
659
  no pager controls, and the block cannot be collapsed. Choices and descriptions appear above the numbered free-text answer and Continue or Skip
596
660
  action. Selected choices fill the whole row with subtle dark green; Continue and Submit uses a
@@ -614,6 +678,8 @@ The dock uses one shared measured layout for all choices: marker gutter, one-thi
614
678
  two-cell gap, and remaining description cell. Boundaries align across rows at every width, including
615
679
  compact terminals; both cells wrap independently, missing descriptions keep their cell, and columns
616
680
  never stack. Recommendation text becomes `(Rec.)` when the label column is fewer than 14 cells.
681
+ Multi-select choices use `✓` when selected and `○` when unselected, matching checklist glyphs;
682
+ single-choice options remain numbered.
617
683
 
618
684
  One shared border-only monospace preview below the choices follows the hovered choice, falling
619
685
  back to keyboard focus. It has no visible caption or extra left rule. Under the approved
@@ -662,12 +728,21 @@ and prompts. `/session` selects a saved session (`/resume` remains an alias), an
662
728
  branches in the current session (`/tree` remains an alias). `/btw <question>` asks a side question;
663
729
  `/side` is its alias. Help and the slash-command palette show each pair once, as `/session (resume)`,
664
730
  `/history (tree)` and `/btw (side)`; aliases still match palette searches.
665
- The separate `$` palette completes enabled skill invocations; `/skills` always browses skills. `/help`
666
- renders the command list as one transcript entry, grouped under Core, Run, Model, Session, Inspect,
667
- Harness, Plugins and Prompts; command names and descriptions wrap in aligned columns, with no
668
- blank rows between choices. `/plugins` opens the browser with protected code trust and plugin settings actions. Settings use
669
- `plugins.configure`; on/off settings and bounded whole-number settings keep their existing ranges.
670
- Saved settings are read when the plugin next uses them and do not require a restart. The standalone
731
+ With no path argument, `/session` opens a full-screen searchable page. Each unnumbered row shows a
732
+ normal-color title and a muted second line with relative activity time, `<project>:<branch>` and JSONL
733
+ file size separated by ` · `. One blank line separates each session. Enter resumes the selected
734
+ session; account and folder scope checks
735
+ remain enforced. Supplying an explicit path continues directly without opening the picker.
736
+ The `$` palette completes enabled skill invocations using the same two-column palette as slash
737
+ commands; `/skills` always browses skills. Choosing a skill inserts `$name ` without submitting.
738
+ A recognized leading `$name` uses the blue accent in the composer, while its arguments, unavailable
739
+ names and ordinary currency text keep the normal color. `/help` renders the command list as one
740
+ transcript entry, grouped under Core, Run, Model, Session, Inspect, Harness, Plugins and Prompts;
741
+ command names and descriptions wrap in aligned columns, with no blank rows between choices. `/plugins`
742
+ opens the focused local manager; its Packages tab installs, updates and removes packages with protected
743
+ Harness operations. Settings use `plugins.configure`; on/off settings and bounded whole-number settings
744
+ keep their existing ranges. Saved settings are read when the plugin next uses them and do not require a
745
+ restart. The standalone
671
746
  terminal no longer has separate `/login`, `/trust`, `/bug`, `/changelog`, `/share`, `/scoped-mode` or
672
747
  `/import` commands. `/btw <question>` (or `/side <question>`) starts a separate Harness run with the
673
748
  main run's effective instructions, visible conversation and redacted public tool inputs/results.
@@ -696,14 +771,18 @@ and URL queries and omits response bodies, prompts and message contents. Embedde
696
771
 
697
772
  ## Slash command ownership
698
773
 
699
- Core commands and commands owned by required built-in plugins stay unprefixed. The required
700
- plugin commands are `/subagents`, `/agents`, `/trajectory`, `/doctor`, and `/worktree`. Optional built-in
701
- plugin commands (currently `/plugin:notes` and `/plugin:annotate`) and Pi extension commands use
702
- `/plugin:<command>`. A bare core command, alias, required built-in command, or loaded prompt owns its
703
- name; a colliding prefixed command is omitted and rejected with a hint to use the bare command.
704
- Duplicate extension names are rejected with the extension paths shown in the diagnostic. Old
705
- `/plugin:` forms of required built-in commands are not aliases. Prompt templates and
706
- `/skill:<name>` keep their existing forms.
774
+ Harness core commands are unprefixed and live in the core terminal command registry, independently
775
+ of feature-plugin command metadata: `/doctor`, `/worktree`, `/trajectory`, `/subagents`, and `/agents`.
776
+ `/history` (also `/tree`) continues to navigate session branches. `/mcp` and `/connections` open the
777
+ Connections browser. Feature descriptors and their services remain registered; only these terminal
778
+ routes move out of the plugin command registry. Other plugin-owned commands continue to use
779
+ `/<owner-prefix>:<command>`. The annotations plugin uses `/annotate:annotate` and `/annotate:notes`;
780
+ `/annotate:` opens its default capture pane. Pi package extensions use their normalized package name
781
+ as owner prefix unless `harness.commandPrefix` overrides it; loose extensions use their normalized
782
+ extension name. A plugin prefix collision or a duplicate command within one owner is rejected with
783
+ owner paths in the diagnostic. The former owner-qualified and `/plugin:<command>` routes of promoted
784
+ Harness commands remain hidden compatibility aliases for one release, omitted from help and
785
+ completion. Prompt templates and `/skill:<name>` keep their existing forms.
707
786
 
708
787
  ## Input performance profile
709
788
 
@@ -853,8 +932,9 @@ inherit that retained ledger.
853
932
 
854
933
  ## Agent-managed session names
855
934
 
856
- Agents can use `session_name({ name: string })` to name meaningful work early and revise
857
- its name when the objective changes. Names submitted by agents are short imperative
935
+ Agents can use `session_name({ name: string })` to name work before their first other tool call
936
+ when a request needs tools or changes state, and revise the name only when the objective changes.
937
+ Names submitted by agents are short imperative
858
938
  sentences with at most six words. The agent may revise a manual name; `/name` remains
859
939
  available and manual names have no new word limit. Pi stores the name in native history,
860
940
  so resuming the same conversation restores it without another model request.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xingular/harness",
3
- "version": "1.1.1",
3
+ "version": "1.3.1-unstable.0",
4
4
  "type": "module",
5
5
  "description": "Xingular Harness — a Pi agent harness built on recursive harnessing (Harness²): versioned eight-component variants, refinement from evidence, multi-account sessions, a compiled prompt, project notes, tools, and MCP",
6
6
  "repository": {
@@ -35,6 +35,7 @@
35
35
  "test": "vitest run",
36
36
  "profile:terminal-input": "node scripts/profile-terminal-input.mjs",
37
37
  "profile:terminal-latency": "python3 scripts/profile-terminal-latency.py",
38
+ "profile:session-runtime": "node scripts/profile-session-runtime.mjs",
38
39
  "prove": "npm run build && node scripts/prove-standalone.mjs",
39
40
  "build:sdk": "node scripts/build-sdk.mjs",
40
41
  "release:pack": "node scripts/release-pack.mjs",
@@ -42,8 +43,8 @@
42
43
  "release:preflight": "node scripts/release-preflight.mjs"
43
44
  },
44
45
  "dependencies": {
45
- "@earendil-works/pi-coding-agent": "1.2.0",
46
- "@earendil-works/pi-tui": "1.2.0",
46
+ "@earendil-works/pi-coding-agent": "1.4.0",
47
+ "@earendil-works/pi-tui": "1.4.0",
47
48
  "@modelcontextprotocol/client": "^2.2.0",
48
49
  "@modelcontextprotocol/server": "^2.2.0",
49
50
  "@opentui/core": "^0.6.6",
@@ -1,9 +0,0 @@
1
- import { type ChecklistItem, type RunEvent } from "../sessions/contracts.js";
2
- import type { ActiveRun } from "../sessions/registry.js";
3
- import type { ToolSpec } from "./types.js";
4
- export declare const CHECKLIST_WRITE = "checklist_write";
5
- /** The checklist as the model reads it back. */
6
- export declare function describeChecklist(items: readonly ChecklistItem[]): string;
7
- /** The latest checklist a run wrote, or an empty list. */
8
- export declare function checklistOf(events: readonly RunEvent[]): ChecklistItem[];
9
- export declare function checklistTool(run: Pick<ActiveRun, 'emit'>): ToolSpec;
@@ -1,54 +0,0 @@
1
- // The run's own checklist: the model writes the whole list each time, and the run records it as
2
- // a `checklist.updated` event. It only changes run state, so it stays callable in plan mode.
3
- import { checklistItemSchema, MAX_CHECKLIST_ITEMS } from "../sessions/contracts.js";
4
- export const CHECKLIST_WRITE = 'checklist_write';
5
- const MARK = { pending: '[ ]', in_progress: '[~]', completed: '[x]' };
6
- /** The checklist as the model reads it back. */
7
- export function describeChecklist(items) {
8
- if (!items.length)
9
- return 'The checklist is empty.';
10
- return items.map((item) => `${MARK[item.status]} ${item.text}`).join('\n');
11
- }
12
- /** The latest checklist a run wrote, or an empty list. */
13
- export function checklistOf(events) {
14
- const last = events.filter((event) => event.type === 'checklist.updated').at(-1);
15
- const items = last?.payload?.items;
16
- return Array.isArray(items) ? items.flatMap((item) => {
17
- const parsed = checklistItemSchema.safeParse(item);
18
- return parsed.success ? [parsed.data] : [];
19
- }) : [];
20
- }
21
- export function checklistTool(run) {
22
- return {
23
- name: CHECKLIST_WRITE,
24
- label: 'Write the checklist',
25
- description: 'Keep a checklist of the steps of the current work. The user watches this list to follow your progress, so write it early and keep it current. Send the whole list every time; it replaces the previous one. ' +
26
- 'Use it whenever the work has several distinct steps or will take several tool calls, when the user gives several things to do, and when a subagent brief asks for more than one thing. Do not use it for a single, simple step or for conversation. ' +
27
- 'Statuses: pending, in_progress, completed. Keep exactly one step in_progress while you work, mark a step completed as soon as it is done (not in batches), and add steps you discover. ' +
28
- 'Only mark a step completed when it is fully done; if something blocks it, keep it in_progress and add a step for the blocker.',
29
- parameters: (Type) => Type.Object({
30
- items: Type.Array(Type.Object({
31
- text: Type.String({ description: 'One step, as a short imperative line' }),
32
- status: Type.Union([Type.Literal('pending'), Type.Literal('in_progress'), Type.Literal('completed')])
33
- }), { maxItems: MAX_CHECKLIST_ITEMS })
34
- }),
35
- readOnly: true,
36
- planModeSafe: () => true,
37
- execute: async (input) => {
38
- if (!Array.isArray(input.items))
39
- return 'Send items: the whole checklist as an array.';
40
- if (input.items.length > MAX_CHECKLIST_ITEMS)
41
- return `Keep the checklist to ${MAX_CHECKLIST_ITEMS} steps or fewer.`;
42
- const items = [];
43
- for (const raw of input.items) {
44
- const entry = raw;
45
- const parsed = checklistItemSchema.safeParse({ text: typeof entry?.text === 'string' ? entry.text.trim() : entry?.text, status: entry?.status });
46
- if (!parsed.success)
47
- return 'Every step needs text of 1 to 500 characters and a status of pending, in_progress or completed.';
48
- items.push(parsed.data);
49
- }
50
- run.emit('checklist.updated', { items });
51
- return describeChecklist(items);
52
- }
53
- };
54
- }