@xingular/harness 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (397) hide show
  1. package/CHANGELOG.md +46 -5
  2. package/README.md +75 -21
  3. package/dist/cli.js +17421 -8711
  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.d.ts +2 -0
  11. package/dist/sdk/agents/builtin.js +48 -0
  12. package/dist/sdk/agents/narrow.d.ts +13 -0
  13. package/dist/sdk/agents/narrow.js +29 -0
  14. package/dist/sdk/agents/planResearch.d.ts +5 -0
  15. package/dist/sdk/agents/planResearch.js +19 -0
  16. package/dist/sdk/agents/profiles.d.ts +81 -0
  17. package/dist/sdk/agents/profiles.js +226 -0
  18. package/dist/sdk/annotations/bridge.d.ts +42 -0
  19. package/dist/sdk/annotations/bridge.js +264 -0
  20. package/dist/sdk/annotations/capture.d.ts +116 -0
  21. package/dist/sdk/annotations/capture.js +308 -0
  22. package/dist/sdk/annotations/delivery.d.ts +72 -0
  23. package/dist/sdk/annotations/delivery.js +130 -0
  24. package/dist/sdk/annotations/inspect.d.ts +10 -0
  25. package/dist/sdk/annotations/inspect.js +33 -0
  26. package/dist/sdk/annotations/isolated.d.ts +6 -0
  27. package/dist/sdk/annotations/isolated.js +51 -0
  28. package/dist/sdk/annotations/pageScript.d.ts +28 -0
  29. package/dist/sdk/annotations/pageScript.js +871 -0
  30. package/dist/sdk/annotations/part.d.ts +10 -0
  31. package/dist/sdk/annotations/part.js +155 -0
  32. package/dist/sdk/annotations/queue.d.ts +4 -0
  33. package/dist/sdk/annotations/queue.js +40 -0
  34. package/dist/sdk/annotations/serverMethods.d.ts +3 -0
  35. package/dist/sdk/annotations/serverMethods.js +62 -0
  36. package/dist/sdk/annotations/store.d.ts +167 -0
  37. package/dist/sdk/annotations/store.js +394 -0
  38. package/dist/sdk/browser/backend.d.ts +16 -0
  39. package/dist/sdk/browser/backend.js +17 -0
  40. package/dist/sdk/browser/contracts.d.ts +19 -0
  41. package/dist/sdk/browser/contracts.js +116 -0
  42. package/dist/sdk/browser/index.d.ts +14 -3
  43. package/dist/sdk/browser/index.js +11 -4
  44. package/dist/sdk/browser/serverMethods.d.ts +3 -0
  45. package/dist/sdk/browser/serverMethods.js +7 -0
  46. package/dist/sdk/browser/session.d.ts +1 -0
  47. package/dist/sdk/browser/session.js +45 -9
  48. package/dist/sdk/browser/tools.d.ts +1 -4
  49. package/dist/sdk/browser/tools.js +14 -91
  50. package/dist/sdk/cli.js +24 -15
  51. package/dist/sdk/commands/list.d.ts +3 -0
  52. package/dist/sdk/commands/list.js +75 -0
  53. package/dist/sdk/commands/registry.d.ts +250 -0
  54. package/dist/sdk/commands/registry.js +47 -0
  55. package/dist/sdk/commands/routes.d.ts +16 -0
  56. package/dist/sdk/commands/routes.js +33 -0
  57. package/dist/sdk/core/bus.js +1 -1
  58. package/dist/sdk/core/commandBudget.d.ts +23 -0
  59. package/dist/sdk/core/commandBudget.js +57 -0
  60. package/dist/sdk/core/env.d.ts +1 -1
  61. package/dist/sdk/core/env.js +1 -1
  62. package/dist/sdk/core/index.js +17 -1
  63. package/dist/sdk/core/interactiveProfile.d.ts +46 -0
  64. package/dist/sdk/core/interactiveProfile.js +143 -0
  65. package/dist/sdk/core/workspace.d.ts +13 -0
  66. package/dist/sdk/core/workspace.js +88 -0
  67. package/dist/sdk/core/workspaceBashTool.d.ts +4 -0
  68. package/dist/sdk/core/workspaceBashTool.js +36 -0
  69. package/dist/sdk/core/workspaceSandbox.d.ts +31 -0
  70. package/dist/sdk/core/workspaceSandbox.js +320 -0
  71. package/dist/sdk/core/workspaceWriteOperations.d.ts +22 -0
  72. package/dist/sdk/core/workspaceWriteOperations.js +206 -0
  73. package/dist/sdk/doctor/serverMethods.d.ts +3 -0
  74. package/dist/sdk/doctor/serverMethods.js +8 -0
  75. package/dist/sdk/doctor/types.d.ts +2 -2
  76. package/dist/sdk/harness.d.ts +22 -0
  77. package/dist/sdk/harness.js +84 -5
  78. package/dist/sdk/history/recall.js +8 -8
  79. package/dist/sdk/history/serverMethods.d.ts +3 -0
  80. package/dist/sdk/history/serverMethods.js +8 -0
  81. package/dist/sdk/hub/cli.d.ts +1 -1
  82. package/dist/sdk/hub/cli.js +1 -1
  83. package/dist/sdk/hub/schema.d.ts +1 -1
  84. package/dist/sdk/hub/serverMethods.d.ts +3 -0
  85. package/dist/sdk/hub/serverMethods.js +11 -0
  86. package/dist/sdk/index.d.ts +16 -1
  87. package/dist/sdk/index.js +10 -0
  88. package/dist/sdk/mcp/connections.js +14 -7
  89. package/dist/sdk/mcp/serverMethods.d.ts +3 -0
  90. package/dist/sdk/mcp/serverMethods.js +22 -0
  91. package/dist/sdk/pi/runtime.d.ts +2 -1
  92. package/dist/sdk/pi/runtime.js +2 -2
  93. package/dist/sdk/plugins/builtin.d.ts +1 -0
  94. package/dist/sdk/plugins/builtin.js +145 -33
  95. package/dist/sdk/plugins/builtinRegistry.d.ts +60 -0
  96. package/dist/sdk/plugins/builtinRegistry.js +71 -0
  97. package/dist/sdk/plugins/catalogue.js +2 -1
  98. package/dist/sdk/plugins/cli.d.ts +1 -1
  99. package/dist/sdk/plugins/cli.js +4 -3
  100. package/dist/sdk/plugins/commandPrefix.d.ts +8 -0
  101. package/dist/sdk/plugins/commandPrefix.js +21 -0
  102. package/dist/sdk/plugins/firstParty.d.ts +1 -1
  103. package/dist/sdk/plugins/firstParty.js +8 -2
  104. package/dist/sdk/plugins/inventory.js +4 -3
  105. package/dist/sdk/plugins/manifest.d.ts +2 -0
  106. package/dist/sdk/plugins/manifest.js +2 -1
  107. package/dist/sdk/plugins/surfaces.d.ts +5 -0
  108. package/dist/sdk/plugins/surfaces.js +11 -0
  109. package/dist/sdk/plugins/types.d.ts +15 -0
  110. package/dist/sdk/prompt/compile.d.ts +19 -2
  111. package/dist/sdk/prompt/compile.js +79 -26
  112. package/dist/sdk/prompt/standard.d.ts +17 -0
  113. package/dist/sdk/prompt/standard.js +21 -0
  114. package/dist/sdk/refine/cli.d.ts +1 -1
  115. package/dist/sdk/refine/cli.js +2 -2
  116. package/dist/sdk/refine/serverMethods.d.ts +3 -0
  117. package/dist/sdk/refine/serverMethods.js +20 -0
  118. package/dist/sdk/server/methods.js +27 -86
  119. package/dist/sdk/server/params.d.ts +4 -0
  120. package/dist/sdk/server/params.js +11 -0
  121. package/dist/sdk/server/remote.js +36 -11
  122. package/dist/sdk/sessions/compactionCheckpoint.d.ts +11 -0
  123. package/dist/sdk/sessions/compactionCheckpoint.js +79 -0
  124. package/dist/sdk/sessions/continuation.d.ts +3 -0
  125. package/dist/sdk/sessions/continuation.js +5 -1
  126. package/dist/sdk/sessions/contracts.d.ts +185 -0
  127. package/dist/sdk/sessions/contracts.js +101 -4
  128. package/dist/sdk/sessions/control.d.ts +72 -0
  129. package/dist/sdk/sessions/control.js +158 -0
  130. package/dist/sdk/sessions/initialBash.d.ts +7 -0
  131. package/dist/sdk/sessions/initialBash.js +7 -0
  132. package/dist/sdk/sessions/planMode.d.ts +18 -4
  133. package/dist/sdk/sessions/planMode.js +82 -16
  134. package/dist/sdk/sessions/reasoningSummaries.d.ts +2 -2
  135. package/dist/sdk/sessions/reasoningSummaries.js +3 -3
  136. package/dist/sdk/sessions/registry.d.ts +2 -1
  137. package/dist/sdk/sessions/registry.js +6 -3
  138. package/dist/sdk/sessions/runIndex.js +7 -7
  139. package/dist/sdk/sessions/runStore.d.ts +14 -0
  140. package/dist/sdk/sessions/runStore.js +38 -1
  141. package/dist/sdk/sessions/runner.d.ts +40 -2
  142. package/dist/sdk/sessions/runner.js +163 -15
  143. package/dist/sdk/sessions/sessions.d.ts +40 -8
  144. package/dist/sdk/sessions/sessions.js +279 -27
  145. package/dist/sdk/sessions/sideQuestionServerMethods.d.ts +3 -0
  146. package/dist/sdk/sessions/sideQuestionServerMethods.js +19 -0
  147. package/dist/sdk/sessions/sideQuestions.d.ts +66 -0
  148. package/dist/sdk/sessions/sideQuestions.js +290 -0
  149. package/dist/sdk/sessions/subagentServerMethods.d.ts +3 -0
  150. package/dist/sdk/sessions/subagentServerMethods.js +41 -0
  151. package/dist/sdk/sessions/subagentService.d.ts +22 -2
  152. package/dist/sdk/sessions/subagentService.js +93 -16
  153. package/dist/sdk/sessions/subagents.d.ts +9 -1
  154. package/dist/sdk/sessions/subagents.js +19 -0
  155. package/dist/sdk/sessions/workSlice.d.ts +103 -0
  156. package/dist/sdk/sessions/workSlice.js +297 -0
  157. package/dist/sdk/sessions/workspaceBoundary.d.ts +15 -0
  158. package/dist/sdk/sessions/workspaceBoundary.js +46 -0
  159. package/dist/sdk/terminal/browser.d.ts +62 -0
  160. package/dist/sdk/terminal/browser.js +41 -0
  161. package/dist/sdk/terminal/browserControl.d.ts +29 -0
  162. package/dist/sdk/terminal/browserControl.js +187 -0
  163. package/dist/sdk/terminal/commandHelp.d.ts +17 -0
  164. package/dist/sdk/terminal/commandHelp.js +20 -0
  165. package/dist/sdk/terminal/controller.d.ts +15 -1
  166. package/dist/sdk/terminal/controller.js +67 -8
  167. package/dist/sdk/terminal/opentui/subagentsWidget.d.ts +28 -0
  168. package/dist/sdk/terminal/opentui/subagentsWidget.js +52 -0
  169. package/dist/sdk/terminal/opentui/theme.d.ts +43 -0
  170. package/dist/sdk/terminal/opentui/theme.js +87 -0
  171. package/dist/sdk/terminal/piExtension.d.ts +6 -1
  172. package/dist/sdk/terminal/piExtension.js +169 -84
  173. package/dist/sdk/terminal/socket.d.ts +6 -3
  174. package/dist/sdk/terminal/socket.js +40 -9
  175. package/dist/sdk/terminal/standalone.d.ts +9 -0
  176. package/dist/sdk/terminal/standalone.js +118 -19
  177. package/dist/sdk/terminal/subagentMonitor.d.ts +47 -0
  178. package/dist/sdk/terminal/subagentMonitor.js +152 -0
  179. package/dist/sdk/terminal/terminals.d.ts +60 -7
  180. package/dist/sdk/terminal/terminals.js +598 -47
  181. package/dist/sdk/terminal/trajectory.js +2 -2
  182. package/dist/sdk/terminal/tui/annotateCommand.d.ts +3 -0
  183. package/dist/sdk/terminal/tui/annotateCommand.js +22 -0
  184. package/dist/sdk/terminal/tui/commandPages.d.ts +7 -1
  185. package/dist/sdk/terminal/tui/commandPages.js +57 -6
  186. package/dist/sdk/terminal/tui/commands.d.ts +10 -4
  187. package/dist/sdk/terminal/tui/commands.js +269 -65
  188. package/dist/sdk/terminal/tui/dialogGeometry.d.ts +2 -2
  189. package/dist/sdk/terminal/tui/dialogGeometry.js +4 -2
  190. package/dist/sdk/terminal/tui/dialogs.d.ts +6 -1
  191. package/dist/sdk/terminal/tui/dialogs.js +9 -2
  192. package/dist/sdk/terminal/tui/list.d.ts +14 -1
  193. package/dist/sdk/terminal/tui/list.js +96 -14
  194. package/dist/sdk/terminal/tui/modelPicker.js +1 -6
  195. package/dist/sdk/terminal/tui/page.d.ts +3 -0
  196. package/dist/sdk/terminal/tui/pageOverlay.js +27 -7
  197. package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +26 -4
  198. package/dist/sdk/terminal/tui/pages/accountsPage.js +264 -36
  199. package/dist/sdk/terminal/tui/pages/agentsPage.d.ts +74 -0
  200. package/dist/sdk/terminal/tui/pages/agentsPage.js +190 -0
  201. package/dist/sdk/terminal/tui/pages/annotatePage.d.ts +94 -0
  202. package/dist/sdk/terminal/tui/pages/annotatePage.js +341 -0
  203. package/dist/sdk/terminal/tui/pages/browserPage.d.ts +87 -0
  204. package/dist/sdk/terminal/tui/pages/browserPage.js +738 -0
  205. package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +2 -0
  206. package/dist/sdk/terminal/tui/pages/doctorPage.js +103 -15
  207. package/dist/sdk/terminal/tui/pages/notesPage.d.ts +75 -0
  208. package/dist/sdk/terminal/tui/pages/notesPage.js +201 -0
  209. package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +0 -5
  210. package/dist/sdk/terminal/tui/pages/pluginsPage.js +9 -3
  211. package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +8 -0
  212. package/dist/sdk/terminal/tui/pages/settingsPage.js +16 -1
  213. package/dist/sdk/terminal/tui/pages/subagentsPage.d.ts +24 -0
  214. package/dist/sdk/terminal/tui/pages/subagentsPage.js +152 -0
  215. package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +12 -5
  216. package/dist/sdk/terminal/tui/pages/trajectoryPage.js +156 -83
  217. package/dist/sdk/terminal/tui/pages/usagePage.d.ts +43 -0
  218. package/dist/sdk/terminal/tui/pages/usagePage.js +370 -0
  219. package/dist/sdk/terminal/tui/pages/worktreesPage.d.ts +72 -0
  220. package/dist/sdk/terminal/tui/pages/worktreesPage.js +203 -0
  221. package/dist/sdk/terminal/tui/piAdapter.d.ts +1 -2
  222. package/dist/sdk/terminal/tui/piAdapter.js +3 -5
  223. package/dist/sdk/terminal/tui/planMode.d.ts +1 -1
  224. package/dist/sdk/terminal/tui/planMode.js +1 -1
  225. package/dist/sdk/terminal/tui/pluginCommands.d.ts +16 -0
  226. package/dist/sdk/terminal/tui/pluginCommands.js +31 -0
  227. package/dist/sdk/terminal/tui/questions.d.ts +2 -0
  228. package/dist/sdk/terminal/tui/runtime.js +27 -5
  229. package/dist/sdk/terminal/tui/sessionPicker.d.ts +40 -0
  230. package/dist/sdk/terminal/tui/sessionPicker.js +141 -0
  231. package/dist/sdk/terminal/tui/settingsModel.d.ts +2 -0
  232. package/dist/sdk/terminal/tui/settingsModel.js +32 -2
  233. package/dist/sdk/terminal/tui/sideQuestion.d.ts +26 -26
  234. package/dist/sdk/terminal/tui/sideQuestion.js +131 -98
  235. package/dist/sdk/terminal/tui/ui.d.ts +2 -0
  236. package/dist/sdk/terminal/tui/ui.js +1 -0
  237. package/dist/sdk/tools/askUser.js +26 -8
  238. package/dist/sdk/tools/checklist.js +3 -2
  239. package/dist/sdk/tools/checkpoint.d.ts +27 -0
  240. package/dist/sdk/tools/checkpoint.js +154 -0
  241. package/dist/sdk/tools/getCapabilities.d.ts +31 -0
  242. package/dist/sdk/tools/getCapabilities.js +34 -0
  243. package/dist/sdk/tools/harnessTools.d.ts +2 -0
  244. package/dist/sdk/tools/harnessTools.js +1 -1
  245. package/dist/sdk/tools/spawnSubagent.js +14 -4
  246. package/dist/sdk/usage/analytics.d.ts +20 -0
  247. package/dist/sdk/usage/analytics.js +151 -0
  248. package/dist/sdk/usage/ledger.d.ts +38 -0
  249. package/dist/sdk/usage/ledger.js +142 -0
  250. package/dist/sdk/usage/limits/adapters.d.ts +11 -0
  251. package/dist/sdk/usage/limits/adapters.js +349 -0
  252. package/dist/sdk/usage/limits/capture.d.ts +8 -0
  253. package/dist/sdk/usage/limits/capture.js +47 -0
  254. package/dist/sdk/usage/limits/http.d.ts +12 -0
  255. package/dist/sdk/usage/limits/http.js +51 -0
  256. package/dist/sdk/usage/limits/normalize.d.ts +15 -0
  257. package/dist/sdk/usage/limits/normalize.js +211 -0
  258. package/dist/sdk/usage/limits/service.d.ts +30 -0
  259. package/dist/sdk/usage/limits/service.js +176 -0
  260. package/dist/sdk/usage/limits/types.d.ts +65 -0
  261. package/dist/sdk/usage/limits/types.js +1 -0
  262. package/dist/sdk/usage/serverMethods.d.ts +3 -0
  263. package/dist/sdk/usage/serverMethods.js +22 -0
  264. package/dist/sdk/usage/service.d.ts +32 -0
  265. package/dist/sdk/usage/service.js +66 -0
  266. package/dist/sdk/usage/settings.d.ts +7 -0
  267. package/dist/sdk/usage/settings.js +28 -0
  268. package/dist/sdk/usage/types.d.ts +60 -0
  269. package/dist/sdk/usage/types.js +4 -0
  270. package/dist/sdk/web/part.d.ts +10 -0
  271. package/dist/sdk/web/part.js +6 -0
  272. package/dist/sdk/web/serverMethods.d.ts +3 -0
  273. package/dist/sdk/web/serverMethods.js +7 -0
  274. package/dist/sdk/wiki/serverMethods.d.ts +3 -0
  275. package/dist/sdk/wiki/serverMethods.js +26 -0
  276. package/dist/sdk/worktrees/cli.d.ts +11 -0
  277. package/dist/sdk/worktrees/cli.js +146 -0
  278. package/dist/sdk/worktrees/copy.d.ts +9 -0
  279. package/dist/sdk/worktrees/copy.js +111 -0
  280. package/dist/sdk/worktrees/git.d.ts +16 -0
  281. package/dist/sdk/worktrees/git.js +81 -0
  282. package/dist/sdk/worktrees/serverMethods.d.ts +3 -0
  283. package/dist/sdk/worktrees/serverMethods.js +30 -0
  284. package/dist/sdk/worktrees/service.d.ts +73 -0
  285. package/dist/sdk/worktrees/service.js +483 -0
  286. package/dist/sdk/worktrees/setup.d.ts +23 -0
  287. package/dist/sdk/worktrees/setup.js +65 -0
  288. package/dist/sdk/worktrees/types.d.ts +91 -0
  289. package/dist/sdk/worktrees/types.js +1 -0
  290. package/dist/sdk/world/cli.d.ts +2 -2
  291. package/dist/sdk/world/cli.js +6 -6
  292. package/dist/sdk/world/world.d.ts +3 -1
  293. package/dist/sdk/world/world.js +8 -9
  294. package/dist/terminal-opentui.js +16456 -5966
  295. package/dist/terminal-pi.js +1579 -573
  296. package/docs/README.md +22 -2
  297. package/docs/architecture/00-overview.md +28 -16
  298. package/docs/architecture/02-sessions-and-runs.md +184 -25
  299. package/docs/architecture/03-variants.md +10 -2
  300. package/docs/architecture/04-prompt.md +65 -7
  301. package/docs/architecture/06-plugins-and-capabilities.md +57 -4
  302. package/docs/architecture/07-tools-and-gate.md +112 -17
  303. package/docs/architecture/08-memory-and-history.md +4 -2
  304. package/docs/architecture/09-accounts-and-connectors.md +39 -1
  305. package/docs/architecture/10-server-protocol.md +168 -4
  306. package/docs/architecture/11-terminal.md +251 -8
  307. package/docs/architecture/12-storage.md +45 -3
  308. package/docs/architecture/13-world-tools.md +49 -6
  309. package/docs/architecture/14-surfaces-and-parity.md +136 -0
  310. package/docs/architecture/README.md +17 -4
  311. package/docs/architecture/proposals/PROP-0006-run-checklist.md +4 -2
  312. package/docs/architecture/proposals/PROP-0013-resource-browser.md +58 -0
  313. package/docs/architecture/proposals/PROP-0014-fullscreen-browser-tabs.md +58 -0
  314. package/docs/architecture/proposals/PROP-0015-one-capability-surface.md +88 -0
  315. package/docs/architecture/proposals/PROP-0016-managed-worktrees.md +156 -0
  316. package/docs/architecture/proposals/PROP-0017-page-annotations.md +131 -0
  317. package/docs/architecture/proposals/PROP-0018-annotation-queue-and-app-targets.md +179 -0
  318. package/docs/architecture/proposals/PROP-0019-contextual-side-questions.md +122 -0
  319. package/docs/architecture/proposals/PROP-0020-builtin-feature-plugins.md +105 -0
  320. package/docs/architecture/proposals/PROP-0021-command-namespaces-and-duplicates.md +99 -0
  321. package/docs/architecture/proposals/PROP-0022-plan-only-questions.md +102 -0
  322. package/docs/architecture/proposals/PROP-0023-xagent-cli-name.md +61 -0
  323. package/docs/architecture/proposals/PROP-0024-question-sketch-previews.md +130 -0
  324. package/docs/architecture/proposals/PROP-0025-contextual-question-wireframes.md +49 -0
  325. package/docs/architecture/proposals/PROP-0026-connected-sketch-display.md +94 -0
  326. package/docs/architecture/proposals/PROP-0027-xingular-agent-product-identity.md +60 -0
  327. package/docs/architecture/proposals/PROP-0028-normalize-question-wireframes.md +55 -0
  328. package/docs/architecture/proposals/PROP-0029-agent-profiles.md +124 -0
  329. package/docs/architecture/proposals/PROP-0030-subagent-title.md +86 -0
  330. package/docs/architecture/proposals/PROP-0031-plugin-command-owner-namespaces.md +54 -0
  331. package/docs/architecture/proposals/PROP-0032-planning-quality.md +196 -0
  332. package/docs/architecture/proposals/PROP-0033-compaction-plan-checkpoints.md +75 -0
  333. package/docs/architecture/proposals/PROP-0034-conversation-fast-mode.md +120 -0
  334. package/docs/architecture/proposals/PROP-0035-retain-subagent-status.md +47 -0
  335. package/docs/architecture/proposals/PROP-0036-first-class-harness-commands.md +59 -0
  336. package/docs/architecture/proposals/PROP-0037-workspace-write-boundary.md +63 -0
  337. package/docs/architecture/proposals/PROP-0038-annotate-open-shadow-roots.md +73 -0
  338. package/docs/architecture/proposals/PROP-0039-workspace-boundary-hardening.md +139 -0
  339. package/docs/architecture/proposals/PROP-0040-one-launch-path.md +87 -0
  340. package/docs/architecture/proposals/PROP-0041-bounded-work-slices.md +247 -0
  341. package/docs/architecture/proposals/PROP-0042-usage-and-provider-limits.md +127 -0
  342. package/docs/architecture/proposals/PROP-0043-read-only-plan-bash.md +74 -0
  343. package/docs/architecture/proposals/README.md +39 -0
  344. package/docs/decisions/ADR-0001-owned-terminal.md +1 -1
  345. package/docs/decisions/ADR-0009-xharness-command.md +6 -5
  346. package/docs/decisions/ADR-0014-public-release-baseline.md +3 -2
  347. package/docs/decisions/ADR-0015-resource-browser.md +28 -0
  348. package/docs/decisions/ADR-0016-fullscreen-browser-tabs.md +31 -0
  349. package/docs/decisions/ADR-0017-one-capability-surface.md +34 -0
  350. package/docs/decisions/ADR-0018-builtin-feature-plugins.md +35 -0
  351. package/docs/decisions/ADR-0019-managed-git-worktrees.md +31 -0
  352. package/docs/decisions/ADR-0020-page-annotations.md +37 -0
  353. package/docs/decisions/ADR-0021-required-command-namespaces.md +40 -0
  354. package/docs/decisions/ADR-0022-plan-only-question-tools.md +34 -0
  355. package/docs/decisions/ADR-0023-contextual-side-question-runs.md +35 -0
  356. package/docs/decisions/ADR-0024-xagent-command.md +40 -0
  357. package/docs/decisions/ADR-0025-question-choice-sketches.md +49 -0
  358. package/docs/decisions/ADR-0026-contextual-question-wireframes.md +58 -0
  359. package/docs/decisions/ADR-0027-connected-sketch-display.md +60 -0
  360. package/docs/decisions/ADR-0028-xingular-agent-product-identity.md +56 -0
  361. package/docs/decisions/ADR-0029-normalized-question-wireframe-borders.md +33 -0
  362. package/docs/decisions/ADR-0030-agent-profiles.md +43 -0
  363. package/docs/decisions/ADR-0031-plugin-command-owner-namespaces.md +37 -0
  364. package/docs/decisions/ADR-0032-compaction-run-checkpoints.md +33 -0
  365. package/docs/decisions/ADR-0033-plan-mode-research-delegation.md +47 -0
  366. package/docs/decisions/ADR-0034-first-class-harness-terminal-commands.md +25 -0
  367. package/docs/decisions/ADR-0035-one-launch-path.md +40 -0
  368. package/docs/decisions/ADR-0036-workspace-write-operation-boundary.md +54 -0
  369. package/docs/decisions/ADR-0037-usage-ledger-and-provider-limits.md +44 -0
  370. package/docs/decisions/ADR-0038-plan-bash-os-read-only.md +29 -0
  371. package/docs/doctor.md +10 -4
  372. package/docs/experiments/EXP-0003-performance-audit/data/session-runtime-replication.json +420 -0
  373. package/docs/experiments/EXP-0003-performance-audit/data/session-runtime.json +420 -0
  374. package/docs/experiments/EXP-0003-performance-audit/data/terminal-compact.json +376 -0
  375. package/docs/experiments/EXP-0003-performance-audit/data/terminal-history.json +422 -0
  376. package/docs/experiments/EXP-0003-performance-audit/data/terminal-question.json +95 -0
  377. package/docs/experiments/EXP-0003-performance-audit/data/terminal-wide.json +1036 -0
  378. package/docs/experiments/EXP-0003-performance-audit/plan.md +109 -0
  379. package/docs/experiments/EXP-0003-performance-audit/results.md +151 -0
  380. package/docs/features/README.md +26 -0
  381. package/docs/features/interfaces/README.md +1 -1
  382. package/docs/future-work.md +48 -0
  383. package/docs/handoff-2026-10-25-app-parity-and-solo-tabs.md +202 -0
  384. package/docs/parity.md +134 -0
  385. package/docs/releases/1.0.0.md +2 -2
  386. package/docs/releases/1.1.1.md +28 -0
  387. package/docs/releases/1.2.0.md +49 -0
  388. package/docs/releases/4.0.0.md +47 -0
  389. package/docs/releases/README.md +37 -27
  390. package/docs/study/00-index.md +8 -0
  391. package/docs/study/STUDY-0003-long-horizon-runs.md +210 -0
  392. package/docs/study/autonomous-engineering-sources.md +277 -0
  393. package/docs/study/autonomy-sources.md +147 -0
  394. package/docs/study/proactive-autonomy.md +408 -0
  395. package/docs/study/tui-resource-browser.md +78 -0
  396. package/docs/terminal-tui.md +386 -113
  397. package/package.json +6 -5
