indusagi-coding-agent 0.2.4 → 0.2.5

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 (266) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +95 -1
  3. package/dist/entry.js +1559 -1100
  4. package/dist/guardrails.js +26 -509
  5. package/dist/index.js +1581 -1155
  6. package/package.json +8 -7
  7. package/dist/types/addons/addons.test.d.ts +0 -21
  8. package/dist/types/addons/contract.d.ts +0 -640
  9. package/dist/types/addons/dispatch/event-dispatcher.d.ts +0 -140
  10. package/dist/types/addons/dispatch/index.d.ts +0 -23
  11. package/dist/types/addons/dispatch/tool-interceptor.d.ts +0 -128
  12. package/dist/types/addons/host.d.ts +0 -246
  13. package/dist/types/addons/index.d.ts +0 -51
  14. package/dist/types/addons/manifest.d.ts +0 -56
  15. package/dist/types/addons/sandbox.d.ts +0 -103
  16. package/dist/types/addons/surface.d.ts +0 -42
  17. package/dist/types/boot/auth-vault.d.ts +0 -29
  18. package/dist/types/boot/boot.d.ts +0 -26
  19. package/dist/types/boot/boot.test.d.ts +0 -15
  20. package/dist/types/boot/contract.d.ts +0 -236
  21. package/dist/types/boot/heap.d.ts +0 -31
  22. package/dist/types/boot/index.d.ts +0 -20
  23. package/dist/types/boot/invocation.d.ts +0 -40
  24. package/dist/types/boot/invocation.test.d.ts +0 -8
  25. package/dist/types/boot/runners/addon-wiring.d.ts +0 -103
  26. package/dist/types/boot/runners/addon-wiring.test.d.ts +0 -19
  27. package/dist/types/boot/runners/checkpoint.d.ts +0 -133
  28. package/dist/types/boot/runners/checkpoint.test.d.ts +0 -12
  29. package/dist/types/boot/runners/delegate-runner.d.ts +0 -109
  30. package/dist/types/boot/runners/delegate-runner.test.d.ts +0 -13
  31. package/dist/types/boot/runners/index.d.ts +0 -13
  32. package/dist/types/boot/runners/link-runner.d.ts +0 -20
  33. package/dist/types/boot/runners/memdir.d.ts +0 -103
  34. package/dist/types/boot/runners/memdir.test.d.ts +0 -12
  35. package/dist/types/boot/runners/oneshot-runner.d.ts +0 -19
  36. package/dist/types/boot/runners/read-state.d.ts +0 -82
  37. package/dist/types/boot/runners/read-state.test.d.ts +0 -10
  38. package/dist/types/boot/runners/registry.d.ts +0 -30
  39. package/dist/types/boot/runners/repl-runner.d.ts +0 -19
  40. package/dist/types/boot/runners/server-mode.d.ts +0 -71
  41. package/dist/types/boot/runners/session-persist.test.d.ts +0 -10
  42. package/dist/types/boot/runners/session.d.ts +0 -88
  43. package/dist/types/boot/runners/session.test.d.ts +0 -15
  44. package/dist/types/boot/server-token.d.ts +0 -97
  45. package/dist/types/boot/stages.d.ts +0 -92
  46. package/dist/types/boot/upgrade/apply.d.ts +0 -45
  47. package/dist/types/boot/upgrade/index.d.ts +0 -13
  48. package/dist/types/boot/upgrade/upgrades.d.ts +0 -126
  49. package/dist/types/briefing/briefing.test.d.ts +0 -15
  50. package/dist/types/briefing/compose.d.ts +0 -37
  51. package/dist/types/briefing/context-docs.d.ts +0 -38
  52. package/dist/types/briefing/context-docs.test.d.ts +0 -18
  53. package/dist/types/briefing/contract.d.ts +0 -686
  54. package/dist/types/briefing/index.d.ts +0 -29
  55. package/dist/types/briefing/macros.d.ts +0 -206
  56. package/dist/types/briefing/skills.d.ts +0 -67
  57. package/dist/types/capability-deck/bridge-ledger/index.d.ts +0 -25
  58. package/dist/types/capability-deck/bridge-ledger/key.d.ts +0 -65
  59. package/dist/types/capability-deck/bridge-ledger/ledger.d.ts +0 -129
  60. package/dist/types/capability-deck/bridge-ledger/network.d.ts +0 -115
  61. package/dist/types/capability-deck/builtin-bridge.d.ts +0 -114
  62. package/dist/types/capability-deck/capability-deck.test.d.ts +0 -18
  63. package/dist/types/capability-deck/cards/bg-process-card.d.ts +0 -99
  64. package/dist/types/capability-deck/cards/index.d.ts +0 -37
  65. package/dist/types/capability-deck/cards/memory-card.d.ts +0 -68
  66. package/dist/types/capability-deck/cards/plan-file.d.ts +0 -56
  67. package/dist/types/capability-deck/cards/plan-tools.d.ts +0 -97
  68. package/dist/types/capability-deck/cards/plan-tools.test.d.ts +0 -9
  69. package/dist/types/capability-deck/cards/saas-card.d.ts +0 -78
  70. package/dist/types/capability-deck/cards/task-card.d.ts +0 -106
  71. package/dist/types/capability-deck/cards/todo-card.d.ts +0 -78
  72. package/dist/types/capability-deck/cards/workflow-card.d.ts +0 -55
  73. package/dist/types/capability-deck/cards/workflow-card.test.d.ts +0 -12
  74. package/dist/types/capability-deck/checkpoint.int.test.d.ts +0 -25
  75. package/dist/types/capability-deck/contract.d.ts +0 -318
  76. package/dist/types/capability-deck/index.d.ts +0 -46
  77. package/dist/types/capability-deck/manifest.d.ts +0 -60
  78. package/dist/types/capability-deck/provision.d.ts +0 -76
  79. package/dist/types/capability-deck/read-edit-gate.int.test.d.ts +0 -21
  80. package/dist/types/channels/channels.test.d.ts +0 -15
  81. package/dist/types/channels/contract.d.ts +0 -489
  82. package/dist/types/channels/framer.d.ts +0 -49
  83. package/dist/types/channels/index.d.ts +0 -24
  84. package/dist/types/channels/link/dialog.d.ts +0 -138
  85. package/dist/types/channels/link/driver.d.ts +0 -81
  86. package/dist/types/channels/link/index.d.ts +0 -13
  87. package/dist/types/channels/link/server.d.ts +0 -70
  88. package/dist/types/channels/oneshot.d.ts +0 -37
  89. package/dist/types/channels/ops.d.ts +0 -89
  90. package/dist/types/channels/session-ops.d.ts +0 -80
  91. package/dist/types/conductor/bash-guard.d.ts +0 -106
  92. package/dist/types/conductor/bash-guard.test.d.ts +0 -17
  93. package/dist/types/conductor/catalog/catalog.d.ts +0 -87
  94. package/dist/types/conductor/catalog/index.d.ts +0 -14
  95. package/dist/types/conductor/catalog/matcher.d.ts +0 -47
  96. package/dist/types/conductor/conductor.d.ts +0 -213
  97. package/dist/types/conductor/conductor.test.d.ts +0 -10
  98. package/dist/types/conductor/contract.d.ts +0 -838
  99. package/dist/types/conductor/diagnostics.d.ts +0 -183
  100. package/dist/types/conductor/diagnostics.test.d.ts +0 -10
  101. package/dist/types/conductor/index.d.ts +0 -26
  102. package/dist/types/conductor/permission-gate.integration.test.d.ts +0 -22
  103. package/dist/types/conductor/permission-wiring.test.d.ts +0 -14
  104. package/dist/types/conductor/permissions.d.ts +0 -287
  105. package/dist/types/conductor/permissions.test.d.ts +0 -12
  106. package/dist/types/conductor/plan-mode.integration.test.d.ts +0 -23
  107. package/dist/types/conductor/post-edit-diagnostics.test.d.ts +0 -18
  108. package/dist/types/conductor/quota-error.d.ts +0 -35
  109. package/dist/types/conductor/signal-hub/hub.d.ts +0 -83
  110. package/dist/types/conductor/signal-hub/index.d.ts +0 -19
  111. package/dist/types/conductor/signal-hub/translate.d.ts +0 -77
  112. package/dist/types/conductor/skill-parse/index.d.ts +0 -10
  113. package/dist/types/conductor/skill-parse/parse.d.ts +0 -67
  114. package/dist/types/conductor/submit.test.d.ts +0 -28
  115. package/dist/types/conductor/transcript-store/index.d.ts +0 -16
  116. package/dist/types/conductor/transcript-store/serialize.d.ts +0 -106
  117. package/dist/types/conductor/transcript-store/serialize.test.d.ts +0 -10
  118. package/dist/types/conductor/transcript-store/store.d.ts +0 -188
  119. package/dist/types/console/auth-status.d.ts +0 -28
  120. package/dist/types/console/components/AgentsView.d.ts +0 -41
  121. package/dist/types/console/components/BackgroundAgents.d.ts +0 -63
  122. package/dist/types/console/components/BackgroundAgents.test.d.ts +0 -8
  123. package/dist/types/console/components/Banner.d.ts +0 -110
  124. package/dist/types/console/components/Composer.d.ts +0 -37
  125. package/dist/types/console/components/StatusBar.d.ts +0 -42
  126. package/dist/types/console/components/TerminalConsole.d.ts +0 -27
  127. package/dist/types/console/components/WorkingIndicator.d.ts +0 -44
  128. package/dist/types/console/components/WorkingIndicator.test.d.ts +0 -9
  129. package/dist/types/console/components/banner-sweep.d.ts +0 -55
  130. package/dist/types/console/components/banner.test.d.ts +0 -9
  131. package/dist/types/console/components/welcome.d.ts +0 -115
  132. package/dist/types/console/components/welcome.test.d.ts +0 -9
  133. package/dist/types/console/console.test.d.ts +0 -19
  134. package/dist/types/console/contract.d.ts +0 -611
  135. package/dist/types/console/index.d.ts +0 -34
  136. package/dist/types/console/input/complete.d.ts +0 -120
  137. package/dist/types/console/input/dir-reader.d.ts +0 -28
  138. package/dist/types/console/input/index.d.ts +0 -24
  139. package/dist/types/console/input/input.test.d.ts +0 -14
  140. package/dist/types/console/input/keymap.d.ts +0 -193
  141. package/dist/types/console/input/paste.d.ts +0 -183
  142. package/dist/types/console/mount.d.ts +0 -53
  143. package/dist/types/console/overlays/approval-queue.d.ts +0 -88
  144. package/dist/types/console/overlays/approval.d.ts +0 -104
  145. package/dist/types/console/overlays/approval.test.d.ts +0 -17
  146. package/dist/types/console/overlays/auth.d.ts +0 -31
  147. package/dist/types/console/overlays/boards.d.ts +0 -55
  148. package/dist/types/console/overlays/host.d.ts +0 -45
  149. package/dist/types/console/overlays/index.d.ts +0 -15
  150. package/dist/types/console/overlays/pickers.d.ts +0 -37
  151. package/dist/types/console/overlays/sessions.d.ts +0 -29
  152. package/dist/types/console/reducer.d.ts +0 -51
  153. package/dist/types/console/slash/builtins.d.ts +0 -33
  154. package/dist/types/console/slash/commands/dynamic.d.ts +0 -57
  155. package/dist/types/console/slash/commands/dynamic.test.d.ts +0 -9
  156. package/dist/types/console/slash/commands/integrations.d.ts +0 -28
  157. package/dist/types/console/slash/commands/integrations.test.d.ts +0 -18
  158. package/dist/types/console/slash/commands/shared.d.ts +0 -72
  159. package/dist/types/console/slash/commands/transcript.d.ts +0 -24
  160. package/dist/types/console/slash/commands/transcript.test.d.ts +0 -10
  161. package/dist/types/console/slash/commands/workbench.d.ts +0 -21
  162. package/dist/types/console/slash/commands/workbench.test.d.ts +0 -10
  163. package/dist/types/console/slash/index.d.ts +0 -34
  164. package/dist/types/console/slash/registry.d.ts +0 -90
  165. package/dist/types/console/slash/resolve.d.ts +0 -109
  166. package/dist/types/console/slash/slash.test.d.ts +0 -18
  167. package/dist/types/console/startup.d.ts +0 -119
  168. package/dist/types/console/theme/adapter.d.ts +0 -79
  169. package/dist/types/console/theme/index.d.ts +0 -18
  170. package/dist/types/console/theme/palette.d.ts +0 -77
  171. package/dist/types/console/theme/resolve.d.ts +0 -45
  172. package/dist/types/console/theme/theme.test.d.ts +0 -16
  173. package/dist/types/console/theme/tokens.d.ts +0 -62
  174. package/dist/types/entry.d.ts +0 -17
  175. package/dist/types/guardrails.d.ts +0 -33
  176. package/dist/types/index.d.ts +0 -24
  177. package/dist/types/insight/channel.d.ts +0 -45
  178. package/dist/types/insight/contract.d.ts +0 -411
  179. package/dist/types/insight/index.d.ts +0 -26
  180. package/dist/types/insight/insight.test.d.ts +0 -17
  181. package/dist/types/insight/recorder.d.ts +0 -63
  182. package/dist/types/insight/redaction.d.ts +0 -44
  183. package/dist/types/insight/replay.d.ts +0 -77
  184. package/dist/types/insight/sampling.d.ts +0 -84
  185. package/dist/types/insight/serialize.d.ts +0 -54
  186. package/dist/types/insight/sinks/console.d.ts +0 -36
  187. package/dist/types/insight/sinks/file.d.ts +0 -37
  188. package/dist/types/insight/sinks/index.d.ts +0 -16
  189. package/dist/types/insight/sinks/stream.d.ts +0 -53
  190. package/dist/types/kit/clipboard-image.d.ts +0 -40
  191. package/dist/types/kit/external-editor.d.ts +0 -35
  192. package/dist/types/kit/image.d.ts +0 -102
  193. package/dist/types/kit/index.d.ts +0 -29
  194. package/dist/types/kit/kit.test.d.ts +0 -13
  195. package/dist/types/kit/shell.d.ts +0 -50
  196. package/dist/types/kit/tool-fetch.d.ts +0 -165
  197. package/dist/types/launch/catalog.d.ts +0 -51
  198. package/dist/types/launch/contract.d.ts +0 -387
  199. package/dist/types/launch/credentials.d.ts +0 -112
  200. package/dist/types/launch/index.d.ts +0 -28
  201. package/dist/types/launch/invocation/attachments.d.ts +0 -72
  202. package/dist/types/launch/invocation/flags.d.ts +0 -59
  203. package/dist/types/launch/invocation/index.d.ts +0 -23
  204. package/dist/types/launch/invocation/read.d.ts +0 -52
  205. package/dist/types/launch/invocation/usage.d.ts +0 -25
  206. package/dist/types/launch/launch.test.d.ts +0 -20
  207. package/dist/types/launch/login.d.ts +0 -68
  208. package/dist/types/launch/oauth.d.ts +0 -101
  209. package/dist/types/launch/oauth.test.d.ts +0 -20
  210. package/dist/types/launch/packages.d.ts +0 -75
  211. package/dist/types/launch/packages.test.d.ts +0 -15
  212. package/dist/types/launch/pickers.d.ts +0 -97
  213. package/dist/types/runtime-bridge/bridges/_drive.d.ts +0 -74
  214. package/dist/types/runtime-bridge/bridges/builtins.d.ts +0 -77
  215. package/dist/types/runtime-bridge/bridges/claude-cli.d.ts +0 -37
  216. package/dist/types/runtime-bridge/bridges/codex-cli.d.ts +0 -27
  217. package/dist/types/runtime-bridge/bridges/index.d.ts +0 -15
  218. package/dist/types/runtime-bridge/bridges/indusagi-cli.d.ts +0 -36
  219. package/dist/types/runtime-bridge/broker.d.ts +0 -182
  220. package/dist/types/runtime-bridge/contract.d.ts +0 -436
  221. package/dist/types/runtime-bridge/index.d.ts +0 -21
  222. package/dist/types/runtime-bridge/runtime-bridge.test.d.ts +0 -17
  223. package/dist/types/runtime-bridge/sink.d.ts +0 -59
  224. package/dist/types/sessions/contract.d.ts +0 -79
  225. package/dist/types/sessions/index.d.ts +0 -11
  226. package/dist/types/sessions/library.d.ts +0 -95
  227. package/dist/types/sessions/sessions.test.d.ts +0 -11
  228. package/dist/types/settings/contract.d.ts +0 -175
  229. package/dist/types/settings/index.d.ts +0 -13
  230. package/dist/types/settings/manager.d.ts +0 -109
  231. package/dist/types/settings/settings.test.d.ts +0 -16
  232. package/dist/types/transcript-export/index.d.ts +0 -20
  233. package/dist/types/transcript-export/publish.d.ts +0 -81
  234. package/dist/types/transcript-export/sgr.d.ts +0 -90
  235. package/dist/types/transcript-export/template.d.ts +0 -64
  236. package/dist/types/transcript-export/theme-bridge.d.ts +0 -99
  237. package/dist/types/transcript-export/transcript-export.test.d.ts +0 -16
  238. package/dist/types/window-budget/budget/estimate.d.ts +0 -47
  239. package/dist/types/window-budget/budget/gate.d.ts +0 -37
  240. package/dist/types/window-budget/budget/index.d.ts +0 -14
  241. package/dist/types/window-budget/budget/slice.d.ts +0 -38
  242. package/dist/types/window-budget/condenser.d.ts +0 -73
  243. package/dist/types/window-budget/contract.d.ts +0 -182
  244. package/dist/types/window-budget/index.d.ts +0 -17
  245. package/dist/types/window-budget/microcompact.d.ts +0 -68
  246. package/dist/types/window-budget/microcompact.test.d.ts +0 -16
  247. package/dist/types/window-budget/rehydrate.d.ts +0 -56
  248. package/dist/types/window-budget/summarize/condense.d.ts +0 -76
  249. package/dist/types/window-budget/summarize/index.d.ts +0 -12
  250. package/dist/types/window-budget/summarize/prompt.d.ts +0 -56
  251. package/dist/types/window-budget/window-budget.test.d.ts +0 -18
  252. package/dist/types/workflow-engine/agent-runner.d.ts +0 -124
  253. package/dist/types/workflow-engine/agent-runner.test.d.ts +0 -8
  254. package/dist/types/workflow-engine/display.d.ts +0 -148
  255. package/dist/types/workflow-engine/display.test.d.ts +0 -1
  256. package/dist/types/workflow-engine/engine.d.ts +0 -183
  257. package/dist/types/workflow-engine/engine.test.d.ts +0 -1
  258. package/dist/types/workflow-engine/index.d.ts +0 -21
  259. package/dist/types/workflow-engine/parse.d.ts +0 -64
  260. package/dist/types/workflow-engine/parse.test.d.ts +0 -1
  261. package/dist/types/workflow-engine/structured-output.d.ts +0 -51
  262. package/dist/types/workflow-engine/structured-output.test.d.ts +0 -1
  263. package/dist/types/workspace/brand.d.ts +0 -26
  264. package/dist/types/workspace/index.d.ts +0 -11
  265. package/dist/types/workspace/locator.d.ts +0 -50
  266. package/dist/types/workspace/runtime-detect.d.ts +0 -56
