@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
@@ -0,0 +1,11 @@
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ import { type TodoItem } from "./contracts.js";
3
+ export declare const COMPACTION_CHECKPOINT_EXTENSION = "compaction-checkpoint";
4
+ export interface CompactionCheckpointOptions {
5
+ /** A stopped run's persisted todo, when the active run is a continuation. */
6
+ initialTodo?: readonly TodoItem[];
7
+ /** The current dynamic plan instructions, if this request is in plan mode. */
8
+ planInstructions?: () => string | null;
9
+ }
10
+ /** Adds only the active run's explicit state to requests made after a compaction. */
11
+ export declare function compactionCheckpoint(options?: CompactionCheckpointOptions): (pi: ExtensionAPI) => void;
@@ -0,0 +1,79 @@
1
+ import { renderCompactionCheckpoint } from "../prompt/compile.js";
2
+ import { TODO_WRITE } from "../tools/todo.js";
3
+ import { todoItemSchema, MAX_TODO_ITEMS } from "./contracts.js";
4
+ export const COMPACTION_CHECKPOINT_EXTENSION = 'compaction-checkpoint';
5
+ function validatedTodo(value) {
6
+ if (!Array.isArray(value) || value.length > MAX_TODO_ITEMS)
7
+ return null;
8
+ const items = [];
9
+ for (const valueItem of value) {
10
+ const item = valueItem;
11
+ const parsed = todoItemSchema.safeParse({
12
+ text: typeof item?.text === 'string' ? item.text.trim() : item?.text,
13
+ status: item?.status
14
+ });
15
+ if (!parsed.success)
16
+ return null;
17
+ items.push(parsed.data);
18
+ }
19
+ return items;
20
+ }
21
+ /** Adds only the active run's explicit state to requests made after a compaction. */
22
+ export function compactionCheckpoint(options = {}) {
23
+ return (pi) => {
24
+ let goal = '';
25
+ let todo = validatedTodo(options.initialTodo ?? []) ?? [];
26
+ let lastCompactionKey = null;
27
+ let compacted = false;
28
+ const reset = () => {
29
+ goal = '';
30
+ todo = validatedTodo(options.initialTodo ?? []) ?? [];
31
+ lastCompactionKey = null;
32
+ compacted = false;
33
+ };
34
+ pi.on('before_agent_start', (event) => {
35
+ if (event.messageType !== 'user')
36
+ return;
37
+ goal = event.prompt;
38
+ todo = validatedTodo(options.initialTodo ?? []) ?? [];
39
+ lastCompactionKey = null;
40
+ compacted = false;
41
+ });
42
+ pi.on('tool_result', (event) => {
43
+ if (event.toolName !== TODO_WRITE || event.isError)
44
+ return;
45
+ const items = validatedTodo(event.input.items);
46
+ if (items)
47
+ todo = items;
48
+ });
49
+ pi.on('context', (event) => {
50
+ const summary = event.messages.findLast((message) => message.role === 'compactionSummary');
51
+ const compactionKey = summary ? `${summary.timestamp}:${summary.tokensBefore}` : null;
52
+ const planInstructions = options.planInstructions?.() ?? null;
53
+ if (compactionKey && compactionKey !== lastCompactionKey) {
54
+ lastCompactionKey = compactionKey;
55
+ compacted = true;
56
+ }
57
+ else if (!compactionKey) {
58
+ lastCompactionKey = null;
59
+ compacted = false;
60
+ }
61
+ if (!compacted)
62
+ return;
63
+ const content = renderCompactionCheckpoint({ goal, todo, planInstructions });
64
+ if (!content)
65
+ return;
66
+ return {
67
+ messages: [...event.messages, {
68
+ role: 'custom',
69
+ customType: COMPACTION_CHECKPOINT_EXTENSION,
70
+ content,
71
+ display: false,
72
+ timestamp: Date.now()
73
+ }]
74
+ };
75
+ });
76
+ pi.on('agent_settled', reset);
77
+ pi.on('session_tree', reset);
78
+ };
79
+ }
@@ -1,6 +1,7 @@
1
1
  import type { CapabilitySet } from "../capabilities/types.js";
2
2
  import type { HostSection } from "../prompt/compile.js";
