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,41 +0,0 @@
1
- /**
2
- * AgentsView — the drill-in sub-agent view, styled to the "IndusCode Saffron ·
3
- * Subagent View" design.
4
- *
5
- * Opened from the main screen (← on an empty prompt while sub-agents are
6
- * running), this replaces the transcript with a focused, navigable view of the
7
- * delegated sub-agents: ↑/↓ moves the selection through `main` + each sub-agent,
8
- * and the panel above the picker live-previews the selected sub-agent's activity
9
- * stream — its reasoning and the tools it is using, just like the main screen —
10
- * with a running clock and token count. Selecting `main` and pressing Enter (or
11
- * Esc) returns to the main session.
12
- *
13
- * It is fed entirely by props the surface already holds: the derived
14
- * {@link AgentRun}s plus the per-sub-agent live activity / token maps captured
15
- * from the task tool's streamed progress. Its own {@link useInput} owns the
16
- * keyboard while it is mounted (the surface gates its main handler off).
17
- */
18
- import { type InkThemeAdapter } from "indusagi/react-ink";
19
- import type { AgentRun } from "./BackgroundAgents";
20
- import type { ActivityLine } from "../../capability-deck/cards/task-card";
21
- /** What the {@link AgentsView} renders. */
22
- export interface AgentsViewProps {
23
- /** The framework adapter that turns token roles into terminal colours. */
24
- readonly theme: InkThemeAdapter;
25
- /** The delegated sub-agent runs (from `deriveAgentRuns`). */
26
- readonly runs: readonly AgentRun[];
27
- /** Live activity streams per run id (from the task tool's progress). */
28
- readonly activity: Readonly<Record<string, readonly ActivityLine[]>>;
29
- /** Live token spend per run id. */
30
- readonly tokens: Readonly<Record<string, number>>;
31
- /** Current epoch ms, for the run clock. Defaults to `Date.now()`. */
32
- readonly now?: number;
33
- /** Return to the main session. */
34
- readonly onExit: () => void;
35
- }
36
- /**
37
- * Render the drill-in agents view.
38
- *
39
- * @param props the theme, runs, live activity/token maps, and the exit callback
40
- */
41
- export declare function AgentsView({ theme, runs, activity, tokens, now, onExit }: AgentsViewProps): JSX.Element;
@@ -1,63 +0,0 @@
1
- /**
2
- * BackgroundAgents — the live sub-agent panel pinned below the input, styled to
3
- * the "IndusCode Saffron · Background Agents" design.
4
- *
5
- * When the primary agent delegates with the `task` tool, each sub-agent run is
6
- * surfaced here as a compact status row (a spinner/● dot, the agent profile name
7
- * in saffron, the objective in dim, and a running clock / done / failed status)
8
- * under a `● main` header — so a user watching several agents work sees them all
9
- * at a glance in the main screen instead of scrolling the transcript. The panel
10
- * shows only while at least one run is in flight and hides once they all settle
11
- * (their final reports remain inline in the transcript).
12
- *
13
- * The run list is derived purely from the conversation by {@link deriveAgentRuns}
14
- * (the `task` tool calls in the assistant messages, matched against their
15
- * `toolResult` messages for status), so the panel needs no extra session state —
16
- * it is a projection of `conductor.messages()`.
17
- */
18
- import { type InkThemeAdapter } from "indusagi/react-ink";
19
- import type { AgentMessage } from "indusagi/agent";
20
- /** The live status of one delegated sub-agent. */
21
- export type AgentRunStatus = "running" | "done" | "error";
22
- /** One delegated sub-agent run, projected from the conversation. */
23
- export interface AgentRun {
24
- /** The `task` tool-call id correlating the call with its result. */
25
- readonly id: string;
26
- /** The agent profile name (the `agent` arg), or "subagent" when unnamed. */
27
- readonly name: string;
28
- /** The delegated objective (the `objective` arg), shown as the description. */
29
- readonly objective: string;
30
- /** Whether the run is in flight, finished, or errored. */
31
- readonly status: AgentRunStatus;
32
- /** Epoch ms the delegating assistant message was stamped (for the run clock). */
33
- readonly startedAt: number;
34
- }
35
- /**
36
- * Derive the delegated sub-agent runs from the conversation.
37
- *
38
- * Walks the messages once: every `task` tool call in an assistant message
39
- * becomes a run (named by its `agent` arg, described by its `objective`), and a
40
- * later `toolResult` with the matching id resolves its status to done/error.
41
- * Runs with no result yet are "running". Pure and order-stable — the same
42
- * messages always yield the same list, oldest first.
43
- *
44
- * @param messages the live conversation (`conductor.messages()`)
45
- */
46
- export declare function deriveAgentRuns(messages: readonly AgentMessage[]): AgentRun[];
47
- /** What the {@link BackgroundAgents} renders. */
48
- export interface BackgroundAgentsProps {
49
- /** The framework adapter that turns token roles into terminal colours. */
50
- readonly theme: InkThemeAdapter;
51
- /** The derived sub-agent runs (from {@link deriveAgentRuns}). */
52
- readonly runs: readonly AgentRun[];
53
- /** Live token spend per run, keyed by run id (the task tool-call id). */
54
- readonly tokens?: Readonly<Record<string, number>>;
55
- /** Current epoch ms, for the run clock. Defaults to `Date.now()`. */
56
- readonly now?: number;
57
- }
58
- /**
59
- * Render the background-agents panel, or nothing when no run is in flight.
60
- *
61
- * @param props the theme, the derived runs, and the current time
62
- */
63
- export declare function BackgroundAgents({ theme, runs, tokens, now }: BackgroundAgentsProps): JSX.Element | null;
@@ -1,8 +0,0 @@
1
- /**
2
- * BackgroundAgents — pure derivation tests.
3
- *
4
- * Exercises {@link deriveAgentRuns} against hand-built conversations (no Ink):
5
- * `task` tool calls become runs, matched `toolResult` messages resolve their
6
- * status, non-task calls are ignored, and unnamed agents fall back to a label.
7
- */
8
- export {};
@@ -1,110 +0,0 @@
1
- /**
2
- * Banner — the "IndusCode Saffron" masthead the console renders above the
3
- * transcript.
4
- *
5
- * The startup chrome the surface mounts at the top of a session. Its loud
6
- * (default) mode has two presentations, switched by {@link BannerProps.started}:
7
- *
8
- * - **Welcome card** (fresh session, no messages yet): a bordered card in the
9
- * saffron brand look — a compact `● IndusCode v…` brand label, then two
10
- * columns (left: a personalized greeting above a small block-art robot
11
- * mascot and the bound model / working directory; right: a rotating "getting
12
- * started" tip and the "What's new" notes). The mascot expression and the
13
- * tip rotate per session (seeded once at mount and threaded in via
14
- * {@link BannerProps.variantSeed}), so a new session looks a little different
15
- * each time while staying deterministic for tests.
16
- * - **Startup & Chat masthead** (once the user has sent a message): the
17
- * `➜ dir git:(branch) indus` shell line, the block-letter "INDUS CODE"
18
- * wordmark, the `indus console v…` brand line, the welcome line, and a
19
- * bordered "Session" panel (model + cwd). The conversation itself is rendered
20
- * below the banner by the surface's `MessageList`.
21
- *
22
- * It reads nothing but its props, holds no state, and runs no effects — purely
23
- * presentational Ink primitives themed through the framework
24
- * {@link InkThemeAdapter}. The {@link BannerProps.quiet} or
25
- * {@link BannerProps.compact} flags collapse all of that to a single compact
26
- * header line, still carrying the welcome line, the notices, and a condensed
27
- * changelog so nothing important is silently dropped.
28
- */
29
- import { type InkThemeAdapter } from "indusagi/react-ink";
30
- import type { StartupChangelog, StartupMap, StartupNotice } from "../startup";
31
- /** What the {@link Banner} renders. */
32
- export interface BannerProps {
33
- /** The framework adapter that turns token roles into terminal colours. */
34
- readonly theme: InkThemeAdapter;
35
- /** Canonical id of the model bound to the session. */
36
- readonly modelId: string;
37
- /** Working directory the session is scoped to. */
38
- readonly workspace: string;
39
- /** The product version shown on the brand line (e.g. the package VERSION). */
40
- readonly version: string;
41
- /**
42
- * Whether the conversation has begun (the user has sent at least one message).
43
- * When `false` the loud banner is the fresh-session welcome card; when `true`
44
- * it becomes the Startup & Chat masthead (wordmark + Session panel) that sits
45
- * above the transcript. Has no effect in {@link quiet}/{@link compact} modes.
46
- */
47
- readonly started?: boolean;
48
- /** The active VCS branch (for the masthead shell line), or `null`/absent outside a repo. */
49
- readonly branch?: string | null;
50
- /** Whether to render the extra diagnostics line. */
51
- readonly verbose?: boolean;
52
- /**
53
- * When set, the welcome card is suppressed in favour of a single compact
54
- * header line. Wired from the verbose / quiet-startup flag.
55
- */
56
- readonly quiet?: boolean;
57
- /**
58
- * When set, the masthead auto-condenses to a single emblem + brand + model
59
- * line (the repeat-launch presentation). Distinct from {@link quiet}, which is
60
- * the manual suppression toggle; either collapses the banner, but `compact`
61
- * keeps the small emblem and the welcome line.
62
- */
63
- readonly compact?: boolean;
64
- /**
65
- * The signed-in account label, used for the personalized "Welcome back,
66
- * {name}!" line. Absent → the plain "Welcome back!" fallback is shown.
67
- */
68
- readonly name?: string;
69
- /**
70
- * Opt-in static colour-sweep flourish (legacy; accepted for call-site
71
- * compatibility). The saffron welcome card paints from the theme roles and
72
- * does not consume this flag.
73
- */
74
- readonly sweep?: boolean;
75
- /**
76
- * The per-session variation seed. Selects which mascot expression + "getting
77
- * started" tip the card shows; the same seed always yields the same pair, so a
78
- * test pins an exact variant. Absent → the first (seed 0) variant.
79
- */
80
- readonly variantSeed?: number;
81
- /**
82
- * Optional override for the "What's new" notes (e.g. sourced from a live
83
- * changelog). Absent → the shipped {@link WHATS_NEW} copy.
84
- */
85
- readonly whatsNew?: readonly string[];
86
- /**
87
- * The gathered session resources (context docs, skills, prompts). Reserved:
88
- * the saffron welcome card shows quick-action chips in place of the old
89
- * "Startup Map" panel, so this is accepted for call-site compatibility (and to
90
- * keep the gathering machinery wired) but not rendered in the card.
91
- */
92
- readonly startup?: StartupMap;
93
- /** Out-of-band lines drawn above the card (errors, warnings, info). */
94
- readonly notices?: readonly StartupNotice[];
95
- /** The changelog survey rendered as a "What is new" block on a version bump. */
96
- readonly changelog?: StartupChangelog;
97
- }
98
- /**
99
- * Render the console masthead.
100
- *
101
- * In the default (loud) mode this is the saffron welcome card: a `● IndusCode
102
- * v…` brand label and a two-column body (greeting + mascot + model/cwd on the
103
- * left, a rotating tip + the "What's new" notes on the right). The
104
- * {@link BannerProps.quiet} or {@link BannerProps.compact} flags
105
- * collapse all of that to a single compact header line, still carrying the
106
- * welcome line, the notices, and a condensed changelog.
107
- *
108
- * @param props the brand/version context, session facts, and startup chrome
109
- */
110
- export declare function Banner({ theme, modelId, workspace, version, started, branch, quiet, compact, name, variantSeed, whatsNew, notices, changelog, }: BannerProps): JSX.Element;
@@ -1,37 +0,0 @@
1
- /**
2
- * Composer — the prompt-input surface (the renamed input row).
3
- *
4
- * Presentational only: it renders the live buffer with a visible caret, a busy
5
- * affordance while a turn is in flight, and — when the parent has computed one —
6
- * a completion window of slash/path {@link Suggestion}s with the highlighted
7
- * entry marked. All key handling lives in the parent {@link TerminalConsole}'s
8
- * `useInput` handler (which composes the pure keymap / paste / completion
9
- * modules); the Composer just draws the state it is handed.
10
- *
11
- * The caret is drawn by splitting the buffer at the caret offset and inverting
12
- * the character under it (or a trailing space at end-of-buffer), so the surface
13
- * needs no terminal cursor control.
14
- */
15
- import type { InkThemeAdapter } from "indusagi/react-ink";
16
- import type { Suggestion } from "../input";
17
- /** What the {@link Composer} renders. */
18
- export interface ComposerProps {
19
- /** The framework adapter that turns token roles into terminal colours. */
20
- readonly theme: InkThemeAdapter;
21
- /** The live composer buffer. */
22
- readonly buffer: string;
23
- /** Caret offset within {@link buffer}, in characters. */
24
- readonly caret: number;
25
- /** Whether a turn is in flight (input is visually disabled). */
26
- readonly busy: boolean;
27
- /** The completion candidates to show, or empty for no window. */
28
- readonly suggestions: readonly Suggestion[];
29
- /** Index of the highlighted suggestion within {@link suggestions}. */
30
- readonly highlight: number;
31
- }
32
- /**
33
- * Render the prompt-input row plus any completion window.
34
- *
35
- * @param props the buffer/caret/suggestion state to display
36
- */
37
- export declare function Composer({ theme, buffer, caret, busy, suggestions, highlight, }: ComposerProps): JSX.Element;
@@ -1,42 +0,0 @@
1
- /**
2
- * StatusBar — the bottom chrome strip of the console.
3
- *
4
- * Composes the framework's `StatusLine` (the transient toast row) above its
5
- * `Footer` (the persistent session/usage strip), both fed from a projected
6
- * {@link SessionSnapshot}. The console owns no rendering of its own here — it
7
- * threads the resolved theme adapter and the current snapshot/status into the
8
- * framework components, which do the layout. Purely presentational.
9
- *
10
- * (Renamed surface: the console's status strip.)
11
- */
12
- import { type InkThemeAdapter, type SessionSnapshot, type StatusMessage } from "indusagi/react-ink";
13
- import type { PermissionMode } from "../../settings";
14
- /** What the {@link StatusBar} renders. */
15
- export interface StatusBarProps {
16
- /** The framework adapter that turns token roles into terminal colours. */
17
- readonly theme: InkThemeAdapter;
18
- /** The projected session snapshot the framework strips read. */
19
- readonly snapshot: SessionSnapshot;
20
- /** The active VCS branch, or `null` when not in a repo. */
21
- readonly branch: string | null;
22
- /** How many auth providers are available (shown in the footer). */
23
- readonly providerCount: number;
24
- /** The transient status toast, when one is showing. */
25
- readonly status?: StatusMessage;
26
- /**
27
- * The active permission mode. When supplied, a small badge is rendered above the
28
- * footer (parallel to the transient status toast) so the user can see at a glance
29
- * which of the four cycled modes is live: `default` (tools prompt as usual),
30
- * `acceptEdits` (edits auto-approved), `plan` (mutating tools blocked), or
31
- * `bypass` (every tool auto-allowed — drawn in an alert colour). The
32
- * `bypassPermissions` alias renders as `bypass`. Omitted renders nothing extra.
33
- */
34
- readonly permissionMode?: PermissionMode;
35
- }
36
- /**
37
- * Render the toast row above the footer strip, plus an optional permission-mode
38
- * badge when a non-default mode is active.
39
- *
40
- * @param props the snapshot + status (+ optional permission mode) to display
41
- */
42
- export declare function StatusBar({ theme, snapshot, branch, providerCount, status, permissionMode, }: StatusBarProps): JSX.Element;
@@ -1,27 +0,0 @@
1
- /**
2
- * TerminalConsole — the top-level Ink application for the interactive console.
3
- *
4
- * This is the surface the host process renders to drive a session from a live
5
- * terminal. It owns one {@link consoleReducer} store, subscribes to the
6
- * conductor's {@link SessionSignal} stream and projects each signal into reducer
7
- * events (so the transcript view grows as the agent streams), renders the
8
- * framework `MessageList` / `Footer` / `StatusLine` plus the console's own
9
- * {@link Composer} / {@link StatusBar} / {@link Banner}, and translates raw key
10
- * events — through the pure keymap / paste / completion modules — into reducer
11
- * dispatches and conductor calls.
12
- *
13
- * The component is deliberately thin: every *decision* lives in a pure module
14
- * (the reducer, the keymap, the slash resolver, the completion source, the paste
15
- * coalescer). The surface holds only the live values those pure functions need
16
- * carried between keystrokes — the chord latch, the paste vault, the highlighted
17
- * suggestion index — and the timers, and it wires events in and renders state
18
- * out. Nothing here parses keys or mutates state inline.
19
- *
20
- * Hooks note: `useReducer` / `useRef` / `useCallback` are obtained from the
21
- * default React export of `indusagi/react-host` (only `useState`/`useEffect`/
22
- * `useMemo` are named exports there). `Box` / `Text` / `useInput` come from
23
- * `indusagi/react-host/ink`; the message/footer/dialog components from
24
- * `indusagi/react-ink`.
25
- */
26
- import type { ConsoleProps } from "../contract";
27
- export declare function TerminalConsole(props: ConsoleProps): JSX.Element;
@@ -1,44 +0,0 @@
1
- /**
2
- * WorkingIndicator — the live "agent is working" affordance.
3
- *
4
- * While a turn is in flight (`busy`) this draws an animated braille spinner, a
5
- * label, an elapsed-seconds clock, and an "esc to interrupt" hint. The label is
6
- * a rotating whimsical word (changing every few seconds, induscode-style) for
7
- * the general thinking/streaming case, and a concrete phase label while the
8
- * agent runs tools or compacts context.
9
- *
10
- * It renders nothing when idle, and self-drives its animation via a short
11
- * interval that ticks ONLY while busy (torn down the moment `busy` clears), so an
12
- * idle console does no spinner work. It is a sibling row above the
13
- * {@link Composer} and does NOT consume the sticky status toast — so a previous
14
- * toast (e.g. the permission-mode line) can never mask that the agent is working.
15
- */
16
- import type { InkThemeAdapter } from "indusagi/react-ink";
17
- /**
18
- * The rotating "thinking" words shown while the agent reasons/streams. Whimsical
19
- * present participles, in the spirit of induscode's spinner — purely cosmetic.
20
- */
21
- export declare const WORKING_WORDS: readonly ["Cogitating", "Pondering", "Noodling", "Simmering", "Brewing", "Percolating", "Conjuring", "Tinkering", "Wrangling", "Synthesizing", "Computing", "Musing", "Scheming", "Hatching", "Whirring", "Crunching", "Spelunking", "Untangling", "Marinating", "Ruminating", "Architecting", "Finagling", "Concocting", "Deliberating", "Orchestrating", "Calibrating", "Channeling", "Vibing", "Forging", "Assembling"];
22
- /** Pick a working word by (wrapping, non-negative) index. Exported for testing. */
23
- export declare function pickWord(index: number): string;
24
- /** What the {@link WorkingIndicator} renders. */
25
- export interface WorkingIndicatorProps {
26
- /** The framework adapter that turns token roles into terminal colours. */
27
- readonly theme: InkThemeAdapter;
28
- /** Whether a turn is in flight. When false the indicator renders nothing. */
29
- readonly busy: boolean;
30
- /** The conductor snapshot phase, used to pick a concrete label when relevant. */
31
- readonly phase?: string;
32
- }
33
- /**
34
- * The concrete label for the phases where a specific word is more useful than a
35
- * whimsical one. Returns null for the general thinking/streaming case (the caller
36
- * then shows a rotating {@link WORKING_WORDS} word instead). Exported for testing.
37
- */
38
- export declare function phaseLabel(phase: string | undefined): string | null;
39
- /**
40
- * Render the animated working row, or nothing when idle.
41
- *
42
- * @param props the theme, the busy flag, and the snapshot phase
43
- */
44
- export declare function WorkingIndicator({ theme, busy, phase, }: WorkingIndicatorProps): JSX.Element | null;
@@ -1,9 +0,0 @@
1
- /**
2
- * WorkingIndicator — unit tests for the pure label/word logic.
3
- *
4
- * The animated render is driven by an Ink-only timer that is impractical to
5
- * assert headlessly; the load-bearing pure logic is {@link phaseLabel} (concrete
6
- * labels for tool/compaction phases) and {@link pickWord} (the rotating whimsical
7
- * word for the general thinking case).
8
- */
9
- export {};
@@ -1,55 +0,0 @@
1
- /**
2
- * Banner colour-sweep helpers — the pure, render-agnostic maths behind the
3
- * optional startup flourish (roadmap #14) and the personalized welcome line
4
- * (#7).
5
- *
6
- * Two concerns, no React or Ink, no I/O, no state:
7
- *
8
- * - {@link rowGradient} computes a *frozen* (single-pass, no animation timer)
9
- * colour for one wordmark row by lerping between two palette hexes across
10
- * the block's rows. The banner paints row `i` of `n` with this colour when
11
- * the opt-in sweep is on; off, the wordmark stays a flat accent. Because it
12
- * takes no clock and never schedules a frame, it is reduced-motion safe by
13
- * construction — the suppression decision lives at the call site, which
14
- * simply does not ask for a gradient when motion is reduced.
15
- *
16
- * - {@link welcomeLine} formats the "Welcome back{, name}!" greeting from the
17
- * signed-in account label, with a length guard and a name-less fallback, so
18
- * the banner and its tests share one formatter rather than re-deriving the
19
- * string.
20
- *
21
- * Everything here is referentially transparent: same inputs → same output.
22
- */
23
- /**
24
- * Format the personalized welcome greeting.
25
- *
26
- * Returns `"Welcome back, {name}!"` for a usable name, and the plain
27
- * `"Welcome back!"` fallback when the name is absent, blank, or too long to read
28
- * as a name. The name is trimmed of surrounding whitespace before the checks so
29
- * a padded label does not slip past the guards.
30
- *
31
- * @param name the signed-in account label, if one is known
32
- * @returns the greeting string (never the tag markup — plain text)
33
- */
34
- export declare function welcomeLine(name?: string): string;
35
- /**
36
- * The frozen sweep colour for one wordmark row.
37
- *
38
- * Lerps from `primaryHex` (the first row) to `secondaryHex` (the last row)
39
- * across the `rowCount` rows of the block, returning the colour for row
40
- * `rowIndex` as a `#rrggbb` hex string. A single-row block pins to the primary;
41
- * the endpoints are exact (row 0 = primary, row n-1 = secondary). If either hex
42
- * cannot be parsed, the corresponding raw input hex is returned so the banner
43
- * still gets a usable colour string rather than nothing.
44
- *
45
- * This computes a *static* gradient — there is no timer, no frame loop, no
46
- * clock. The whole sweep is laid down in the one render pass, which is exactly
47
- * why it is safe under reduced-motion: the flourish is colour, not movement.
48
- *
49
- * @param rowIndex the zero-based row being painted
50
- * @param rowCount the total number of rows in the wordmark block
51
- * @param primaryHex the colour of the first row (e.g. the accent)
52
- * @param secondaryHex the colour of the last row (e.g. the secondary accent)
53
- * @returns a `#rrggbb` hex string (or a raw input hex when one is unparseable)
54
- */
55
- export declare function rowGradient(rowIndex: number, rowCount: number, primaryHex: string, secondaryHex: string): string;
@@ -1,9 +0,0 @@
1
- /**
2
- * Banner colour-sweep helpers — pure behavioural tests.
3
- *
4
- * These exercise the render-agnostic maths behind the masthead flourish without
5
- * mounting Ink: the welcome-line formatter (#7) and the frozen colour-sweep
6
- * gradient (#14). Both are referentially transparent, so the assertions are
7
- * exact.
8
- */
9
- export {};
@@ -1,115 +0,0 @@
1
- /**
2
- * Welcome-card content & per-session variation — the pure data behind the
3
- * "IndusCode Saffron" startup card (the boxed masthead the {@link Banner} draws
4
- * in its loud mode).
5
- *
6
- * This module holds *no* React or Ink: it is the render-agnostic source of the
7
- * card's rotating mascot, the rotating "getting started" tip, the static
8
- * "what's new" notes, the slash chips, and the small block-art robot mascot
9
- * geometry. The banner reads these and paints them through the theme adapter;
10
- * the geometry is returned as tone-tagged {@link MascotSegment}s so the banner
11
- * maps a tone → a colour role without re-deriving the layout.
12
- *
13
- * Per-session freshness ("every new session the welcome looks a little
14
- * different") is a *pure* selection: {@link pickWelcomeVariant} maps an integer
15
- * seed onto one mascot + one tip deterministically, so a test pins an exact
16
- * variant while the live surface seeds it once at mount from
17
- * {@link randomWelcomeSeed}. Nothing here reads a clock or mutates state — same
18
- * seed in, same variant out.
19
- */
20
- /**
21
- * One robot-mascot face: the two eye glyphs and the three-cell mouth.
22
- *
23
- * The face is drawn into a fixed nine-cell-wide rounded head (see
24
- * {@link mascotRows}); only the eyes and mouth change between variants, so a
25
- * face is just those glyphs plus a human-readable key for tests/logs. Each eye
26
- * is exactly one display cell and the mouth exactly three so every face packs
27
- * into the same head outline without shifting the columns.
28
- */
29
- export interface MascotFace {
30
- /** Stable identifier for the expression (for tests and selection logs). */
31
- readonly key: string;
32
- /** The left/right eye glyphs (one display cell each). */
33
- readonly eyes: readonly [string, string];
34
- /** The three-cell mouth glyph row. */
35
- readonly mouth: string;
36
- }
37
- /**
38
- * The rotating mascot expressions, in selection order.
39
- *
40
- * Each is the same rounded saffron head with dark eyes and a teal mouth — the
41
- * expression is the only thing that changes session to session.
42
- */
43
- export declare const MASCOTS: readonly MascotFace[];
44
- /** A drawn cell's colour intent, mapped to a theme role by the banner. */
45
- export type MascotTone = "head" | "eye" | "mouth" | "feet";
46
- /** One painted span of a mascot row: literal text plus its colour intent. */
47
- export interface MascotSegment {
48
- /** The literal glyphs to draw. */
49
- readonly text: string;
50
- /** Which colour role the banner paints this span in. */
51
- readonly tone: MascotTone;
52
- }
53
- /**
54
- * Lay a {@link MascotFace} out into its drawable rows.
55
- *
56
- * Returns one array of {@link MascotSegment}s per terminal row of the mascot — a
57
- * five-row rounded head (top, eyes, mouth, base, feet). The head outline is the
58
- * `head` tone, the eyes the `eye` tone, the mouth the `mouth` tone, and the feet
59
- * the `feet` tone; the banner resolves each tone to a concrete colour. Every row
60
- * is the same nine-cell width (the feet row is centred under it), so the column
61
- * stays rectangular whichever expression is chosen.
62
- *
63
- * @param face the expression to lay out
64
- */
65
- export declare function mascotRows(face: MascotFace): readonly (readonly MascotSegment[])[];
66
- /**
67
- * The rotating "Tips for getting started" lines.
68
- *
69
- * One is shown per session (chosen by {@link pickWelcomeVariant}); the pool is
70
- * ordinary onboarding guidance so a returning user sees a different nudge each
71
- * launch rather than the same line forever.
72
- */
73
- export declare const TIPS: readonly string[];
74
- /**
75
- * The static "What's new" notes shown in the card's right column.
76
- *
77
- * These are stable per release (the banner can override them from a live
78
- * changelog); they describe the most recent user-facing changes.
79
- */
80
- export declare const WHATS_NEW: readonly string[];
81
- /** The chosen per-session presentation: one mascot face and one tip line. */
82
- export interface WelcomeVariant {
83
- /** The mascot expression to draw this session. */
84
- readonly mascot: MascotFace;
85
- /** The "getting started" tip to show this session. */
86
- readonly tip: string;
87
- }
88
- /**
89
- * Pick the welcome card's mascot + tip for a session seed.
90
- *
91
- * Pure and total: the same seed always yields the same variant, and any integer
92
- * (including a negative one) lands on a valid mascot and tip. The mascot and the
93
- * tip are advanced by different strides of the seed so they do not move in
94
- * lock-step — two nearby seeds vary both independently.
95
- *
96
- * @param seed the per-session seed (e.g. from {@link randomWelcomeSeed})
97
- */
98
- export declare function pickWelcomeVariant(seed: number): WelcomeVariant;
99
- /**
100
- * The PINNED welcome-card variant seed. The card no longer rotates per session
101
- * (one stable brand look): seeded with this, {@link pickWelcomeVariant} always
102
- * resolves to the clean "focus" mascot (`MASCOTS[0]` — `● ●` eyes, flat `───`
103
- * mouth) + the Shift+Tab tip (`TIPS[2]`). (`12 % MASCOTS.length === 0` → focus;
104
- * `Math.trunc(12 / MASCOTS.length) % TIPS.length === 2` → the Shift+Tab tip.) Swap
105
- * the mount back to {@link randomWelcomeSeed} to restore per-session rotation.
106
- */
107
- export declare const PINNED_WELCOME_SEED = 12;
108
- /**
109
- * Mint a fresh seed for the current session.
110
- *
111
- * Impure by design (it reads the RNG), so the live surface calls it *once* at
112
- * mount and threads the result into the otherwise-pure banner. Tests never call
113
- * this — they pass a fixed seed to {@link pickWelcomeVariant} instead.
114
- */
115
- export declare function randomWelcomeSeed(): number;
@@ -1,9 +0,0 @@
1
- /**
2
- * Welcome-card content & variation — pure behavioural tests.
3
- *
4
- * These exercise the render-agnostic data behind the saffron welcome card
5
- * without mounting Ink: the per-session variant selection (deterministic,
6
- * total, independent strides) and the mascot geometry (rectangular, tone-tagged,
7
- * expression-driven).
8
- */
9
- export {};
@@ -1,19 +0,0 @@
1
- /**
2
- * Console subsystem — unit tests over the PURE modules.
3
- *
4
- * The interactive surface itself (the Ink mount) is verified by eye; these tests
5
- * pin the *decisions* that live in the pure, dependency-free modules the surface
6
- * composes:
7
- *
8
- * 1. the reducer transitions (transcript append, busy toggle, theme switch);
9
- * 2. the theme having both schemes and an OWN, re-derived accent palette
10
- * (no forbidden upstream hex appears);
11
- * 3. slash resolution matching `/model` and `/composio` and parsing args;
12
- * 4. the keymap mapping Enter / Ctrl-C to the right console intent;
13
- * 5. paste coalescing batching a large clipboard burst behind a marker;
14
- * 6. completion suggesting slash names and file paths.
15
- *
16
- * Everything under test is a plain function over plain data — no Ink, no timers,
17
- * no conductor runtime — so the suite needs no React host.
18
- */
19
- export {};