@@ -5,28 +5,51 @@ import { appendFileSync } from 'node:fs';
5
5
  import { homedir } from 'node:os';
6
6
  import { isAbsolute, join, resolve } from 'node:path';
7
7
  import { setLogSink } from "../core/bus.js";
8
+ import { DEFAULT_PRODUCT_NAME } from "../core/env.js";
9
+ import { interactiveProfileSecretStore, resolveInteractiveProfile } from "../core/interactiveProfile.js";
8
10
  import { createHarness } from "../harness.js";
11
+ import { seedVariant } from "../variant/seed.js";
12
+ import * as variantStore from "../variant/store.js";
9
13
  export function standaloneArguments(argv) {
10
14
  const command = argv[0];
11
- if (!command || command.startsWith('--') || command === '-h')
15
+ if (!command || command.startsWith('-'))
12
16
  return argv;
13
17
  return command === 'terminal' ? argv.slice(1) : null;
14
18
  }
15
- export function parseStandaloneOptions(argv, home = homedir(), cwd = process.cwd()) {
16
- const root = join(home, '.xingular-harness');
17
- const paths = {
18
- dataRoot: join(root, 'data'),
19
- stateDir: join(root, 'state')
20
- };
19
+ function resolveStandaloneOptions(argv, home = homedir(), cwd = process.cwd()) {
20
+ const overrides = {};
21
21
  const given = new Set();
22
+ let worktree;
23
+ let variant;
22
24
  for (let index = 0; index < argv.length; index += 1) {
23
25
  const argument = argv[index];
26
+ if (argument === '--worktree' || argument === '-w') {
27
+ const name = argv[index + 1];
28
+ if (name && !name.startsWith('-')) {
29
+ worktree = name;
30
+ index += 1;
31
+ }
32
+ else
33
+ worktree = true;
34
+ continue;
35
+ }
36
+ if (argument === '--variant') {
37
+ const scope = argv[index + 1];
38
+ if (!scope || scope.startsWith('-'))
39
+ throw new Error('--variant needs a variant scope.');
40
+ variant = scope;
41
+ index += 1;
42
+ continue;
43
+ }
24
44
  if (argument !== '--data' && argument !== '--state')
25
45
  throw new Error(`Unknown standalone option: ${argument}`);
26
46
  const value = argv[index + 1];
27
47
  if (!value || value.startsWith('--'))
28
48
  throw new Error(`${argument} needs a directory path.`);
29
- paths[argument === '--data' ? 'dataRoot' : 'stateDir'] = resolve(cwd, value);
49
+ if (argument === '--data')
50
+ overrides.dataRoot = resolve(cwd, value);
51
+ else
52
+ overrides.stateDir = resolve(cwd, value);
30
53
  given.add(argument);
31
54
  index += 1;
32
55
  }
@@ -35,7 +58,49 @@ export function parseStandaloneOptions(argv, home = homedir(), cwd = process.cwd
35
58
  if (!isAbsolute(home) && !(given.has('--data') && given.has('--state'))) {
36
59
  throw new Error(`The home folder "${home}" is not an absolute path, so the default data and state folders cannot be placed. Set HOME to your home folder, or pass --data and --state with absolute folders.`);
37
60
  }
38
- return paths;
61
+ // `npm run dev` passes these roots explicitly. Keep its profile and credentials separate from
62
+ // the installed interactive profile, even when that production profile selects a host store.
63
+ const devRoot = isAbsolute(home) ? join(home, '.xingular-harness-dev') : null;
64
+ const devData = devRoot ? join(devRoot, 'data') : null;
65
+ const devState = devRoot ? join(devRoot, 'state') : null;
66
+ const development = !!devRoot && (overrides.dataRoot === devData || overrides.stateDir === devState);
67
+ const resolvedProfile = isAbsolute(home)
68
+ ? resolveInteractiveProfile({
69
+ home,
70
+ ...(development ? {
71
+ configPath: join(devRoot, 'profile.json'),
72
+ legacyDefaults: {
73
+ dataRoot: devData,
74
+ stateDir: devState,
75
+ defaultVariantScope: 'default',
76
+ secretBackend: { kind: 'file', path: join(devState, 'secrets.json') }
77
+ }
78
+ } : {}),
79
+ overrides
80
+ })
81
+ : {
82
+ version: 1,
83
+ dataRoot: overrides.dataRoot,
84
+ stateDir: overrides.stateDir,
85
+ defaultVariantScope: 'default',
86
+ secretBackend: { kind: 'file', path: join(overrides.stateDir, 'secrets.json') }
87
+ };
88
+ // The standalone development launch has no host adapter and must not use the App's Keychain.
89
+ const profile = development
90
+ ? { ...resolvedProfile, secretBackend: { kind: 'file', path: join(resolvedProfile.stateDir, 'secrets.json') } }
91
+ : resolvedProfile;
92
+ return {
93
+ profile,
94
+ paths: {
95
+ dataRoot: profile.dataRoot,
96
+ stateDir: profile.stateDir,
97
+ ...(worktree !== undefined ? { worktree } : {}),
98
+ ...(variant !== undefined ? { variant } : {})
99
+ }
100
+ };
101
+ }
102
+ export function parseStandaloneOptions(argv, home = homedir(), cwd = process.cwd()) {
103
+ return resolveStandaloneOptions(argv, home, cwd).paths;
39
104
  }
40
105
  function processEnvironment(overrides) {
41
106
  const environment = { ...process.env };
@@ -99,14 +164,33 @@ function spawnFrontend(launch, cwd, spawn = nodeSpawn) {
99
164
  child.once('exit', (code, signal) => finish(() => resolveExit(exitCode(code, signal))));
100
165
  });
101
166
  }
167
+ /**
168
+ * `--worktree`: the named worktree of the repository in `cwd`, or a new managed one. Older managed
169
+ * worktrees beyond the kept number are pruned (unsaved work is kept as a snapshot).
170
+ */
171
+ async function enterWorktree(harness, cwd, wanted) {
172
+ const name = wanted === true ? undefined : wanted;
173
+ const existing = name ? (await harness.worktrees.list(cwd)).find((record) => record.name === name) : undefined;
174
+ if (existing)
175
+ return existing;
176
+ const created = await harness.worktrees.create({ repo: cwd, ...(name ? { name } : {}) });
177
+ process.stdout.write(`Working in worktree ${created.worktree.name} (${created.worktree.path}).\n`);
178
+ if (created.setup.state === 'untrusted')
179
+ process.stdout.write('This repository has a setup script you have not trusted; read .xharness/worktree-setup, then run: xagent worktree trust-setup\n');
180
+ if (created.setup.state === 'failed')
181
+ process.stdout.write(`The worktree setup script failed; see ${created.setup.log}.\n`);
182
+ await harness.worktrees.prune({ repo: cwd }).catch(() => undefined);
183
+ return created.worktree;
184
+ }
102
185
  export async function runStandaloneTerminal(argv, dependencies = {}) {
103
186
  if (!(dependencies.stdinIsTTY ?? process.stdin.isTTY) || !(dependencies.stdoutIsTTY ?? process.stdout.isTTY)) {
104
- throw new Error('The interactive Harness terminal needs a TTY. Run it from a terminal, or use `xharness serve` for a host process.');
187
+ throw new Error('The interactive Harness terminal needs a TTY. Run it from a terminal, or use `xagent serve` for a host process.');
105
188
  }
106
- const cwd = resolve(dependencies.cwd ?? process.cwd());
107
- const paths = parseStandaloneOptions(argv, dependencies.home, cwd);
189
+ let cwd = resolve(dependencies.cwd ?? process.cwd());
190
+ const { paths, profile } = resolveStandaloneOptions(argv, dependencies.home, cwd);
191
+ const secrets = await interactiveProfileSecretStore(profile, dependencies.hostSecretStore);
108
192
  const makeHarness = dependencies.createHarness ?? createHarness;
109
- const harness = makeHarness({ dataRoot: paths.dataRoot, stateDir: paths.stateDir, productName: 'Xingular Harness' });
193
+ const harness = makeHarness({ dataRoot: paths.dataRoot, stateDir: paths.stateDir, productName: DEFAULT_PRODUCT_NAME, secrets });
110
194
  const newSessionId = dependencies.createSessionId ?? randomUUID;
111
195
  let current = { sessionId: newSessionId(), accountId: null, nativeSessionId: null };
112
196
  // The frontend draws on this terminal, so the host's diagnostics go to a file the person can read instead.
@@ -121,19 +205,34 @@ export async function runStandaloneTerminal(argv, dependencies = {}) {
121
205
  });
122
206
  try {
123
207
  await harness.ready;
208
+ const variantScope = paths.variant ?? profile.defaultVariantScope;
209
+ if (variantScope === profile.defaultVariantScope && !variantStore.head(paths.dataRoot, variantScope)) {
210
+ variantStore.seed(paths.dataRoot, variantScope, seedVariant(paths.dataRoot, {}), 'interactive profile default');
211
+ }
124
212
  if (harness.accounts.overview().accounts.length === 0)
125
213
  harness.accounts.create('Default', 'subscription');
126
- const cwdHash = createHash('sha256').update(cwd).digest('hex');
127
- const sessionFolder = join(paths.dataRoot, 'sessions', 'terminal', cwdHash);
214
+ let worktreeId = null;
215
+ if (paths.worktree) {
216
+ const worktree = await enterWorktree(harness, cwd, paths.worktree);
217
+ cwd = worktree.path;
218
+ worktreeId = worktree.id;
219
+ }
128
220
  for (;;) {
129
- const launch = await harness.terminals.prepare({ ...current, cwd, sessionFolder });
221
+ const sessionFolder = join(paths.dataRoot, 'sessions', 'terminal', createHash('sha256').update(cwd).digest('hex'));
222
+ const launch = await harness.terminals.prepare({ ...current, cwd, sessionFolder, variant: { scope: variantScope }, ...(worktreeId ? { run: { worktreeId } } : {}) });
130
223
  const code = await spawnFrontend(launch, cwd, dependencies.spawn);
131
- // `/accounts` asks for a switch and ends the frontend. The conversation resumes on the chosen account.
224
+ // `/accounts` and `/worktree` ask for a switch and end the frontend. An account switch resumes
225
+ // the conversation; a folder switch starts a new one there.
132
226
  const next = harness.terminals.takeRelaunch(current.sessionId);
133
227
  if (!next)
134
228
  return code;
135
- const label = harness.accounts.find(next.accountId).label;
136
- process.stdout.write(`Switching this session to account ${label}.\n`);
229
+ if (next.cwd) {
230
+ process.stdout.write(`Opening ${next.cwd}.\n`);
231
+ cwd = next.cwd;
232
+ worktreeId = next.worktreeId ?? null;
233
+ }
234
+ else
235
+ process.stdout.write(`Switching this session to account ${harness.accounts.find(next.accountId).label}.\n`);
137
236
  await harness.terminals.dispose(current.sessionId);
138
237
  current = { sessionId: newSessionId(), accountId: next.accountId, nativeSessionId: next.nativeSessionId };
139
238
  }
@@ -0,0 +1,47 @@
1
+ import { type RunEvent, type RunStatus, type UsagePayload } from "../sessions/contracts.js";
2
+ import type { Effort } from "../sessions/runner.js";
3
+ /** The agent profile a child started from, as the roster shows it (PROP-0029). */
4
+ export interface TerminalSubagentProfile {
5
+ name: string;
6
+ color: string;
7
+ }
8
+ export interface TerminalSubagentRun {
9
+ id: string;
10
+ parentRunId: string | null;
11
+ relation: 'subagent';
12
+ /** The short name the parent gave the child (PROP-0030). */
13
+ title: string;
14
+ goal: string | null;
15
+ status: RunStatus;
16
+ startedAt: string;
17
+ endedAt: string | null;
18
+ profile?: TerminalSubagentProfile | null;
19
+ /** The pinned account's display label; subagents never switch accounts. */
20
+ accountLabel?: string | null;
21
+ /** Effective launch selection, superseded by provider-reported usage when available. */
22
+ model?: string | null;
23
+ effort?: Effort | null;
24
+ }
25
+ export type TerminalSubagentUsage = Partial<Pick<UsagePayload, 'provider' | 'model' | 'inputTokens' | 'outputTokens' | 'cacheReadTokens' | 'cacheWriteTokens' | 'reasoningTokens' | 'costUsd' | 'costSource' | 'requests' | 'contextTokens' | 'contextWindow'>>;
26
+ export interface TerminalSubagentActivity extends TerminalSubagentRun {
27
+ activity: string;
28
+ /** Cumulative run usage only; provider reasoning summaries and request details stay private. */
29
+ usage: TerminalSubagentUsage | null;
30
+ /** How far the child's own checklist is: counts only, never the items. */
31
+ checklist: {
32
+ done: number;
33
+ total: number;
34
+ } | null;
35
+ }
36
+ export declare const ACTIVE_SUBAGENT_STATUSES: Set<"queued" | "running" | "waiting_for_approval" | "waiting_for_input" | "interrupted" | "completed" | "failed">;
37
+ export declare function terminalSubagentDuration(activity: TerminalSubagentRun, now?: number): string;
38
+ export declare function terminalSubagentTone(status: RunStatus): 'success' | 'warning' | 'error' | 'muted';
39
+ /** Volatile, read-only activity projection for the latest terminal parent run. */
40
+ export declare class SubagentMonitor {
41
+ private parentRunId;
42
+ private readonly activities;
43
+ begin(parentRunId: string): void;
44
+ observe(parentRunId: string, run: TerminalSubagentRun, event: RunEvent): void;
45
+ snapshot(parentRunId: string): TerminalSubagentActivity[];
46
+ clear(parentRunId?: string): void;
47
+ }
@@ -0,0 +1,152 @@
1
+ import { usagePayloadSchema } from "../sessions/contracts.js";
2
+ export const ACTIVE_SUBAGENT_STATUSES = new Set(['queued', 'running', 'waiting_for_approval', 'waiting_for_input']);
3
+ export function terminalSubagentDuration(activity, now = Date.now()) {
4
+ const start = Date.parse(activity.startedAt);
5
+ const end = activity.endedAt ? Date.parse(activity.endedAt) : now;
6
+ if (!Number.isFinite(start) || !Number.isFinite(end))
7
+ return '—';
8
+ const seconds = Math.max(0, Math.floor((end - start) / 1000));
9
+ if (seconds < 60)
10
+ return `${seconds}s`;
11
+ const minutes = Math.floor(seconds / 60);
12
+ if (minutes < 60)
13
+ return `${minutes}:${String(seconds % 60).padStart(2, '0')}`;
14
+ return `${Math.floor(minutes / 60)}h${String(minutes % 60).padStart(2, '0')}m`;
15
+ }
16
+ export function terminalSubagentTone(status) {
17
+ if (status === 'completed')
18
+ return 'success';
19
+ if (status === 'failed')
20
+ return 'error';
21
+ if (ACTIVE_SUBAGENT_STATUSES.has(status))
22
+ return 'warning';
23
+ return 'muted';
24
+ }
25
+ function statusActivity(status) {
26
+ switch (status) {
27
+ case 'queued': return 'Queued';
28
+ case 'waiting_for_approval': return 'Waiting for approval';
29
+ case 'waiting_for_input': return 'Waiting for input';
30
+ case 'completed': return 'Completed';
31
+ case 'failed': return 'Failed';
32
+ case 'interrupted': return 'Interrupted';
33
+ case 'running': return 'Working';
34
+ }
35
+ }
36
+ function payloadOf(event) {
37
+ return event.payload && typeof event.payload === 'object' ? event.payload : {};
38
+ }
39
+ function stringOf(value) {
40
+ return typeof value === 'string' && value.trim() ? value.trim() : undefined;
41
+ }
42
+ function latestTool(tools) {
43
+ return [...tools.values()].sort((left, right) => right.sequence - left.sequence)[0]?.text;
44
+ }
45
+ /** Volatile, read-only activity projection for the latest terminal parent run. */
46
+ export class SubagentMonitor {
47
+ parentRunId = null;
48
+ activities = new Map();
49
+ begin(parentRunId) {
50
+ this.parentRunId = parentRunId;
51
+ this.activities.clear();
52
+ }
53
+ observe(parentRunId, run, event) {
54
+ if (this.parentRunId !== parentRunId || run.relation !== 'subagent')
55
+ return;
56
+ const row = this.activities.get(run.id) ?? {
57
+ id: run.id,
58
+ parentRunId: run.parentRunId,
59
+ relation: run.relation,
60
+ title: run.title,
61
+ goal: run.goal,
62
+ status: run.status,
63
+ startedAt: run.startedAt,
64
+ endedAt: run.endedAt,
65
+ activity: statusActivity(run.status),
66
+ checklist: null,
67
+ profile: run.profile ?? null,
68
+ accountLabel: run.accountLabel ?? null,
69
+ model: run.model ?? null,
70
+ effort: run.effort ?? null,
71
+ usage: null,
72
+ tools: new Map(),
73
+ lastTool: null
74
+ };
75
+ row.parentRunId = run.parentRunId;
76
+ if (run.profile !== undefined)
77
+ row.profile = run.profile;
78
+ if (run.accountLabel !== undefined)
79
+ row.accountLabel = run.accountLabel;
80
+ if (run.model !== undefined && !row.usage?.model)
81
+ row.model = run.model;
82
+ if (run.effort !== undefined)
83
+ row.effort = run.effort;
84
+ row.title = run.title;
85
+ row.goal = run.goal;
86
+ row.status = run.status;
87
+ row.startedAt = run.startedAt;
88
+ row.endedAt = run.endedAt;
89
+ const payload = payloadOf(event);
90
+ if (event.type === 'tool.started') {
91
+ const toolCallId = stringOf(payload.toolCallId);
92
+ const name = stringOf(payload.name) ?? 'Tool';
93
+ if (toolCallId)
94
+ row.tools.set(toolCallId, { sequence: event.sequence, text: name });
95
+ }
96
+ else if (event.type === 'tool.completed') {
97
+ const toolCallId = stringOf(payload.toolCallId);
98
+ const tool = toolCallId ? row.tools.get(toolCallId) : undefined;
99
+ if (tool && (!row.lastTool || tool.sequence >= row.lastTool.sequence))
100
+ row.lastTool = tool;
101
+ if (toolCallId)
102
+ row.tools.delete(toolCallId);
103
+ }
104
+ else if (event.type === 'message.delta') {
105
+ row.lastTool = null;
106
+ row.activity = 'Responding';
107
+ }
108
+ else if (event.type === 'usage.updated') {
109
+ const parsed = usagePayloadSchema.safeParse(payload);
110
+ if (parsed.success) {
111
+ const usage = parsed.data;
112
+ row.usage = {
113
+ ...(usage.provider === undefined ? {} : { provider: usage.provider }),
114
+ ...(usage.model === undefined ? {} : { model: usage.model }),
115
+ ...(usage.inputTokens === undefined ? {} : { inputTokens: usage.inputTokens }),
116
+ ...(usage.outputTokens === undefined ? {} : { outputTokens: usage.outputTokens }),
117
+ ...(usage.cacheReadTokens === undefined ? {} : { cacheReadTokens: usage.cacheReadTokens }),
118
+ ...(usage.cacheWriteTokens === undefined ? {} : { cacheWriteTokens: usage.cacheWriteTokens }),
119
+ ...(usage.reasoningTokens === undefined ? {} : { reasoningTokens: usage.reasoningTokens }),
120
+ ...(usage.costUsd === undefined ? {} : { costUsd: usage.costUsd }),
121
+ ...(usage.costSource === undefined ? {} : { costSource: usage.costSource }),
122
+ ...(usage.requests === undefined ? {} : { requests: usage.requests }),
123
+ ...(usage.contextTokens === undefined ? {} : { contextTokens: usage.contextTokens }),
124
+ ...(usage.contextWindow === undefined ? {} : { contextWindow: usage.contextWindow })
125
+ };
126
+ }
127
+ }
128
+ else if (event.type === 'checklist.updated') {
129
+ const items = Array.isArray(payload.items) ? payload.items : [];
130
+ row.checklist = items.length ? { done: items.filter(item => item?.status === 'completed').length, total: items.length } : null;
131
+ }
132
+ if (run.status !== 'running')
133
+ row.tools.clear();
134
+ row.activity = run.status === 'running'
135
+ ? latestTool(row.tools) ?? row.lastTool?.text ?? (event.type === 'message.delta' ? 'Responding' : 'Working')
136
+ : statusActivity(run.status);
137
+ this.activities.set(run.id, row);
138
+ }
139
+ snapshot(parentRunId) {
140
+ if (this.parentRunId !== parentRunId)
141
+ return [];
142
+ return [...this.activities.values()]
143
+ .sort((left, right) => left.startedAt.localeCompare(right.startedAt) || left.id.localeCompare(right.id))
144
+ .map(({ tools: _tools, lastTool: _lastTool, ...activity }) => activity);
145
+ }
146
+ clear(parentRunId) {
147
+ if (parentRunId && this.parentRunId !== parentRunId)
148
+ return;
149
+ this.parentRunId = null;
150
+ this.activities.clear();
151
+ }
152
+ }
@@ -1,5 +1,6 @@
1
1
  import type { CapabilitySet } from "../capabilities/types.js";
2
2
  import type { Subagents } from "../sessions/subagentService.js";
3
+ import type { SideQuestions } from "../sessions/sideQuestions.js";
3
4
  import { type SubagentOptions } from "../sessions/subagents.js";
4
5
  import type { Accounts } from "../accounts/accounts.js";
5
6
  import type { Approvals } from "../sessions/approvals.js";
@@ -18,11 +19,16 @@ import type { RunRecord } from "../sessions/contracts.js";
18
19
  import type { ToolPolicy } from "../sessions/policy.js";
19
20
  import type { RunRegistry } from "../sessions/registry.js";
20
21
  import type { World } from "../world/world.js";
22
+ import type { Worktrees } from "../worktrees/service.js";
23
+ import type { AnnotationCapture } from "../annotations/capture.js";
24
+ import type { NoteDeliveries } from "../annotations/delivery.js";
25
+ import type { Usage } from "../usage/service.js";
26
+ import type { UsageLimits } from "../usage/limits/service.js";
21
27
  /** The files a terminal session needs on disk, outside this process. */
22
28
  export interface TerminalAssets {
23
29
  /** The Node binary that runs the commands. */
24
30
  node: string;
25
- /** The built `xharness` command (`dist/cli.js`). */
31
+ /** The built `xagent` command (`dist/cli.js`). */
26
32
  cli: string;
27
33
  /** The built Pi extension (`dist/terminal-pi.js`). */
28
34
  piExtension: string;
@@ -52,6 +58,15 @@ export interface TerminalPrepareInput {
52
58
  /** Fields copied onto each run this session records. */
53
59
  run?: Partial<Pick<RunRecord, 'mode' | 'worktreeId'>>;
54
60
  }
61
+ /** What a session asked to restart as: another account, or another folder (a worktree or the main checkout). */
62
+ export interface TerminalRelaunch {
63
+ accountId: string;
64
+ nativeSessionId: string | null;
65
+ /** Restart in this folder, as a new conversation there. */
66
+ cwd?: string;
67
+ /** The managed worktree the new folder belongs to; null for the main checkout. */
68
+ worktreeId?: string | null;
69
+ }
55
70
  export interface TerminalLaunch {
56
71
  program: string;
57
72
  args: string[];
@@ -65,6 +80,8 @@ export interface TerminalsOptions {
65
80
  /** Which plugin code in variants a person trusted. */
66
81
  trust?: VariantTrust | null;
67
82
  subagents?: Subagents;
83
+ /** Shared tool-free side-question runs. */
84
+ sideQuestions?: SideQuestions;
68
85
  resolveCapabilities?: (caller: CallerContext, tools: readonly string[], cwd: string) => Promise<CapabilitySet>;
69
86
  env: HarnessEnv;
70
87
  stateDir: string;
@@ -82,6 +99,16 @@ export interface TerminalsOptions {
82
99
  assets?: TerminalAssets;
83
100
  /** Web, browser and computer tools, offered when their plugins are on. */
84
101
  world?: World;
102
+ /** Managed worktrees: a session naming one works in it and holds it while it lives. */
103
+ worktrees?: Worktrees;
104
+ /** The visible browser a person captures page notes in. */
105
+ noteCapture?: AnnotationCapture;
106
+ /** Page notes on their way to a session (PROP-0018). */
107
+ pageNotes?: NoteDeliveries;
108
+ /** Usage analytics over the derived ledger (`/usage:analysis`). */
109
+ usage?: Usage;
110
+ /** Provider plan windows, balances and rate limits (`/usage:limit`). */
111
+ usageLimits?: UsageLimits;
85
112
  }
86
113
  /** What `/plugins` in a terminal can do. Each takes the session's folder, account and project. */
87
114
  export interface PluginControl {
@@ -98,6 +125,12 @@ export interface PluginControl {
98
125
  pluginId: string;
99
126
  settings: Record<string, unknown>;
100
127
  }): Promise<Plugin[]>;
128
+ install?(params: PluginScope & {
129
+ source: string;
130
+ }): Promise<Plugin[]>;
131
+ remove?(params: PluginScope & {
132
+ pluginId: string;
133
+ }): Promise<Plugin[]>;
101
134
  }
102
135
  export declare class Terminals {
103
136
  private readonly options;
@@ -110,15 +143,27 @@ export declare class Terminals {
110
143
  private readonly worldReadOnly;
111
144
  private readonly socket;
112
145
  private readonly assets;
113
- /** A session's `/accounts` switch, taken once its Pi process has ended. */
146
+ /** A session's `/accounts` or `/worktree` switch, taken once its Pi process has ended. */
114
147
  private readonly relaunches;
148
+ /** The managed worktree each live session holds. */
149
+ private readonly worktreeLeases;
150
+ /** Each child's profile name and colour, looked up once per child run. */
151
+ private readonly childProfiles;
152
+ private subagentProfile;
115
153
  constructor(options: TerminalsOptions);
116
154
  /** The commands a terminal session finds on PATH. Rewritten only when they change. */
117
155
  private ensureCommands;
118
- /** The broker's tools, then the world tools whose plugins are on for this session. */
156
+ /**
157
+ * The harness's own History, Wiki and skill tools, then the broker's, then the world tools whose
158
+ * plugins are on for this session: the same tools a structured session has (INV-PAR-1).
159
+ */
119
160
  private tools;
161
+ private readonly ownNames;
162
+ private ownTools;
120
163
  /** The world tools a new session will have, named in its instructions. */
121
164
  private worldToolNames;
165
+ /** The harness's own History, Wiki and skill tools a new session will have. */
166
+ private ownToolNames;
122
167
  /** Whether a world tool's plugin is switched on for a session's folder, account and project. */
123
168
  private worldOn;
124
169
  private appsCall;
@@ -133,20 +178,28 @@ export declare class Terminals {
133
178
  * or removing an account is a person's choice, never the model's shell command.
134
179
  */
135
180
  private accountsCall;
181
+ /** `/agents`: the agent profiles this session's folder can use (PROP-0029). */
182
+ private agentsCall;
183
+ /** `/worktree`: the managed worktrees of the repository this session works in. */
184
+ private worktreesCall;
185
+ /** `/usage:analysis` and `/usage:limit`: usage for this session's own account, project or session. */
186
+ private usageCall;
187
+ /** `/annotate:notes` and `/annotate:`: Web annotations and their visible capture browser. */
188
+ private annotationsCall;
136
189
  /** The account a session asked to switch to. Taken once, after its Pi process has ended and before `dispose`. */
137
- takeRelaunch(sessionId: string): {
138
- accountId: string;
139
- nativeSessionId: string | null;
140
- } | null;
190
+ takeRelaunch(sessionId: string): TerminalRelaunch | null;
141
191
  private live;
142
192
  private historyDir;
143
193
  private runRecord;
144
194
  /** The run a native turn reports into: the one reserved by `send`, or a new one for what the person typed. */
145
195
  private begin;
146
196
  private decide;
197
+ private workspaceEscape;
198
+ private workspaceBoundaryBypass;
147
199
  private subagentsCall;
148
200
  private componentsCall;
149
201
  private trajectoryCall;
202
+ private sideQuestionCall;
150
203
  /** The only terminal frontend: the Bun-run OpenTUI application. */
151
204
  private frontendCommand;
152
205
  /**