3
- import { type ChecklistItem } from "./contracts.js";
3
+ import type { Checkpoint } from "./contracts.js";
4
+ import { type TodoItem } from "./contracts.js";
4
5
  import { type PendingDecision } from "./runStore.js";
5
6
  export declare const CONTINUATION_SECTION_ID = "continuation";
6
7
  /** Right after the plan section, before the variant's own sections. */
@@ -27,7 +28,11 @@ export interface Continuation {
27
28
  capabilities: CapabilitySet | null;
28
29
  stoppedAt: string | null;
29
30
  terminalReason: string | null;
30
- checklist: ChecklistItem[];
31
+ todo: TodoItem[];
32
+ /** @deprecated Use `todo`; kept for one release so hosts can migrate. */
33
+ checklist: TodoItem[];
34
+ /** The last work-slice handoff, when the run wrote one (PROP-0041). */
35
+ checkpoint: Checkpoint | null;
31
36
  pending: PendingDecision[];
32
37
  /** The last tool the run started, and whether it finished. */
33
38
  lastTool: {
@@ -2,7 +2,8 @@
2
2
  // own (INV-RUN-4); it says whether a run can be continued and, when the application starts a new
3
3
  // run with `continueFrom`, tells the model where the earlier one stopped.
4
4
  import { loadRun as loadCapabilities } from "../capabilities/runSnapshot.js";
5
- import { checklistOf, describeChecklist } from "../tools/checklist.js";
5
+ import { todoOf, describeTodo } from "../tools/todo.js";
6
+ import { checkpointOf, describeCheckpoint } from "../tools/checkpoint.js";
6
7
  import { isActiveStatus } from "./contracts.js";
7
8
  import { findHistory } from "./history.js";
8
9
  import { findRun, pendingDecisions, readEvents, recordedSubagents } from "./runStore.js";
@@ -17,7 +18,7 @@ const CONTINUATION_BUDGET = 2000;
17
18
  export function continuationOf(root, runId, sessionDir) {
18
19
  const record = findRun(root, runId);
19
20
  if (!record) {
20
- return { runId, sessionId: '', status: 'missing', resumable: false, reason: 'not_found', resume: null, accountId: null, variant: null, capabilities: null, stoppedAt: null, terminalReason: null, checklist: [], pending: [], lastTool: null, unfinishedSubagents: [] };
21
+ return { runId, sessionId: '', status: 'missing', resumable: false, reason: 'not_found', resume: null, accountId: null, variant: null, capabilities: null, stoppedAt: null, terminalReason: null, todo: [], checklist: [], checkpoint: null, pending: [], lastTool: null, unfinishedSubagents: [] };
21
22
  }
22
23
  const events = readEvents(root, runId);
23
24
  const started = events.filter((event) => event.type === 'tool.started').at(-1);
@@ -45,7 +46,9 @@ export function continuationOf(root, runId, sessionDir) {
45
46
  capabilities,
46
47
  stoppedAt: record.endedAt,
47
48
  terminalReason: record.terminalReason,
48
- checklist: checklistOf(events),
49
+ checklist: todoOf(events),
50
+ todo: todoOf(events),
51
+ checkpoint: checkpointOf(events),
49
52
  pending: pendingDecisions(events),
50
53
  lastTool,
51
54
  unfinishedSubagents: recordedSubagents(root, runId).filter((id) => {
@@ -69,12 +72,14 @@ export function continuationBody(continuation) {
69
72
  ];
70
73
  if (continuation.lastTool)
71
74
  lines.push(continuation.lastTool.finished ? `Its last tool call, ${continuation.lastTool.name}, finished.` : `Its last tool call, ${continuation.lastTool.name}, did not finish; its effect is unknown.`);
72
- if (continuation.checklist.length)
73
- lines.push('', 'Its checklist when it stopped:', describeChecklist(continuation.checklist));
75
+ if (continuation.checkpoint)
76
+ lines.push('', 'The handoff it wrote when it stopped:', describeCheckpoint(continuation.checkpoint));
77
+ if (continuation.todo.length)
78
+ lines.push('', 'Its todo list when it stopped:', describeTodo(continuation.todo));
74
79
  if (continuation.pending.length)
75
80
  lines.push('', 'Unanswered when it stopped (ask again if still needed; never assume an answer):', ...continuation.pending.map(describePending));
76
81
  if (continuation.unfinishedSubagents.length)
77
- lines.push('', `Subagents that did not finish: ${continuation.unfinishedSubagents.join(', ')}. Start them again if their work is still needed.`);
82
+ lines.push('', `Subagents that did not finish: ${continuation.unfinishedSubagents.join(', ')}. Their conversations are saved: continue one with spawn_subagent { "continue": "<run ID>" } if its work is still needed, instead of starting it again from scratch.`);
78
83
  return lines.join('\n');
79
84
  }
80
85
  /** The dynamic section for a continuation; on a later run, the empty slot withdraws it. */
@@ -30,7 +30,10 @@ export declare const runEventTypeSchema: z.ZodEnum<{
30
30
  "extension.notice": "extension.notice";
31
31
  "reaction.added": "reaction.added";
32
32
  "agent.message": "agent.message";
33
+ "todo.updated": "todo.updated";
33
34
  "checklist.updated": "checklist.updated";
35
+ checkpoint: "checkpoint";
36
+ heartbeat: "heartbeat";
34
37
  "artifact.added": "artifact.added";
35
38
  "file.changed": "file.changed";
36
39
  "usage.updated": "usage.updated";
@@ -65,8 +68,8 @@ export declare const questionOptionSchema: z.ZodObject<{
65
68
  sketch: z.ZodOptional<z.ZodString>;
66
69
  }, z.core.$strip>;
67
70
  export type QuestionOption = z.infer<typeof questionOptionSchema>;
68
- /** One line of the run's checklist. The list has no ids: every update replaces all of it. */
69
- export declare const checklistItemSchema: z.ZodObject<{
71
+ /** One line of the run's todo list. The list has no ids: every update replaces all of it. */
72
+ export declare const todoItemSchema: z.ZodObject<{
70
73
  text: z.ZodString;
71
74
  status: z.ZodEnum<{
72
75
  completed: "completed";
@@ -74,8 +77,75 @@ export declare const checklistItemSchema: z.ZodObject<{
74
77
  in_progress: "in_progress";
75
78
  }>;
76
79
  }, z.core.$strict>;
77
- export type ChecklistItem = z.infer<typeof checklistItemSchema>;
78
- export declare const MAX_CHECKLIST_ITEMS = 50;
80
+ export type TodoItem = z.infer<typeof todoItemSchema>;
81
+ export declare const MAX_TODO_ITEMS = 50;
82
+ export declare const MAX_CHECKPOINT_SUMMARY = 1200;
83
+ export declare const MAX_CHECKPOINT_DONE = 20;
84
+ export declare const MAX_CHECKPOINT_EVIDENCE = 5;
85
+ export declare const MAX_CHECKPOINT_FILES = 20;
86
+ export declare const MAX_CHECKPOINT_CHECKS = 8;
87
+ export declare const MAX_CHECKPOINT_DECISIONS = 8;
88
+ /**
89
+ * The handoff a reply writes when it reaches its work-slice budget. The harness validates and
90
+ * records it; the next slice is told where this one stopped from it (PROP-0041).
91
+ */
92
+ export declare const checkpointItemSchema: z.ZodObject<{
93
+ item: z.ZodString;
94
+ evidence: z.ZodDefault<z.ZodArray<z.ZodString>>;
95
+ }, z.core.$strict>;
96
+ export declare const checkpointFileSchema: z.ZodObject<{
97
+ path: z.ZodString;
98
+ why: z.ZodDefault<z.ZodString>;
99
+ }, z.core.$strict>;
100
+ export declare const checkpointCheckSchema: z.ZodObject<{
101
+ command: z.ZodString;
102
+ ok: z.ZodBoolean;
103
+ detail: z.ZodOptional<z.ZodString>;
104
+ }, z.core.$strict>;
105
+ export declare const checkpointDecisionSchema: z.ZodObject<{
106
+ what: z.ZodString;
107
+ why: z.ZodDefault<z.ZodString>;
108
+ }, z.core.$strict>;
109
+ export declare const checkpointReasonSchema: z.ZodEnum<{
110
+ budget: "budget";
111
+ stuck: "stuck";
112
+ "compaction-thrash": "compaction-thrash";
113
+ requested: "requested";
114
+ }>;
115
+ declare const checkpointPayload: z.ZodObject<{
116
+ summary: z.ZodString;
117
+ done: z.ZodDefault<z.ZodArray<z.ZodObject<{
118
+ item: z.ZodString;
119
+ evidence: z.ZodDefault<z.ZodArray<z.ZodString>>;
120
+ }, z.core.$strict>>>;
121
+ next: z.ZodDefault<z.ZodString>;
122
+ blocked: z.ZodOptional<z.ZodString>;
123
+ files: z.ZodDefault<z.ZodArray<z.ZodObject<{
124
+ path: z.ZodString;
125
+ why: z.ZodDefault<z.ZodString>;
126
+ }, z.core.$strict>>>;
127
+ checks: z.ZodDefault<z.ZodArray<z.ZodObject<{
128
+ command: z.ZodString;
129
+ ok: z.ZodBoolean;
130
+ detail: z.ZodOptional<z.ZodString>;
131
+ }, z.core.$strict>>>;
132
+ decisions: z.ZodDefault<z.ZodArray<z.ZodObject<{
133
+ what: z.ZodString;
134
+ why: z.ZodDefault<z.ZodString>;
135
+ }, z.core.$strict>>>;
136
+ slice: z.ZodNumber;
137
+ reason: z.ZodEnum<{
138
+ budget: "budget";
139
+ stuck: "stuck";
140
+ "compaction-thrash": "compaction-thrash";
141
+ requested: "requested";
142
+ }>;
143
+ }, z.core.$strict>;
144
+ export type Checkpoint = z.infer<typeof checkpointPayload>;
145
+ export type CheckpointItem = z.infer<typeof checkpointItemSchema>;
146
+ export type CheckpointFile = z.infer<typeof checkpointFileSchema>;
147
+ export type CheckpointCheck = z.infer<typeof checkpointCheckSchema>;
148
+ export type CheckpointDecision = z.infer<typeof checkpointDecisionSchema>;
79
149
  /** Where a cost figure comes from: Pi reported it, or the tokens were priced at list rates. */
80
150
  export declare const costSourceSchema: z.ZodEnum<{
81
151
  harness: "harness";
@@ -157,9 +227,37 @@ export declare const accountLimitSchema: z.ZodObject<{
157
227
  id: z.ZodString;
158
228
  label: z.ZodString;
159
229
  usedPercent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
230
+ remainingPercent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
160
231
  resetsAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
161
232
  windowMinutes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
162
233
  status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
234
+ provider: z.ZodOptional<z.ZodNullable<z.ZodString>>;
235
+ kind: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
236
+ error: "error";
237
+ window: "window";
238
+ rate: "rate";
239
+ credit: "credit";
240
+ configured: "configured";
241
+ }>>>;
242
+ unit: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
243
+ requests: "requests";
244
+ percent: "percent";
245
+ tokens: "tokens";
246
+ usd: "usd";
247
+ currency: "currency";
248
+ count: "count";
249
+ }>>>;
250
+ used: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
251
+ limit: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
252
+ remaining: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
253
+ source: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
254
+ error: "error";
255
+ headers: "headers";
256
+ estimate: "estimate";
257
+ provider: "provider";
258
+ }>>>;
259
+ observedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
260
+ detail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
163
261
  }, z.core.$strip>;
164
262
  export type AccountLimit = z.infer<typeof accountLimitSchema>;
165
263
  /** Payload schema per discriminant. */
@@ -335,6 +433,16 @@ export declare const runEventPayloadSchemas: {
335
433
  agentName: z.ZodString;
336
434
  text: z.ZodString;
337
435
  }, z.core.$strip>;
436
+ 'todo.updated': z.ZodObject<{
437
+ items: z.ZodArray<z.ZodObject<{
438
+ text: z.ZodString;
439
+ status: z.ZodEnum<{
440
+ completed: "completed";
441
+ pending: "pending";
442
+ in_progress: "in_progress";
443
+ }>;
444
+ }, z.core.$strict>>;
445
+ }, z.core.$strict>;
338
446
  'checklist.updated': z.ZodObject<{
339
447
  items: z.ZodArray<z.ZodObject<{
340
448
  text: z.ZodString;
@@ -345,6 +453,43 @@ export declare const runEventPayloadSchemas: {
345
453
  }>;
346
454
  }, z.core.$strict>>;
347
455
  }, z.core.$strict>;
456
+ checkpoint: z.ZodObject<{
457
+ summary: z.ZodString;
458
+ done: z.ZodDefault<z.ZodArray<z.ZodObject<{
459
+ item: z.ZodString;
460
+ evidence: z.ZodDefault<z.ZodArray<z.ZodString>>;
461
+ }, z.core.$strict>>>;
462
+ next: z.ZodDefault<z.ZodString>;
463
+ blocked: z.ZodOptional<z.ZodString>;
464
+ files: z.ZodDefault<z.ZodArray<z.ZodObject<{
465
+ path: z.ZodString;
466
+ why: z.ZodDefault<z.ZodString>;
467
+ }, z.core.$strict>>>;
468
+ checks: z.ZodDefault<z.ZodArray<z.ZodObject<{
469
+ command: z.ZodString;
470
+ ok: z.ZodBoolean;
471
+ detail: z.ZodOptional<z.ZodString>;
472
+ }, z.core.$strict>>>;
473
+ decisions: z.ZodDefault<z.ZodArray<z.ZodObject<{
474
+ what: z.ZodString;
475
+ why: z.ZodDefault<z.ZodString>;
476
+ }, z.core.$strict>>>;
477
+ slice: z.ZodNumber;
478
+ reason: z.ZodEnum<{
479
+ budget: "budget";
480
+ stuck: "stuck";
481
+ "compaction-thrash": "compaction-thrash";
482
+ requested: "requested";
483
+ }>;
484
+ }, z.core.$strict>;
485
+ heartbeat: z.ZodObject<{
486
+ steps: z.ZodNumber;
487
+ elapsedMs: z.ZodNumber;
488
+ lastTool: z.ZodNullable<z.ZodString>;
489
+ compactions: z.ZodNumber;
490
+ slice: z.ZodNumber;
491
+ maxToolCalls: z.ZodNumber;
492
+ }, z.core.$strict>;
348
493
  'artifact.added': z.ZodObject<{
349
494
  artifactId: z.ZodString;
350
495
  name: z.ZodString;
@@ -412,9 +557,37 @@ export declare const runEventPayloadSchemas: {
412
557
  id: z.ZodString;
413
558
  label: z.ZodString;
414
559
  usedPercent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
560
+ remainingPercent: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
415
561
  resetsAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
416
562
  windowMinutes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
417
563
  status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
564
+ provider: z.ZodOptional<z.ZodNullable<z.ZodString>>;
565
+ kind: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
566
+ error: "error";
567
+ window: "window";
568
+ rate: "rate";
569
+ credit: "credit";
570
+ configured: "configured";
571
+ }>>>;
572
+ unit: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
573
+ requests: "requests";
574
+ percent: "percent";
575
+ tokens: "tokens";
576
+ usd: "usd";
577
+ currency: "currency";
578
+ count: "count";
579
+ }>>>;
580
+ used: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
581
+ limit: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
582
+ remaining: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
583
+ source: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
584
+ error: "error";
585
+ headers: "headers";
586
+ estimate: "estimate";
587
+ provider: "provider";
588
+ }>>>;
589
+ observedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
590
+ detail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
418
591
  }, z.core.$strip>>>;
419
592
  }, z.core.$strip>;
420
593
  'status.changed': z.ZodObject<{
@@ -462,7 +635,10 @@ export declare const runEventSchema: z.ZodObject<{
462
635
  "extension.notice": "extension.notice";
463
636
  "reaction.added": "reaction.added";
464
637
  "agent.message": "agent.message";
638
+ "todo.updated": "todo.updated";
465
639
  "checklist.updated": "checklist.updated";
640
+ checkpoint: "checkpoint";
641
+ heartbeat: "heartbeat";
466
642
  "artifact.added": "artifact.added";
467
643
  "file.changed": "file.changed";
468
644
  "usage.updated": "usage.updated";
@@ -494,6 +670,8 @@ export interface RunRecord {
494
670
  sessionId: string;
495
671
  nativeSessionId: string | null;
496
672
  workingDirectory: string | null;
673
+ /** Canonical filesystem root whose writes this run may make by default. */
674
+ workspaceRoot?: string | null;
497
675
  worktreeId: string | null;
498
676
  goal: string | null;
499
677
  attachmentCount: number;
@@ -515,6 +693,10 @@ export interface RunRecord {
515
693
  profile?: string | null;
516
694
  /** The short name a parent gave a subagent, shown in the roster (PROP-0030). */
517
695
  title?: string | null;
696
+ /** The model the run used, as `provider/id`: the launch selection, then the one the session opened. */
697
+ model?: string | null;
698
+ /** The reasoning effort the run used. */
699
+ effort?: string | null;
518
700
  }
519
701
  export declare const runRecordSchema: z.ZodObject<{
520
702
  resumedFromRunId: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>;
@@ -529,6 +711,7 @@ export declare const runRecordSchema: z.ZodObject<{
529
711
  sessionId: z.ZodString;
530
712
  nativeSessionId: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>;
531
713
  workingDirectory: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>;
714
+ workspaceRoot: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>>;
532
715
  worktreeId: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>;
533
716
  goal: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>;
534
717
  attachmentCount: z.ZodDefault<z.ZodNumber>;
@@ -544,8 +727,11 @@ export declare const runRecordSchema: z.ZodObject<{
544
727
  variantVersion: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>>;
545
728
  profile: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>>;
546
729
  title: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>>;
730
+ model: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>>;
731
+ effort: z.ZodOptional<z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodString>>, z.ZodTransform<string | null, string | null | undefined>>>;
547
732
  }, z.core.$strip>;
548
733
  /** Records written before PROP-0009 name the variant `harnessScope` and `harnessVersion`. */
549
734
  export declare function upgradeRunRecord(raw: unknown): unknown;
550
735
  export declare const ACTIVE_STATUSES: readonly string[];
551
736
  export declare function isActiveStatus(status: string): boolean;
737
+ export {};
@@ -21,7 +21,11 @@ export const runEventTypeSchema = z.enum([
21
21
  'extension.notice',
22
22
  'reaction.added',
23
23
  'agent.message',
24
+ 'todo.updated',
25
+ // Written before the rename; accepted so stored run logs keep their lists. Never written now.
24
26
  'checklist.updated',
27
+ 'checkpoint',
28
+ 'heartbeat',
25
29
  'artifact.added',
26
30
  'file.changed',
27
31
  'usage.updated',
@@ -172,11 +176,54 @@ const extensionNoticePayload = z.object({
172
176
  text: z.string(),
173
177
  extension: z.string().optional()
174
178
  });
175
- /** One line of the run's checklist. The list has no ids: every update replaces all of it. */
176
- export const checklistItemSchema = z.object({ text: z.string().min(1).max(500), status: z.enum(['pending', 'in_progress', 'completed']) }).strict();
177
- export const MAX_CHECKLIST_ITEMS = 50;
178
- /** The whole checklist as the model last wrote it; the latest event replaces every earlier one. */
179
- const checklistPayload = z.object({ items: z.array(checklistItemSchema).max(MAX_CHECKLIST_ITEMS) }).strict();
179
+ /** One line of the run's todo list. The list has no ids: every update replaces all of it. */
180
+ export const todoItemSchema = z.object({ text: z.string().min(1).max(500), status: z.enum(['pending', 'in_progress', 'completed']) }).strict();
181
+ export const MAX_TODO_ITEMS = 50;
182
+ /** The whole todo list as the model last wrote it; the latest event replaces every earlier one. */
183
+ const todoPayload = z.object({ items: z.array(todoItemSchema).max(MAX_TODO_ITEMS) }).strict();
184
+ export const MAX_CHECKPOINT_SUMMARY = 1_200;
185
+ export const MAX_CHECKPOINT_DONE = 20;
186
+ export const MAX_CHECKPOINT_EVIDENCE = 5;
187
+ export const MAX_CHECKPOINT_FILES = 20;
188
+ export const MAX_CHECKPOINT_CHECKS = 8;
189
+ export const MAX_CHECKPOINT_DECISIONS = 8;
190
+ /**
191
+ * The handoff a reply writes when it reaches its work-slice budget. The harness validates and
192
+ * records it; the next slice is told where this one stopped from it (PROP-0041).
193
+ */
194
+ export const checkpointItemSchema = z.object({
195
+ item: z.string().min(1).max(300),
196
+ evidence: z.array(z.string().min(1).max(300)).max(MAX_CHECKPOINT_EVIDENCE).default([])
197
+ }).strict();
198
+ export const checkpointFileSchema = z.object({ path: z.string().min(1).max(300), why: z.string().max(200).default('') }).strict();
199
+ export const checkpointCheckSchema = z.object({
200
+ command: z.string().min(1).max(200),
201
+ ok: z.boolean(),
202
+ detail: z.string().max(300).optional()
203
+ }).strict();
204
+ export const checkpointDecisionSchema = z.object({ what: z.string().min(1).max(200), why: z.string().max(300).default('') }).strict();
205
+ export const checkpointReasonSchema = z.enum(['budget', 'stuck', 'compaction-thrash', 'requested']);
206
+ const checkpointPayload = z.object({
207
+ summary: z.string().max(MAX_CHECKPOINT_SUMMARY),
208
+ done: z.array(checkpointItemSchema).max(MAX_CHECKPOINT_DONE).default([]),
209
+ next: z.string().max(500).default(''),
210
+ blocked: z.string().max(500).optional(),
211
+ files: z.array(checkpointFileSchema).max(MAX_CHECKPOINT_FILES).default([]),
212
+ checks: z.array(checkpointCheckSchema).max(MAX_CHECKPOINT_CHECKS).default([]),
213
+ decisions: z.array(checkpointDecisionSchema).max(MAX_CHECKPOINT_DECISIONS).default([]),
214
+ /** Which slice of the session wrote it, from 1. */
215
+ slice: z.number().int().positive(),
216
+ reason: checkpointReasonSchema
217
+ }).strict();
218
+ /** Counters a live reply reports while it works; a person and the watchdog read liveness from it. */
219
+ const heartbeatPayload = z.object({
220
+ steps: z.number().int().nonnegative(),
221
+ elapsedMs: z.number().nonnegative(),
222
+ lastTool: z.string().max(120).nullable(),
223
+ compactions: z.number().int().nonnegative(),
224
+ slice: z.number().int().positive(),
225
+ maxToolCalls: z.number().int().nonnegative()
226
+ }).strict();
180
227
  const artifactPayload = z.object({ artifactId: z.string(), name: z.string(), file: z.unknown().optional() });
181
228
  const fileChangedPayload = z.object({ path: z.string(), change: z.enum(['added', 'modified', 'deleted']) });
182
229
  /** Where a cost figure comes from: Pi reported it, or the tokens were priced at list rates. */
@@ -228,9 +275,19 @@ export const accountLimitSchema = z.object({
228
275
  id: z.string(),
229
276
  label: z.string(),
230
277
  usedPercent: z.number().nullable().optional(),
278
+ remainingPercent: z.number().nullable().optional(),
231
279
  resetsAt: z.string().nullable().optional(),
232
280
  windowMinutes: z.number().nullable().optional(),
233
- status: z.string().nullable().optional()
281
+ status: z.string().nullable().optional(),
282
+ provider: z.string().nullable().optional(),
283
+ kind: z.enum(['window', 'rate', 'credit', 'configured', 'error']).nullable().optional(),
284
+ unit: z.enum(['percent', 'requests', 'tokens', 'usd', 'currency', 'count']).nullable().optional(),
285
+ used: z.number().nullable().optional(),
286
+ limit: z.number().nullable().optional(),
287
+ remaining: z.number().nullable().optional(),
288
+ source: z.enum(['headers', 'provider', 'estimate', 'error']).nullable().optional(),
289
+ observedAt: z.string().nullable().optional(),
290
+ detail: z.string().nullable().optional()
234
291
  });
235
292
  /** Limit snapshots, plan changes, and classified account failures. */
236
293
  const accountStatusPayload = z.object({
@@ -264,7 +321,10 @@ export const runEventPayloadSchemas = {
264
321
  'extension.notice': extensionNoticePayload,
265
322
  'reaction.added': reactionAddedPayload,
266
323
  'agent.message': agentMessagePayload,
267
- 'checklist.updated': checklistPayload,
324
+ 'todo.updated': todoPayload,
325
+ 'checklist.updated': todoPayload,
326
+ checkpoint: checkpointPayload,
327
+ heartbeat: heartbeatPayload,
268
328
  'artifact.added': artifactPayload,
269
329
  'file.changed': fileChangedPayload,
270
330
  'usage.updated': usagePayloadSchema,
@@ -306,6 +366,7 @@ export const runRecordSchema = z.object({
306
366
  sessionId: z.string(),
307
367
  nativeSessionId: text,
308
368
  workingDirectory: text,
369
+ workspaceRoot: text.optional(),
309
370
  worktreeId: text,
310
371
  goal: text,
311
372
  attachmentCount: z.number().int().nonnegative().default(0),
@@ -320,7 +381,9 @@ export const runRecordSchema = z.object({
320
381
  variantScope: text.optional(),
321
382
  variantVersion: text.optional(),
322
383
  profile: text.optional(),
323
- title: text.optional()
384
+ title: text.optional(),
385
+ model: text.optional(),
386
+ effort: text.optional()
324
387
  });
325
388
  /** Records written before PROP-0009 name the variant `harnessScope` and `harnessVersion`. */
326
389
  export function upgradeRunRecord(raw) {
@@ -0,0 +1,72 @@
1
+ /** Which saved history a command acts on: one file in the folder, or the newest there. */
2
+ export interface SessionRef {
3
+ sessionDir: string;
4
+ sessionFile?: string | null;
5
+ /** Recorded in a new history's header. Defaults to the source history's own folder. */
6
+ cwd?: string | null;
7
+ }
8
+ export interface SessionTreeEntry {
9
+ id: string;
10
+ parentId: string | null;
11
+ type: string;
12
+ /** `user`, `assistant`, `toolResult`, ... for a message entry. */
13
+ role?: string;
14
+ /** One line of what the entry says, at most 160 characters. */
15
+ text: string;
16
+ label?: string;
17
+ timestamp: string;
18
+ /** How deep in the tree, for indentation. */
19
+ depth: number;
20
+ }
21
+ export interface SessionTree {
22
+ sessionFile: string;
23
+ leafId: string | null;
24
+ entries: SessionTreeEntry[];
25
+ /** The person's messages on the current branch, newest last: where `/fork` may start. */
26
+ forkPoints: {
27
+ entryId: string;
28
+ text: string;
29
+ }[];
30
+ }
31
+ /** A move without a summary is saved as this entry, so the next turn opens on the chosen branch. */
32
+ export declare const NAVIGATION_ENTRY = "xingular-navigation";
33
+ export declare function tree(ref: SessionRef): SessionTree;
34
+ /**
35
+ * Moves the conversation to another entry without a summary. Choosing one of the person's
36
+ * messages goes to just before it and gives its text back to edit, as the terminal does.
37
+ */
38
+ export declare function navigate(ref: SessionRef & {
39
+ entryId: string;
40
+ }): {
41
+ leafId: string | null;
42
+ editorText?: string;
43
+ };
44
+ /** A new history in `targetDir` that ends just before one of the person's messages. */
45
+ export declare function fork(ref: SessionRef & {
46
+ entryId: string;
47
+ targetDir: string;
48
+ }): {
49
+ sessionFile: string;
50
+ editorText: string;
51
+ };
52
+ /** A new history in `targetDir` with the whole current branch. */
53
+ export declare function clone(ref: SessionRef & {
54
+ targetDir: string;
55
+ }): {
56
+ sessionFile: string;
57
+ };
58
+ export declare function rename(ref: SessionRef & {
59
+ name: string;
60
+ }): {
61
+ name: string;
62
+ };
63
+ /** The text of the last reply on the current branch, or null before the first. */
64
+ export declare function lastReply(ref: SessionRef): {
65
+ text: string | null;
66
+ };
67
+ /** Writes the current branch as JSONL. HTML needs a live session: see `SessionCommand`. */
68
+ export declare function exportJsonl(ref: SessionRef & {
69
+ path: string;
70
+ }): {
71
+ path: string;
72
+ };