@@ -1,838 +0,0 @@
1
- /**
2
- * Conductor contract — the FROZEN type surface of Phase 2 (agent runtime core).
3
- *
4
- * This module is the single typed seam between the coding-agent *product* (the
5
- * UI/channels that drive a session) and the framework `Agent` (the raw LLM
6
- * conversation loop, published by `indusagi/agent`). It declares *only* shapes
7
- * plus two tiny inert helpers — no behavior, no I/O, no orchestration. Every
8
- * later conductor module (the signal hub, the transcript store, the model
9
- * catalog/matcher, the credential vault, the conductor factory, and the
10
- * `SessionConductor` itself) is written against the names declared here, so the
11
- * file is intentionally small, append-mostly, and stable.
12
- *
13
- * Design stance:
14
- * - The conductor *wraps* the framework `Agent`. The framework emits a
15
- * fine-grained `AgentEvent` stream for its own loop; the conductor consumes
16
- * that internally and **re-emits a distinct, product-level
17
- * {@link SessionSignal} stream** to consumers. The two are deliberately not
18
- * the same union: `SessionSignal` is the stable surface the app renders,
19
- * free to evolve independently of the framework's loop events.
20
- * - Faults are **typed discriminated values** ({@link ConductorFault}), never
21
- * string sentinels. A consumer switches on `fault.kind`, not on substring
22
- * matching of a message.
23
- * - Persistence uses a **fresh on-disk vocabulary** ({@link TranscriptEntry},
24
- * {@link SessionHead}, {@link TRANSCRIPT_SCHEMA}). The node is a `parent`-linked
25
- * tree, the version is a namespaced string, and the field names are the
26
- * conductor's own — not the framework's session-manager schema.
27
- * - State is exposed as an **immutable snapshot** ({@link ConductorState});
28
- * consumers read it, they never mutate it.
29
- *
30
- * Framework anchors (all from the `indusagi` package — the sibling rebuilt
31
- * framework this app targets):
32
- * - `AgentMessage`, `ThinkingLevel`, `AgentTool` ← `indusagi/agent`
33
- * - `Model`, `Usage`, `KnownProvider` ← `indusagi/ai`
34
- *
35
- * The conductor never re-declares these; it composes them.
36
- */
37
- import type { AgentMessage, AgentTool, CanUseToolFn, ThinkingLevel } from "indusagi/agent";
38
- import type { KnownProvider, Model, Usage } from "indusagi/ai";
39
- import type { PermissionMode } from "../settings";
40
- import type { ApprovalResolver } from "./permissions";
41
- /** Re-exported framework vocabulary that conductor consumers routinely need. */
42
- export type { AgentMessage, AgentTool, CanUseToolFn, ThinkingLevel, Model, Usage, KnownProvider };
43
- /** Re-exported permission vocabulary, so conductor consumers get it in one import. */
44
- export type { PermissionMode, ApprovalResolver };
45
- /**
46
- * The closed set of failure categories the conductor can surface.
47
- *
48
- * Each is a distinct recovery story, so the kind is a discriminant — not a
49
- * free-form string:
50
- * - `model` — the LLM call itself failed (transport, provider, decode).
51
- * - `tool` — a tool invocation threw or returned a hard error.
52
- * - `persistence` — writing/reading the on-disk transcript failed.
53
- * - `aborted` — the caller cancelled the in-flight turn via {@link SessionConductor.abort}.
54
- * - `overflow` — the context window was exceeded and could not be condensed.
55
- */
56
- export type FaultKind = "model" | "tool" | "persistence" | "aborted" | "overflow";
57
- /**
58
- * A typed, discriminated failure value emitted on the {@link SessionSignal}
59
- * stream and attached to faulted states.
60
- *
61
- * The `kind` selects the category; `message` is a human-readable summary; the
62
- * optional `cause` carries the underlying error (or any structured detail) for
63
- * logging without forcing consumers to parse the message string.
64
- */
65
- export interface ConductorFault {
66
- /** Failure category — the discriminant consumers switch on. */
67
- readonly kind: FaultKind;
68
- /** Human-readable, single-line summary of what went wrong. */
69
- readonly message: string;
70
- /** Underlying error or structured detail, if any. */
71
- readonly cause?: unknown;
72
- }
73
- /**
74
- * Construct a {@link ConductorFault}. The single sanctioned way to mint a fault,
75
- * so the shape stays uniform across every producer.
76
- *
77
- * @param kind the failure category
78
- * @param message a human-readable, single-line summary
79
- * @param cause optional underlying error or structured detail
80
- */
81
- export declare function conductorFault(kind: FaultKind, message: string, cause?: unknown): ConductorFault;
82
- /**
83
- * The product-level event stream the conductor emits to its consumers (the
84
- * interactive UI, the print/JSON mode, the JSON-RPC link).
85
- *
86
- * This is the conductor's **re-emitted surface** — distinct from the framework
87
- * `AgentEvent` union. The conductor subscribes to the raw framework loop,
88
- * layers persistence / auto-condense / fault handling on top, and projects the
89
- * result down to this small, stable set of discriminated signals. Consumers
90
- * switch on `kind` and never see a framework loop event directly.
91
- *
92
- * - `prompt` — the user's turn was committed to the conversation; `text`
93
- * is the submitted prompt. Emitted the instant the turn is
94
- * accepted (before the model replies) so a UI can echo the
95
- * user message immediately rather than waiting for the first
96
- * assistant token.
97
- * - `text` — a chunk of assistant answer text streamed in.
98
- * - `thinking` — a chunk of reasoning/thinking text streamed in.
99
- * - `tool_start`— a tool invocation began (correlate by `id`).
100
- * - `tool_update`— a running tool emitted partial progress (correlate by `id`);
101
- * `name` is the tool name and `details` is the tool's own typed
102
- * partial-result detail (e.g. the live `◆ Workflow` snapshot).
103
- * - `tool_end` — a tool invocation finished (`ok` = no error).
104
- * - `turn_end` — the assistant turn settled; `usage` reports token spend.
105
- * - `persisted` — the latest node was committed to the transcript (`entryId`).
106
- * - `compacted` — the transcript WAS condensed (emitted on completion, not at
107
- * the start). `manual` marks a user-driven `/compact` — a view may then
108
- * reset its visible transcript — versus mid-turn auto-compaction, where the
109
- * display must keep the in-flight exchange on screen.
110
- * - `fault` — a typed {@link ConductorFault} occurred. `transient` marks a
111
- * fault surfaced purely as an in-turn notice (e.g. a fallback-model swap on
112
- * provider overload) — the turn keeps running, so a consumer must NOT treat
113
- * it as the turn's end (must not clear a busy/in-flight indicator on it).
114
- * - `queue` — the pending-input queue changed; `count` is its new depth.
115
- * - `idle` — the conductor has no in-flight work and is ready for input.
116
- */
117
- export type SessionSignal = {
118
- readonly kind: "prompt";
119
- readonly text: string;
120
- } | {
121
- readonly kind: "text";
122
- readonly delta: string;
123
- } | {
124
- readonly kind: "thinking";
125
- readonly delta: string;
126
- } | {
127
- readonly kind: "tool_start";
128
- readonly id: string;
129
- readonly name: string;
130
- } | {
131
- readonly kind: "tool_update";
132
- readonly id: string;
133
- readonly name: string;
134
- readonly details: unknown;
135
- } | {
136
- readonly kind: "tool_end";
137
- readonly id: string;
138
- readonly ok: boolean;
139
- } | {
140
- readonly kind: "turn_end";
141
- readonly usage: Usage;
142
- } | {
143
- readonly kind: "persisted";
144
- readonly entryId: string;
145
- } | {
146
- readonly kind: "compacted";
147
- readonly manual?: boolean;
148
- } | {
149
- readonly kind: "fault";
150
- readonly fault: ConductorFault;
151
- readonly transient?: boolean;
152
- } | {
153
- readonly kind: "queue";
154
- readonly count: number;
155
- } | {
156
- readonly kind: "idle";
157
- };
158
- /** The discriminant literals of {@link SessionSignal}, for filtering/logging. */
159
- export type SignalKind = SessionSignal["kind"];
160
- /** Extract a single member of {@link SessionSignal} by its `kind`. */
161
- export type SignalOf<K extends SignalKind> = Extract<SessionSignal, {
162
- kind: K;
163
- }>;
164
- /** A subscriber callback registered with {@link SessionConductor.subscribe}. */
165
- export type SignalHandler = (signal: SessionSignal) => void;
166
- /**
167
- * The on-disk transcript schema namespace + version.
168
- *
169
- * A namespaced string (not a bare integer) so the format is self-describing and
170
- * can evolve without colliding with any other versioned artifact in the app.
171
- * This is deliberately the conductor's own vocabulary.
172
- */
173
- export declare const TRANSCRIPT_SCHEMA: "indus/transcript@1";
174
- /** The literal type of {@link TRANSCRIPT_SCHEMA}. */
175
- export type TranscriptSchema = typeof TRANSCRIPT_SCHEMA;
176
- /**
177
- * The conversational role a {@link TranscriptEntry} node carries.
178
- *
179
- * Spans both the LLM-facing turns (`user`/`assistant`/`tool`) and the
180
- * conductor's own bookkeeping nodes (`system` seed, `condense` markers, and
181
- * `note` for app-injected context). Kept open at the product layer so the
182
- * transcript can hold more than the framework's message roles.
183
- */
184
- export type TranscriptRole = "user" | "assistant" | "tool" | "system" | "condense" | "note";
185
- /**
186
- * A single node in the on-disk transcript tree.
187
- *
188
- * The transcript is an append-only **tree**: every node names its `parent`
189
- * (a root has `parent: null`), and the active leaf is tracked separately in
190
- * {@link SessionHead}. Branching is moving the head to an earlier node; the next
191
- * append becomes that node's child. `content` holds the framework
192
- * {@link AgentMessage} payload so the node round-trips back into the agent loop;
193
- * `meta` carries optional, non-LLM annotations (labels, condense bookkeeping,
194
- * model/reasoning markers).
195
- *
196
- * Field names are the conductor's own (`parent`, `createdAt`, `meta`) — not the
197
- * framework's persistence schema.
198
- */
199
- export interface TranscriptEntry {
200
- /** Stable unique node id (e.g. a ULID). */
201
- readonly id: string;
202
- /** Parent node id, or `null` for the transcript root. */
203
- readonly parent: string | null;
204
- /** Conversational role of this node. */
205
- readonly role: TranscriptRole;
206
- /** The framework message payload this node persists. */
207
- readonly content: AgentMessage;
208
- /** ISO-8601 creation timestamp. */
209
- readonly createdAt: string;
210
- /** Optional, non-LLM annotations keyed by name. */
211
- readonly meta?: Readonly<Record<string, unknown>>;
212
- }
213
- /**
214
- * The head record of a persisted transcript: which session, and where its
215
- * active leaf currently points.
216
- *
217
- * The `leaf` is the id of the most recently appended (or branched-to) node;
218
- * walking `parent` links from `leaf` to a root reconstructs the active branch.
219
- * `null` means an empty transcript (no nodes yet).
220
- */
221
- export interface SessionHead {
222
- /** Stable identifier of the session this transcript belongs to. */
223
- readonly sessionId: string;
224
- /** Id of the active leaf node, or `null` for an empty transcript. */
225
- readonly leaf: string | null;
226
- /**
227
- * Cumulative session usage (tokens + cost) persisted alongside the head so
228
- * resume can restore the running total instead of seeding zero. Optional and
229
- * absent on legacy transcripts; the store rewrites the head line on every
230
- * flush, keeping this current with the live tally.
231
- */
232
- readonly usage?: Usage;
233
- }
234
- /**
235
- * A lightweight, resolved reference to one model card in the catalog.
236
- *
237
- * This is the *display/identity* projection of a framework {@link Model} — the
238
- * minimum a UI needs to list, label, and select a model without holding the
239
- * full model object. The matcher produces these; the conductor resolves the
240
- * chosen one back to a full `Model` when it configures the agent.
241
- */
242
- export interface ModelCardRef {
243
- /** Canonical `"provider/modelId"` identifier (the catalog key). */
244
- readonly id: string;
245
- /** Owning provider. */
246
- readonly provider: KnownProvider | string;
247
- /** Provider-scoped model id (e.g. `"claude-sonnet-4"`). */
248
- readonly modelId: string;
249
- /** Human-readable display name. */
250
- readonly name: string;
251
- /** Whether this model exposes a reasoning/thinking budget. */
252
- readonly reasoning: boolean;
253
- }
254
- /**
255
- * A query against the model catalog/matcher.
256
- *
257
- * Resolution is a prioritized candidate pipeline: an explicit `provider`+`modelId`
258
- * pins a single card; otherwise `pattern` is matched (exact id, `provider/`
259
- * prefix, then glob/fuzzy) and narrowed by the optional capability filters.
260
- * All fields are optional so an empty query means "the default candidate".
261
- */
262
- export interface MatchQuery {
263
- /** Free-form selector: an id, an alias, or a glob pattern. */
264
- readonly pattern?: string;
265
- /** Restrict candidates to this provider. */
266
- readonly provider?: KnownProvider | string;
267
- /** Pin a specific provider-scoped model id (used with {@link provider}). */
268
- readonly modelId?: string;
269
- /** Require reasoning/thinking support. */
270
- readonly reasoning?: boolean;
271
- /** Require image input support. */
272
- readonly supportsImageInput?: boolean;
273
- }
274
- /**
275
- * The coarse lifecycle phase of the conductor at a point in time.
276
- *
277
- * - `idle` — assembled and ready; no turn in flight.
278
- * - `streaming` — an assistant turn is producing text/thinking.
279
- * - `tooling` — a tool invocation is executing mid-turn.
280
- * - `condensing` — the transcript is being condensed to fit the window.
281
- * - `faulted` — the last turn ended in a {@link ConductorFault}.
282
- */
283
- export type ConductorPhase = "idle" | "streaming" | "tooling" | "condensing" | "faulted";
284
- /**
285
- * An immutable snapshot of the conductor's observable state.
286
- *
287
- * Returned by {@link SessionConductor.snapshot} and resolved by
288
- * {@link SessionConductor.submit}. It is a value, not a live view: every field
289
- * is read-only and the object reflects the instant it was taken. Re-read with a
290
- * fresh `snapshot()` to observe later changes.
291
- */
292
- export interface ConductorState {
293
- /** Coarse lifecycle phase at snapshot time. */
294
- readonly phase: ConductorPhase;
295
- /** The active transcript head (session id + current leaf). */
296
- readonly head: SessionHead;
297
- /** Cumulative token/cost spend across the session so far. */
298
- readonly usage: Usage;
299
- /**
300
- * Tokens occupying the model's context window as of the most recent turn —
301
- * the last assistant turn's reported usage, NOT the cumulative session spend.
302
- * This is what the footer's `ctx:%` divides by the context window;
303
- * {@link usage}.totalTokens grows unbounded across turns and would inflate it.
304
- */
305
- readonly contextTokens: number;
306
- /** Canonical id of the model currently bound to the session. */
307
- readonly modelId: string;
308
- /** The fault from the most recent turn, when {@link phase} is `"faulted"`. */
309
- readonly fault?: ConductorFault;
310
- }
311
- /**
312
- * How a queued input rejoins the conversation once the active turn settles.
313
- *
314
- * - `steer` — interrupt-style input meant to redirect the agent; drained
315
- * ahead of plain follow-ups.
316
- * - `followUp` — input that simply waits its turn after the current one ends.
317
- *
318
- * The conductor enqueues input under one of these modes when {@link SessionConductor.submit}
319
- * is called while a turn is in flight, then drains the queue in order.
320
- */
321
- export type QueueMode = "steer" | "followUp";
322
- /**
323
- * One entry in the conductor's pending-input queue: the {@link QueueMode} it was
324
- * filed under and the raw user `text`. Surfaced by
325
- * {@link SessionConductor.pendingInputs} so a UI can render what is waiting.
326
- */
327
- export interface QueuedInput {
328
- /** How this input will rejoin the conversation when drained. */
329
- readonly mode: QueueMode;
330
- /** The raw user message text held for a later turn. */
331
- readonly text: string;
332
- }
333
- /**
334
- * A point-in-time tally of the active session: message counts by role, tool
335
- * activity, cumulative token spend, and total cost. Computed by
336
- * {@link SessionConductor.stats} from the live message list plus the running
337
- * usage carried on {@link ConductorState}.
338
- */
339
- export interface SessionStats {
340
- /** Identifier of the session these figures describe. */
341
- readonly sessionId: string;
342
- /** Number of user-role messages in the active branch. */
343
- readonly userMessages: number;
344
- /** Number of assistant-role messages in the active branch. */
345
- readonly assistantMessages: number;
346
- /** Number of tool invocations the assistant issued. */
347
- readonly toolCalls: number;
348
- /** Number of tool-result messages produced in reply. */
349
- readonly toolResults: number;
350
- /** Total message count across all roles. */
351
- readonly totalMessages: number;
352
- /** Cumulative token spend, broken out by category and totalled. */
353
- readonly tokens: {
354
- readonly input: number;
355
- readonly output: number;
356
- readonly cacheRead: number;
357
- readonly cacheWrite: number;
358
- readonly total: number;
359
- };
360
- /** Cumulative monetary cost of the session so far. */
361
- readonly cost: number;
362
- }
363
- /** Options for {@link SessionConductor.executeBash}. */
364
- export interface ExecuteBashOptions {
365
- /**
366
- * When `true`, the command's output is *not* recorded as a transcript note,
367
- * so it never re-enters the agent's context. Defaults to `false`.
368
- */
369
- readonly excludeFromContext?: boolean;
370
- }
371
- /** The settled result of {@link SessionConductor.executeBash}. */
372
- export interface BashOutcome {
373
- /** Combined stdout + stderr of the command. */
374
- readonly output: string;
375
- /** Process exit code (`0` on success; non-zero, or `1` on a thrown error). */
376
- readonly exitCode: number;
377
- }
378
- /**
379
- * The minimal file-checkpoint surface the conductor drives for rewind (#24).
380
- *
381
- * The product mints a concrete `CheckpointStore` (in `boot/runners/checkpoint.ts`),
382
- * injects it into the deck's `ctx.framework` bag under the `'checkpoint'` key so
383
- * the framework's write/edit tools record pre-mutation file content against the
384
- * active transcript node, and ALSO hands it to the conductor as this port. The
385
- * conductor pins the active node id as its head advances ({@link setActiveNodeId})
386
- * so a turn's edits key to the node that was active before the turn, and exposes
387
- * {@link restore}/{@link hasSnapshot} so the tree picker can roll the working tree
388
- * back when navigating to an earlier node.
389
- *
390
- * Declared as a tiny structural port (not the concrete store) so the conductor
391
- * stays free of any boot-layer import — the product's store satisfies it by shape.
392
- */
393
- export interface CheckpointPort {
394
- /**
395
- * Pin the transcript node subsequent file snapshots are filed under. Called by
396
- * the conductor as its head advances (at turn start) so a turn's edits key to
397
- * the node active before the turn ran.
398
- *
399
- * @param id the active transcript node id, or `null` to fall back to the root
400
- */
401
- setActiveNodeId(id: string | null): void;
402
- /** Whether a node has ANY recorded file snapshot (the picker's restore gate). */
403
- hasSnapshot(nodeId: string): boolean;
404
- /**
405
- * Roll the working tree back to a node's recorded state, rewriting each tracked
406
- * file to its pre-mutation content (deleting files recorded as absent). A safe
407
- * no-op when the node has no snapshot.
408
- *
409
- * @param nodeId the transcript node whose file state to restore to
410
- * @returns the absolute paths that were written or deleted
411
- */
412
- restore(nodeId: string): string[];
413
- }
414
- /**
415
- * Options that configure a {@link SessionConductor} at assembly time.
416
- *
417
- * Only {@link modelId} is required; everything else has a sensible default
418
- * resolved by the conductor factory. The shape is intentionally small — richer
419
- * wiring (MCP, memory, provider routing) is attached by the factory, not passed
420
- * through this surface.
421
- */
422
- export interface SessionConductorOptions {
423
- /** Canonical id of the model to bind the session to. */
424
- readonly modelId: string;
425
- /** Initial system prompt seeding the conversation. */
426
- readonly system?: string;
427
- /** Tools made available to the agent for this session. */
428
- readonly tools?: AgentTool[];
429
- /** Initial reasoning effort for models that support it. */
430
- readonly thinking?: ThinkingLevel;
431
- /**
432
- * Canonical id of a model to fall back to when the bound model is overloaded
433
- * (HTTP 529 / "overloaded") mid-turn (`--fallback-model`). When set, an
434
- * overload that exhausts the transient-retry budget swaps to this model once
435
- * per turn and retries instead of surfacing a terminal fault. Absent disables
436
- * the swap entirely (behavior-preserving default).
437
- */
438
- readonly fallbackModelId?: string;
439
- /**
440
- * Per-provider indus-gateway base URLs ("server mode"), keyed by provider slug
441
- * (e.g. `{ minimax: "http://host/gateway/minimax", sarvam: "…/gateway/sarvam" }`).
442
- * Set by the session runner for every gateway-eligible provider the user has no
443
- * local key for but holds a valid server token. At EVERY model bind (including a
444
- * runtime `/model` switch) the conductor looks up the BOUND model's provider in
445
- * this map and, when present, binds a CLONE of the framework model with its
446
- * `baseUrl` swapped to that URL — so any server-tier model routes through the
447
- * quota-enforcing server while the session token (via {@link getApiKey})
448
- * authenticates it. A provider absent from the map keeps the direct path.
449
- */
450
- readonly gatewayBaseUrls?: Record<string, string>;
451
- /** Working directory the session is scoped to (defaults to process cwd). */
452
- readonly workspace?: string;
453
- /**
454
- * Directory to persist the transcript into. When set, the conductor backs its
455
- * {@link TranscriptStore} with a filesystem backend rooted here (one
456
- * `<sessionId>.ndjson` per session) so the conversation survives the process
457
- * and can be resumed. Absent (or when a `store` dep is injected) keeps the
458
- * default in-memory store — nothing is written to disk.
459
- */
460
- readonly sessionsDir?: string;
461
- /** Condense the transcript automatically when it nears the window (default on). */
462
- readonly autoCompact?: boolean;
463
- /**
464
- * Resolve the credential for a provider on each call. Threaded to the framework
465
- * `Agent`, which calls it per request so short-lived OAuth access tokens (e.g.
466
- * `openai-codex`) can be refreshed and providers with no env-var mapping still
467
- * authenticate. Returning `undefined` lets the framework fall back to its own
468
- * environment lookup. May be sync or async.
469
- */
470
- readonly getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;
471
- /**
472
- * The hard per-tool permission gate, threaded straight to the framework `Agent`.
473
- * The framework awaits it on the validated arguments immediately before each
474
- * tool runs and either proceeds (optionally with substituted input) or
475
- * short-circuits to an `isError` tool result.
476
- *
477
- * Supplied as a **factory** `(currentMode, requestApproval?) => CanUseToolFn`:
478
- * the conductor calls it once with a getter onto its OWN live permission mode,
479
- * so the gate it returns reads `permissionMode()` live — a
480
- * {@link SessionConductor.setPermissionMode} retargets later tool calls with no
481
- * agent rebuild. (A caller that does not care about the live mode can simply
482
- * ignore the getter and close over a fixed gate.)
483
- *
484
- * The OPTIONAL second argument is a stable {@link ApprovalResolver} delegate the
485
- * conductor owns: it forwards to whatever resolver was installed via
486
- * {@link SessionConductor.setApprovalResolver} at call time (and denies when none
487
- * is installed). An interactive front-end can therefore wire its approval overlay
488
- * AFTER the conductor (and its gate) are built — the factory just closes over the
489
- * delegate. A factory that ignores it keeps today's behavior.
490
- *
491
- * Optional everywhere: omit it and the framework allows every tool (today's
492
- * allow-all behavior).
493
- */
494
- readonly canUseTool?: (currentMode: () => PermissionMode, requestApproval?: ApprovalResolver) => CanUseToolFn;
495
- /**
496
- * The permission mode the session opens in. Seeds {@link SessionConductor.permissionMode};
497
- * defaults to `"default"` when absent. The mode is consulted live by the
498
- * {@link canUseTool} gate, so a later {@link SessionConductor.setPermissionMode}
499
- * changes subsequent tool calls without rebuilding the gate.
500
- */
501
- readonly permissionMode?: PermissionMode;
502
- /**
503
- * Directory the approved plan-mode plan is persisted into. When the model calls
504
- * `exit_plan_mode` and the user approves leaving plan mode, the conductor writes
505
- * the plan as a slug-named markdown file under `<plansDir>/plans/`. Absent keeps
506
- * the handshake (mode flip + context injection) but skips the disk write —
507
- * tests and headless probes can run the round-trip without a filesystem.
508
- */
509
- readonly plansDir?: string;
510
- /**
511
- * The per-session file-checkpoint store for rewind (#24), or `undefined` to run
512
- * without code checkpointing. When present, the conductor pins the active
513
- * transcript node on it (the head leaf at turn start) so a turn's file edits key
514
- * to the node that was active before the turn, and {@link SessionConductor.restoreCode}
515
- * delegates to it so the tree picker can revert the working tree.
516
- */
517
- readonly checkpoint?: CheckpointPort;
518
- }
519
- /**
520
- * What a manual {@link SessionConductor.condense} run amounted to — the honest
521
- * completion vocabulary `/compact` reports from (see the method doc).
522
- */
523
- export type CondenseOutcome = "condensed" | "nothing" | "cancelled" | "failed" | "busy";
524
- /**
525
- * The conductor of a single coding-agent session.
526
- *
527
- * It owns the framework `Agent`, threads persistence and auto-condense through
528
- * the turn loop, and exposes a small product API: submit input, subscribe to
529
- * the {@link SessionSignal} stream, abort the in-flight turn, read an immutable
530
- * {@link ConductorState} snapshot, resume a persisted session, and optionally
531
- * rotate the active model. This is the surface all three run modes drive.
532
- */
533
- export interface SessionConductor {
534
- /**
535
- * Submit user input as a new turn and run the agent to settle.
536
- *
537
- * Streams {@link SessionSignal}s to subscribers as the turn progresses and
538
- * resolves to the immutable {@link ConductorState} once the turn settles
539
- * (success or fault).
540
- *
541
- * When a turn is already in flight the input is **not** dropped: it is handed
542
- * to {@link enqueue} and run automatically as a later turn once the current one
543
- * settles. In that case `submit` resolves immediately with the current
544
- * snapshot rather than waiting for the queued turn.
545
- *
546
- * @param input the user message text for this turn
547
- */
548
- submit(input: string): Promise<ConductorState>;
549
- /**
550
- * Queue an input to run as a future turn. Used directly, or reached via
551
- * {@link submit} when the conductor is busy. Queued items drain in order after
552
- * the active turn settles, each running as its own turn. Emits a
553
- * `{ kind: "queue" }` signal so a UI can reflect the new depth.
554
- *
555
- * @param input the user message text to hold for a later turn
556
- * @param mode how it rejoins the conversation when drained (default `"followUp"`)
557
- */
558
- enqueue(input: string, mode?: QueueMode): void;
559
- /** How many inputs are currently waiting in the pending-input queue. */
560
- pendingCount(): number;
561
- /** A read-only view of the queued inputs, oldest first. */
562
- pendingInputs(): readonly QueuedInput[];
563
- /** Discard every queued input. Emits a `{ kind: "queue" }` signal. */
564
- clearQueue(): void;
565
- /**
566
- * Promote the NEWEST queued input to run immediately: the in-flight turn (if
567
- * any) is aborted — its work stops — while the rest of the queue is kept, and
568
- * the promoted input runs as the very next turn. The user-facing "run my new
569
- * message NOW" affordance for a long/stuck turn (issue #19), distinct from
570
- * {@link abort} (which stops everything and clears the queue). Returns `false`
571
- * when no input is queued.
572
- */
573
- steerNow(): boolean;
574
- /**
575
- * Remove and return the text of the most-recently queued input, or `undefined`
576
- * when the queue is empty. Lets a UI pop the last entry back into its prompt.
577
- */
578
- dequeueLast(): string | undefined;
579
- /**
580
- * The live transcript messages for the active branch.
581
- *
582
- * A read-through onto the wrapped agent's running message list — what the
583
- * interactive UI renders as the conversation. The returned array is the
584
- * current contents at call time; re-read to observe later turns.
585
- */
586
- messages(): readonly AgentMessage[];
587
- /**
588
- * The full framework {@link Model} object currently bound to the session, or
589
- * `undefined` when none could be resolved. Tracks the active selection across
590
- * {@link selectModel}/{@link cycleModel} changes.
591
- */
592
- model(): Model<any> | undefined;
593
- /** Whether a turn is currently in flight (guards re-entrant submit). */
594
- isBusy(): boolean;
595
- /**
596
- * The model catalog entries a picker lists, best-first. Derived from the
597
- * configured model matcher; returns `[]` when no matcher is wired in.
598
- */
599
- availableModels(): ModelCardRef[];
600
- /**
601
- * Bind a model by canonical id for subsequent turns. The companion of
602
- * {@link cycleModel}; both route through the same selection path.
603
- *
604
- * @param id canonical id of the model to switch to
605
- */
606
- selectModel(id: string): void;
607
- /**
608
- * Replace the server-tier gateway routing map and immediately re-bind the
609
- * currently selected model against it (without changing which model is
610
- * selected). Lets an interactive mid-session sign-in (see `/login` ->
611
- * "Indus Server") take effect right away: the gateway base-url map is
612
- * otherwise frozen at conductor construction, so a login that happens after
613
- * boot would silently never route the bound model through the gateway even
614
- * though the per-request key resolver already started vending the fresh
615
- * session token as the provider key.
616
- *
617
- * @param map provider id -> gateway base URL, as produced by
618
- * `resolveServerGatewayUrls` for the current vault/token state
619
- */
620
- updateGatewayBaseUrls(map: Record<string, string>): void;
621
- /**
622
- * Replace the agent's tool deck for subsequent turns.
623
- *
624
- * Used by `/mcp` to inject the tools of freshly-connected MCP servers into the
625
- * live session (and to drop them again on disconnect). The conductor merges the
626
- * passed list with its own seed deck (the built-in tools the session was
627
- * assembled with), so callers pass only the *extra* tools to add — never the
628
- * built-ins, which are preserved automatically. Pass `[]` to clear the extras
629
- * and fall back to the seed deck alone.
630
- *
631
- * @param tools the additional tools to layer over the seed deck
632
- */
633
- registerTools(tools: AgentTool[]): void;
634
- /**
635
- * Manually run the transcript-condense path (`/compact`) and report what
636
- * happened, so the caller can give honest feedback instead of announcing
637
- * "condensed" regardless:
638
- * - `"condensed"` — the branch shrank and was rebound (emits `compacted`).
639
- * - `"nothing"` — nothing older to fold (single-turn session, or already
640
- * compacted); the transcript is untouched.
641
- * - `"cancelled"` — {@link cancelCondense} fired mid-run; the digest was
642
- * discarded and the transcript is untouched.
643
- * - `"failed"` — the condense hook threw; a typed fault was emitted.
644
- * - `"busy"` — a turn is in flight; compact after it settles (or abort
645
- * it first).
646
- * While the condense runs, {@link submit} queues instead of racing it, and the
647
- * queue drains once the condense settles.
648
- */
649
- condense(): Promise<CondenseOutcome>;
650
- /**
651
- * Cancel an in-flight manual {@link condense} (the `/compact` Esc affordance).
652
- * The summarizer's result is discarded and the transcript stays untouched; a
653
- * no-op when no manual condense is running.
654
- */
655
- cancelCondense(): void;
656
- /**
657
- * Branch the transcript from a prior node. A new branch is opened whose parent
658
- * is `entryId`; the agent's message list is rebound to that branch's root→leaf
659
- * path. The conductor's head advances onto the chosen node.
660
- *
661
- * @param entryId the transcript node to branch from
662
- */
663
- fork(entryId: string): Promise<void>;
664
- /**
665
- * Move the active leaf to `nodeId`, rebuild that branch's root→leaf path, and
666
- * rebind the agent's message list to it. Used to walk between existing
667
- * branches without forking a new one.
668
- *
669
- * @param nodeId the transcript node to make the active leaf
670
- */
671
- navigateTree(nodeId: string): Promise<void>;
672
- /**
673
- * Roll the working tree back to a transcript node's file-checkpoint state
674
- * (rewind, #24). Reverts every file the node tracked to its pre-mutation content
675
- * (deleting files that were absent at that point). Additive and code-only: it
676
- * does NOT move the conversation head — pair it with {@link navigateTree}/{@link fork}
677
- * for a combined "restore code and conversation". A safe no-op when no checkpoint
678
- * store is wired or the node has no recorded snapshot.
679
- *
680
- * @param nodeId the transcript node whose file state to restore to
681
- * @returns the absolute paths that were restored (written or deleted)
682
- */
683
- restoreCode(nodeId: string): Promise<string[]>;
684
- /**
685
- * Whether the tree picker should offer "restore code" for a node — i.e. whether
686
- * the node has any recorded file-checkpoint snapshot. `false` when no checkpoint
687
- * store is wired or the node never mutated files, so the picker's restore option
688
- * is a safe no-op there.
689
- *
690
- * @param nodeId the transcript node to test
691
- */
692
- codeRestoreInfo(nodeId: string): Promise<{
693
- readonly canRestore: boolean;
694
- }>;
695
- /**
696
- * Run a shell command in the session workspace, returning its combined
697
- * stdout+stderr and exit code. Unless `opts.excludeFromContext` is set, the
698
- * output is recorded as a transcript note so it re-enters the agent's context.
699
- * Never throws: a spawn/exec failure resolves to a non-zero {@link BashOutcome}.
700
- *
701
- * @param command the shell command to execute
702
- * @param opts execution options
703
- */
704
- executeBash(command: string, opts?: ExecuteBashOptions): Promise<BashOutcome>;
705
- /** A point-in-time {@link SessionStats} tally for the active session. */
706
- stats(): SessionStats;
707
- /**
708
- * Render the session's cumulative cost + token usage as a human-readable,
709
- * multi-line report. Drives the `/cost` slash command without the caller
710
- * having to format the {@link SessionStats} figures itself.
711
- */
712
- costReport(): string;
713
- /** The reasoning effort currently applied to the session. */
714
- thinkingLevel(): ThinkingLevel;
715
- /**
716
- * Set the reasoning effort for subsequent turns. Applied to the agent when it
717
- * exposes a setter; otherwise stored and applied on the next model bind.
718
- *
719
- * @param level the reasoning effort to apply
720
- */
721
- setThinkingLevel(level: ThinkingLevel): void;
722
- /**
723
- * Advance the reasoning effort to the next level in the cycle, applying it, and
724
- * return the newly-selected level.
725
- */
726
- cycleThinkingLevel(): ThinkingLevel;
727
- /**
728
- * The permission mode currently in effect. The live `canUseTool` gate reads
729
- * this on every tool call, so the value reflects the most recent
730
- * {@link setPermissionMode}.
731
- */
732
- permissionMode(): PermissionMode;
733
- /**
734
- * Switch the permission mode for subsequent tool calls. The gate consults the
735
- * mode live (via a getter), so this takes effect on the next tool call with no
736
- * agent rebuild. A no-op-equivalent when no gate was wired (the conductor still
737
- * tracks the mode for the UI).
738
- *
739
- * @param mode the permission mode to apply
740
- */
741
- setPermissionMode(mode: PermissionMode): void;
742
- /**
743
- * Install (or clear) the host approval resolver an `ask` decision routes to.
744
- *
745
- * The `canUseTool` gate consults a STABLE delegate the conductor owns; this
746
- * method swaps the resolver behind that delegate, so an interactive front-end
747
- * can wire its approval overlay AFTER the conductor (and its gate) are built —
748
- * the exact post-mount install the React console needs. Passing `undefined`
749
- * clears it (an `ask` then deterministically denies, the non-interactive
750
- * default). A no-op-equivalent when no gate was wired; the resolver is simply
751
- * never consulted.
752
- *
753
- * @param resolver the resolver to consult on an `ask`, or `undefined` to clear
754
- */
755
- setApprovalResolver(resolver: ApprovalResolver | undefined): void;
756
- /**
757
- * Toggle plan mode on or off.
758
- *
759
- * Entering plan mode (`true`) captures the current mode as the pre-plan mode and
760
- * switches to `"plan"` (read-only — the gate blocks every mutating tool).
761
- * Leaving (`false`) restores the captured pre-plan mode (or `"default"` when none
762
- * was captured). Idempotent: toggling on while already in plan mode is a no-op,
763
- * and toggling off when not in plan mode restores/keeps `"default"`. Drives the
764
- * `/plan` command and the Shift+Tab toggle, and is the same path the conductor's
765
- * own `enter_plan_mode` / approved `exit_plan_mode` handshake uses.
766
- *
767
- * @param on `true` to enter plan mode, `false` to leave it
768
- * @returns the permission mode in effect after the toggle
769
- */
770
- togglePlanMode(on: boolean): PermissionMode;
771
- /**
772
- * Advance the permission mode to the NEXT mode in the fixed cycle and return the
773
- * new mode. The order is `default → acceptEdits → plan → bypass → (wrap)
774
- * default`; the `"bypassPermissions"` alias is folded to `"bypass"` when reading
775
- * the current mode so the cycle is stable.
776
- *
777
- * Built on top of {@link setPermissionMode}, so the live `canUseTool` gate (which
778
- * reads {@link permissionMode} on every call) picks the new mode up immediately
779
- * with no agent rebuild. Plan bookkeeping is preserved: ENTERING `"plan"` captures
780
- * the pre-plan mode exactly as {@link togglePlanMode} does, so a later round-trip
781
- * restores the prior mode; LEAVING `"plan"` (cycling `plan → bypass`) is a plain
782
- * mode change — it does NOT run the `exit_plan_mode` approval handshake, since a
783
- * manual cycle is not a plan exit. Drives the Shift+Tab cycle; {@link togglePlanMode}
784
- * remains the path `/plan` uses.
785
- *
786
- * @returns the permission mode in effect after the advance
787
- */
788
- cyclePermissionMode(): PermissionMode;
789
- /**
790
- * The mode captured when plan mode was last entered, restored on exit — or
791
- * `undefined` when not currently in (or paused from) plan mode. Exposed so a UI
792
- * (and the round-trip tests) can observe the Enter/Exit pairing.
793
- */
794
- prePlanMode(): PermissionMode | undefined;
795
- /** The human-readable session name, or `undefined` when none is set. */
796
- sessionName(): string | undefined;
797
- /**
798
- * Assign a human-readable name to the session.
799
- *
800
- * @param name the display name to store
801
- */
802
- setSessionName(name: string): void;
803
- /**
804
- * Register a handler for the {@link SessionSignal} stream.
805
- *
806
- * @param handler invoked for every emitted signal
807
- * @returns an unsubscribe function that removes the handler
808
- */
809
- subscribe(handler: SignalHandler): () => void;
810
- /** Cancel the in-flight turn, if any; emits an `aborted` fault signal. */
811
- abort(): void;
812
- /** Read an immutable snapshot of the current {@link ConductorState}. */
813
- snapshot(): ConductorState;
814
- /**
815
- * Restore a previously persisted session, replacing the current transcript
816
- * and rebinding the agent to the restored model/leaf.
817
- *
818
- * @param sessionId the persisted session to resume
819
- */
820
- resume(sessionId: string): Promise<void>;
821
- /**
822
- * Abandon the current conversation and start a fresh, empty session.
823
- *
824
- * Drops the agent's message history, opens a new session id (so later turns
825
- * persist separately, leaving the prior transcript intact on disk), zeroes the
826
- * usage tally, clears the pending-input queue and session name, and settles to
827
- * `idle`. Emits an `idle` signal so a subscribed UI re-renders the now-empty
828
- * conversation. This is what `/clear` (and `/new`) drive.
829
- */
830
- newSession(): Promise<void>;
831
- /**
832
- * Rotate the active model for subsequent turns. Optional: not every assembly
833
- * supports mid-session model changes.
834
- *
835
- * @param id canonical id of the model to switch to
836
- */
837
- cycleModel?(id: string): void;
838
- }