indusagi-coding-agent 0.2.5 → 0.2.9

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 (224) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +9 -5
  3. package/dist/entry.js +14267 -24282
  4. package/dist/guardrails.js +924 -7867
  5. package/dist/index.js +13706 -23775
  6. package/package.json +3 -2
  7. package/src/_decls/entry.ts +18 -0
  8. package/src/_decls/guardrails.ts +35 -0
  9. package/src/_decls/index.ts +26 -0
  10. package/src/addons/contract.ts +236 -0
  11. package/src/addons/dispatch/event-dispatcher.ts +164 -0
  12. package/src/addons/dispatch/index.ts +25 -0
  13. package/src/addons/dispatch/tool-interceptor.ts +208 -0
  14. package/src/addons/host.ts +225 -0
  15. package/src/addons/index.ts +112 -0
  16. package/src/addons/manifest.ts +158 -0
  17. package/src/addons/sandbox.ts +170 -0
  18. package/src/addons/surface.ts +78 -0
  19. package/src/boot/auth-vault.ts +195 -0
  20. package/src/boot/boot.ts +138 -0
  21. package/src/boot/contract.ts +238 -0
  22. package/src/boot/heap.ts +59 -0
  23. package/src/boot/index.ts +28 -0
  24. package/src/boot/invocation.ts +93 -0
  25. package/src/boot/runners/addon-wiring.ts +153 -0
  26. package/src/boot/runners/checkpoint.ts +169 -0
  27. package/src/boot/runners/delegate-runner.ts +294 -0
  28. package/src/boot/runners/index.ts +13 -0
  29. package/src/boot/runners/link-runner.ts +45 -0
  30. package/src/boot/runners/memdir.ts +168 -0
  31. package/src/boot/runners/oneshot-runner.ts +58 -0
  32. package/src/boot/runners/read-state.ts +90 -0
  33. package/src/boot/runners/registry.ts +42 -0
  34. package/src/boot/runners/repl-runner.ts +143 -0
  35. package/src/boot/runners/server-mode.ts +121 -0
  36. package/src/boot/runners/session.ts +641 -0
  37. package/src/boot/server-token.ts +148 -0
  38. package/src/boot/stages.ts +167 -0
  39. package/src/boot/upgrade/apply.ts +94 -0
  40. package/src/boot/upgrade/index.ts +13 -0
  41. package/src/boot/upgrade/upgrades.ts +289 -0
  42. package/src/briefing/compose.ts +150 -0
  43. package/src/briefing/context-docs.ts +19 -0
  44. package/src/briefing/contract.ts +717 -0
  45. package/src/briefing/index.ts +31 -0
  46. package/src/briefing/macros.ts +97 -0
  47. package/src/briefing/skills.ts +47 -0
  48. package/src/capability-deck/bridge-ledger/index.ts +27 -0
  49. package/src/capability-deck/bridge-ledger/key.ts +67 -0
  50. package/src/capability-deck/bridge-ledger/ledger.ts +131 -0
  51. package/src/capability-deck/bridge-ledger/network.ts +117 -0
  52. package/src/capability-deck/builtin-bridge.ts +312 -0
  53. package/src/capability-deck/cards/bg-process-card.ts +335 -0
  54. package/src/capability-deck/cards/index.ts +115 -0
  55. package/src/capability-deck/cards/memory-card.ts +146 -0
  56. package/src/capability-deck/cards/plan-file.ts +97 -0
  57. package/src/capability-deck/cards/plan-tools.ts +185 -0
  58. package/src/capability-deck/cards/saas-card.ts +183 -0
  59. package/src/capability-deck/cards/task-card.ts +207 -0
  60. package/src/capability-deck/cards/todo-card.ts +168 -0
  61. package/src/capability-deck/cards/workflow-card.ts +247 -0
  62. package/src/capability-deck/contract.ts +388 -0
  63. package/src/capability-deck/index.ts +48 -0
  64. package/src/capability-deck/manifest.ts +109 -0
  65. package/src/capability-deck/provision.ts +169 -0
  66. package/src/channels/contract.ts +191 -0
  67. package/src/channels/framer.ts +50 -0
  68. package/src/channels/index.ts +101 -0
  69. package/src/channels/link/dialog.ts +129 -0
  70. package/src/channels/link/driver.ts +190 -0
  71. package/src/channels/link/index.ts +34 -0
  72. package/src/channels/link/server.ts +134 -0
  73. package/src/channels/oneshot.ts +90 -0
  74. package/src/channels/ops.ts +65 -0
  75. package/src/channels/session-ops.ts +81 -0
  76. package/src/conductor/bash-guard.ts +599 -0
  77. package/src/conductor/catalog/catalog.ts +116 -0
  78. package/src/conductor/catalog/index.ts +8 -0
  79. package/src/conductor/catalog/matcher.ts +134 -0
  80. package/src/conductor/conductor.ts +234 -0
  81. package/src/conductor/contract.ts +842 -0
  82. package/src/conductor/diagnostics.ts +227 -0
  83. package/src/conductor/index.ts +33 -0
  84. package/src/conductor/permissions.ts +588 -0
  85. package/src/conductor/quota-error.ts +49 -0
  86. package/src/conductor/signal-hub/hub.ts +46 -0
  87. package/src/conductor/signal-hub/index.ts +2 -0
  88. package/src/conductor/signal-hub/translate.test.ts +81 -0
  89. package/src/conductor/signal-hub/translate.ts +74 -0
  90. package/src/conductor/skill-parse/index.ts +2 -0
  91. package/src/conductor/skill-parse/parse.ts +108 -0
  92. package/src/conductor/transcript-store/index.ts +22 -0
  93. package/src/conductor/transcript-store/serialize.ts +116 -0
  94. package/src/conductor/transcript-store/store.ts +205 -0
  95. package/src/console/auth-status.ts +56 -0
  96. package/src/console/components/AgentsView.ts +165 -0
  97. package/src/console/components/BackgroundAgents.ts +155 -0
  98. package/src/console/components/Banner.ts +334 -0
  99. package/src/console/components/Composer.ts +94 -0
  100. package/src/console/components/StatusBar.ts +49 -0
  101. package/src/console/components/TerminalConsole.ts +1090 -0
  102. package/src/console/components/WorkingIndicator.ts +98 -0
  103. package/src/console/components/banner-sweep.ts +24 -0
  104. package/src/console/components/welcome.ts +74 -0
  105. package/src/console/contract.ts +630 -0
  106. package/src/console/index.ts +34 -0
  107. package/src/console/input/complete.ts +127 -0
  108. package/src/console/input/dir-reader.ts +34 -0
  109. package/src/console/input/index.ts +23 -0
  110. package/src/console/input/keymap.ts +159 -0
  111. package/src/console/input/paste.ts +104 -0
  112. package/src/console/mount.ts +56 -0
  113. package/src/console/overlays/approval-queue.ts +57 -0
  114. package/src/console/overlays/approval.ts +130 -0
  115. package/src/console/overlays/auth.ts +342 -0
  116. package/src/console/overlays/boards.ts +308 -0
  117. package/src/console/overlays/host.ts +36 -0
  118. package/src/console/overlays/index.ts +26 -0
  119. package/src/console/overlays/pickers.ts +258 -0
  120. package/src/console/overlays/sessions.ts +190 -0
  121. package/src/console/reducer.ts +182 -0
  122. package/src/console/slash/builtins.ts +81 -0
  123. package/src/console/slash/commands/dynamic.ts +83 -0
  124. package/src/console/slash/commands/integrations.ts +695 -0
  125. package/src/console/slash/commands/shared.ts +75 -0
  126. package/src/console/slash/commands/transcript.ts +263 -0
  127. package/src/console/slash/commands/workbench.ts +246 -0
  128. package/src/console/slash/index.ts +15 -0
  129. package/src/console/slash/registry.ts +70 -0
  130. package/src/console/slash/resolve.ts +63 -0
  131. package/src/console/startup.ts +209 -0
  132. package/src/console/theme/adapter.ts +45 -0
  133. package/src/console/theme/index.ts +7 -0
  134. package/src/console/theme/palette.ts +68 -0
  135. package/src/console/theme/resolve.ts +39 -0
  136. package/src/console/theme/tokens.ts +71 -0
  137. package/src/entry.ts +55 -0
  138. package/src/guardrails.ts +37 -0
  139. package/src/index.ts +18 -0
  140. package/src/insight/channel.ts +88 -0
  141. package/src/insight/contract.ts +185 -0
  142. package/src/insight/index.ts +110 -0
  143. package/src/insight/recorder.ts +213 -0
  144. package/src/insight/redaction.ts +157 -0
  145. package/src/insight/replay.ts +158 -0
  146. package/src/insight/sampling.ts +70 -0
  147. package/src/insight/serialize.ts +50 -0
  148. package/src/insight/sinks/console.ts +64 -0
  149. package/src/insight/sinks/file.ts +40 -0
  150. package/src/insight/sinks/index.ts +24 -0
  151. package/src/insight/sinks/stream.ts +54 -0
  152. package/src/integrations/sarvam/attach.ts +239 -0
  153. package/src/integrations/sarvam/config.ts +156 -0
  154. package/src/integrations/sarvam/index.ts +25 -0
  155. package/src/integrations/sarvam/sarvam.test.ts +60 -0
  156. package/src/integrations/sarvam/types.ts +27 -0
  157. package/src/integrations/zoho/attach.ts +342 -0
  158. package/src/integrations/zoho/config.ts +125 -0
  159. package/src/integrations/zoho/index.ts +27 -0
  160. package/src/integrations/zoho/types.ts +21 -0
  161. package/src/integrations/zoho/zoho.test.ts +50 -0
  162. package/src/kit/clipboard-image.ts +107 -0
  163. package/src/kit/external-editor.ts +48 -0
  164. package/src/kit/image.ts +59 -0
  165. package/src/kit/index.ts +51 -0
  166. package/src/kit/shell.ts +19 -0
  167. package/src/kit/tool-fetch.ts +85 -0
  168. package/src/launch/catalog.ts +148 -0
  169. package/src/launch/contract.ts +187 -0
  170. package/src/launch/credentials.ts +625 -0
  171. package/src/launch/index.ts +98 -0
  172. package/src/launch/invocation/attachments.ts +179 -0
  173. package/src/launch/invocation/flags.ts +196 -0
  174. package/src/launch/invocation/index.ts +25 -0
  175. package/src/launch/invocation/read.ts +260 -0
  176. package/src/launch/invocation/usage.ts +67 -0
  177. package/src/launch/login.ts +324 -0
  178. package/src/launch/oauth.test.ts +18 -0
  179. package/src/launch/oauth.ts +203 -0
  180. package/src/launch/packages.ts +194 -0
  181. package/src/launch/pickers.ts +189 -0
  182. package/src/runtime-bridge/bridges/_drive.ts +96 -0
  183. package/src/runtime-bridge/bridges/builtins.ts +68 -0
  184. package/src/runtime-bridge/bridges/claude-cli.ts +123 -0
  185. package/src/runtime-bridge/bridges/codex-cli.ts +142 -0
  186. package/src/runtime-bridge/bridges/index.ts +33 -0
  187. package/src/runtime-bridge/bridges/indusagi-cli.ts +155 -0
  188. package/src/runtime-bridge/broker.ts +227 -0
  189. package/src/runtime-bridge/contract.ts +122 -0
  190. package/src/runtime-bridge/index.ts +79 -0
  191. package/src/runtime-bridge/sink.ts +180 -0
  192. package/src/sessions/contract.ts +81 -0
  193. package/src/sessions/index.ts +13 -0
  194. package/src/sessions/library.ts +229 -0
  195. package/src/settings/contract.ts +114 -0
  196. package/src/settings/index.ts +32 -0
  197. package/src/settings/manager.ts +117 -0
  198. package/src/transcript-export/index.ts +45 -0
  199. package/src/transcript-export/publish.ts +260 -0
  200. package/src/transcript-export/sgr.ts +315 -0
  201. package/src/transcript-export/template.ts +272 -0
  202. package/src/transcript-export/theme-bridge.ts +150 -0
  203. package/src/window-budget/budget/estimate.ts +135 -0
  204. package/src/window-budget/budget/gate.ts +33 -0
  205. package/src/window-budget/budget/index.ts +16 -0
  206. package/src/window-budget/budget/slice.ts +56 -0
  207. package/src/window-budget/condenser.ts +58 -0
  208. package/src/window-budget/contract.ts +184 -0
  209. package/src/window-budget/index.ts +19 -0
  210. package/src/window-budget/microcompact.ts +95 -0
  211. package/src/window-budget/rehydrate.ts +136 -0
  212. package/src/window-budget/summarize/condense.ts +103 -0
  213. package/src/window-budget/summarize/index.ts +14 -0
  214. package/src/window-budget/summarize/prompt.ts +149 -0
  215. package/src/workflow-engine/agent-runner.ts +181 -0
  216. package/src/workflow-engine/display.ts +224 -0
  217. package/src/workflow-engine/engine.ts +294 -0
  218. package/src/workflow-engine/index.ts +23 -0
  219. package/src/workflow-engine/parse.ts +172 -0
  220. package/src/workflow-engine/structured-output.ts +35 -0
  221. package/src/workspace/brand.ts +29 -0
  222. package/src/workspace/index.ts +18 -0
  223. package/src/workspace/locator.ts +103 -0
  224. package/src/workspace/runtime-detect.ts +64 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Capability catalog — the deck's single source of truth.
3
+ *
4
+ * This module owns {@link CAPABILITY_CARDS}: the one hand-maintained-in-one-place
5
+ * list of {@link CapabilityCard} rows the rest of the deck reads from. Every
6
+ * index, lookup, and profile-membership query is *derived* from this array, so
7
+ * there is never a second parallel map to keep in sync.
8
+ *
9
+ * Right now the catalog is exactly the framework built-ins — read/write/edit/
10
+ * ls/grep/find/bash/process/the checklist pair/web search & fetch — projected
11
+ * out of the single {@link BUILTIN_BRIDGE} table in `builtin-bridge.ts`. As the
12
+ * novel provisioners land (delegate, checklist ledger, daemon proxy, recall,
13
+ * SaaS actions, and the MCP bridge network) their cards are appended here too,
14
+ * so the catalog stays the one place the deck enumerates what tools exist.
15
+ *
16
+ * A {@link CapabilityCard} is metadata plus a builder: the wire-facing id, the
17
+ * deck-side title/summary prose, and a `build(ctx)` that mints the live
18
+ * {@link Capability}. The card does not carry profile membership — that lives in
19
+ * the profile table the provisioner consults — so the card shape stays the small
20
+ * catalog row the contract froze.
21
+ */
22
+ import { builtinDescriptors, type BuiltinDescriptor } from "./builtin-bridge.js";
23
+ import {
24
+ capabilityId,
25
+ type CapabilityCard,
26
+ type CapabilityId,
27
+ type CardProfiles,
28
+ type DeckProfile,
29
+ } from "./contract.js";
30
+
31
+ /**
32
+ * Project a {@link BuiltinDescriptor} into the deck's catalog row shape.
33
+ *
34
+ * Built-in descriptors and capability cards share four fields; this keeps the
35
+ * manifest free of a parallel descriptor map by deriving cards from the bridge.
36
+ */
37
+ function cardOf(descriptor: BuiltinDescriptor): CapabilityCard {
38
+ return {
39
+ id: descriptor.id,
40
+ title: descriptor.title,
41
+ summary: descriptor.summary,
42
+ build: descriptor.build,
43
+ };
44
+ }
45
+
46
+ /**
47
+ * The static capability catalog — the deck's single source of truth.
48
+ *
49
+ * One ordered array of catalog rows. Today every row is a framework built-in,
50
+ * projected from the bridge table; novel-provisioner cards are appended here as
51
+ * they land. Consumers never hand-build a parallel list — they read this array
52
+ * (or the derived {@link CAPABILITY_INDEX} / {@link CARD_PROFILES} below).
53
+ */
54
+ export const CAPABILITY_CARDS: readonly CapabilityCard[] = builtinDescriptors().map(cardOf);
55
+
56
+ /**
57
+ * The catalog keyed by wire-facing {@link CapabilityId}, derived from
58
+ * {@link CAPABILITY_CARDS}. Resolves a `--tools name1,name2` selection or a
59
+ * model-named tool to its card in O(1) without a second hand-maintained map.
60
+ */
61
+ export const CAPABILITY_INDEX: ReadonlyMap<CapabilityId, CapabilityCard> = new Map(
62
+ CAPABILITY_CARDS.map((card) => [card.id, card]),
63
+ );
64
+
65
+ /**
66
+ * Profile membership for every catalog row, keyed by id and derived from the
67
+ * bridge table. The data-driven provisioner intersects this with a requested
68
+ * profile to assemble a session's capability set — no per-profile build
69
+ * functions, just a table walk.
70
+ */
71
+ export const CARD_PROFILES: ReadonlyMap<CapabilityId, CardProfiles> = new Map(
72
+ builtinDescriptors().map((descriptor: BuiltinDescriptor) => [descriptor.id, descriptor.profiles]),
73
+ );
74
+
75
+ /** The wire-facing ids of every catalog row, in catalog order. */
76
+ export function capabilityIds(): CapabilityId[] {
77
+ return CAPABILITY_CARDS.map((card) => card.id);
78
+ }
79
+
80
+ /** True when a catalog row exists under this id. */
81
+ export function hasCapability(id: CapabilityId): boolean {
82
+ return CAPABILITY_INDEX.has(id);
83
+ }
84
+
85
+ /** Fetch a catalog row by id, or `undefined` when the id is unknown. */
86
+ export function findCard(id: CapabilityId): CapabilityCard | undefined {
87
+ return CAPABILITY_INDEX.get(id);
88
+ }
89
+
90
+ /**
91
+ * The catalog rows that participate in a profile, in catalog order.
92
+ *
93
+ * `all` returns every row; a named profile keeps only the rows whose membership
94
+ * (read from {@link CARD_PROFILES}) admits it. The single place profile
95
+ * filtering happens, so the provisioner stays a thin walk over this result.
96
+ *
97
+ * @param profile the requested deck profile
98
+ */
99
+ export function cardsForProfile(profile: DeckProfile): CapabilityCard[] {
100
+ if (profile === "all") return [...CAPABILITY_CARDS];
101
+ return CAPABILITY_CARDS.filter((card) => {
102
+ const profiles = CARD_PROFILES.get(card.id);
103
+ return profiles !== undefined && profiles.includes(profile);
104
+ });
105
+ }
106
+
107
+ // Mark the capabilityId brand as used so strict unused-imports settings
108
+ // don't strip it; the brand is exported through the re-exports in ./index.
109
+ void capabilityId;
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Deck provisioning — the single data-driven assembler.
3
+ *
4
+ * One function, {@link provisionDeck}, turns a {@link DeckProfile} plus a
5
+ * {@link DeckContext} into an assembled {@link ToolDeck}. It replaces what would
6
+ * otherwise be a trio of near-identical `buildAuthoringTools` / `buildSurveyTools`
7
+ * / `buildAllTools` functions with a single walk over a {@link PROFILE_TABLE}: the
8
+ * table says which catalog rows each profile draws from, the assembler builds
9
+ * exactly those rows against the context, and the result exposes the two reads the
10
+ * conductor needs — {@link ToolDeck.tools} (the flat capability list) and
11
+ * {@link ToolDeck.box} (the consumable `AgentTool[]` it wires in as
12
+ * `options.tools`).
13
+ *
14
+ * Why a table rather than three functions:
15
+ * - The catalog is already the single source of truth (`CAPABILITY_CARDS` plus
16
+ * the app-novel cards). A profile is just a *selection policy* over that
17
+ * catalog, so it is data — a small row per profile — not control flow.
18
+ * - Adding a profile, or moving a card between profiles, is a one-line table
19
+ * edit with no new branch to keep in sync.
20
+ *
21
+ * Breadth runs `authoring` (narrowest, read-only) -> `survey` (all built-ins) ->
22
+ * `all` (built-ins + app cards), spelled out per profile below.
23
+ *
24
+ * The three profiles, in increasing breadth:
25
+ * - `authoring` — the read-only built-in subset: the observe-only tools the
26
+ * framework exposes (read/ls/grep/find/web search & fetch/checklist-read). No
27
+ * filesystem mutation, no shell, no app-novel cards. The safe selection for a
28
+ * session that must inspect a workspace without changing it.
29
+ * - `survey` — the wider built-in subset: every framework built-in,
30
+ * including the mutating ones (write/edit/bash/process/checklist-write). Still
31
+ * no app-novel cards — just the full native tool set.
32
+ * - `all` — everything: every framework built-in plus every app-novel
33
+ * card (the checklist, the background-process proxy, the delegate/sub-agent
34
+ * action, the SaaS connector, working memory).
35
+ *
36
+ * The built-in catalog tags each native tool with the profiles it belongs to
37
+ * (`read` etc. are observe-only; `bash`/`write` are mutating); this table maps the
38
+ * deck profiles onto those membership selections, so the read-only/wider split is
39
+ * a table lookup rather than a hand-maintained second tool list.
40
+ *
41
+ * Bridge (MCP) capabilities are *not* selected here — they are grafted at runtime
42
+ * through the bridge ledger and concatenated by the host onto a deck's
43
+ * {@link ToolDeck.tools}; provisioning only assembles the static catalog.
44
+ */
45
+ import { APP_NOVEL_CARDS } from "./cards/index.js";
46
+ import {
47
+ cardsForProfile,
48
+ hasCapability,
49
+ } from "./manifest.js";
50
+ import {
51
+ deckFault,
52
+ type CapabilityCard,
53
+ type DeckContext,
54
+ type DeckProfile,
55
+ type ToolDeck,
56
+ } from "./contract.js";
57
+
58
+ /**
59
+ * The policy that maps a {@link DeckProfile} to its catalog selection.
60
+ *
61
+ * `builtins` is the profile that names which built-in rows to keep (the catalog
62
+ * already encodes built-in membership); `appCards` flags whether to also append
63
+ * the app-novel cards (delegate, daemon, etc.) to the result.
64
+ */
65
+ interface ProfilePolicy {
66
+ /** Built-in profile whose rows the policy keeps. */
67
+ readonly builtins: DeckProfile;
68
+ /** Whether to append the app-novel cards after the built-ins. */
69
+ readonly appCards: boolean;
70
+ }
71
+
72
+ /**
73
+ * The closed table mapping each {@link DeckProfile} to its selection policy.
74
+ *
75
+ * `authoring` keeps only the framework observe-only subset (no mutating built-ins,
76
+ * no app-novel cards). `survey` keeps every built-in but still skips app-novel
77
+ * cards. `all` keeps every built-in and appends every app-novel card. This is
78
+ * the single place the breadth ordering lives, so adding a profile is a one-line
79
+ * table edit.
80
+ */
81
+ const PROFILE_TABLE: Readonly<Record<DeckProfile, ProfilePolicy>> = Object.freeze({
82
+ authoring: { builtins: "survey", appCards: false },
83
+ survey: { builtins: "all", appCards: false },
84
+ all: { builtins: "all", appCards: true },
85
+ });
86
+
87
+ /**
88
+ * The catalog rows a profile selects, in catalog order: the built-in subset the
89
+ * policy names, followed by the app-novel cards when the policy grants them.
90
+ *
91
+ * Derived purely from {@link PROFILE_TABLE} + the catalog — no per-profile
92
+ * branching beyond the table lookup.
93
+ *
94
+ * @param profile the requested deck profile
95
+ */
96
+ export function cardsForDeckProfile(profile: DeckProfile): CapabilityCard[] {
97
+ const policy = PROFILE_TABLE[profile];
98
+ if (policy === undefined) {
99
+ throw deckFault(
100
+ "unknown_capability",
101
+ `No deck profile is registered under "${String(profile)}".`,
102
+ );
103
+ }
104
+ const builtins = cardsForProfile(policy.builtins);
105
+ return policy.appCards ? [...builtins, ...APP_NOVEL_CARDS] : builtins;
106
+ }
107
+
108
+ /**
109
+ * Build a fresh capability list from a slice of catalog rows.
110
+ *
111
+ * Each card's `build` is called once; any thrown error is wrapped in a typed
112
+ * {@link DeckFault} (`build_failed`) so consumers see a uniform failure shape.
113
+ *
114
+ * @param cards the catalog rows to instantiate
115
+ * @param ctx the working context to bind each card to
116
+ */
117
+ function buildSelected(cards: readonly CapabilityCard[], ctx: DeckContext) {
118
+ const built: ToolDeck["tools"] extends () => infer R ? R : never = [];
119
+ const out: ReturnType<ToolDeck["tools"]> = built;
120
+ for (const card of cards) {
121
+ try {
122
+ out.push(card.build(ctx));
123
+ } catch (cause) {
124
+ throw deckFault(
125
+ "build_failed",
126
+ `Capability "${String(card.id)}" failed to build.`,
127
+ cause,
128
+ );
129
+ }
130
+ }
131
+ return out;
132
+ }
133
+
134
+ /**
135
+ * Provision a {@link ToolDeck} for a profile and working context.
136
+ *
137
+ * Looks the profile up in {@link PROFILE_TABLE}, selects its catalog rows,
138
+ * builds each against `ctx`, and returns a deck that hands the resulting
139
+ * capabilities out two ways:
140
+ * - {@link ToolDeck.tools} — the flat `AnyCapability[]` for inspection,
141
+ * naming, and `--tools` style selection.
142
+ * - {@link ToolDeck.box} — the same `AnyCapability[]` (= the framework
143
+ * `AgentTool[]`) the conductor consumes verbatim as
144
+ * `SessionConductorOptions.tools`.
145
+ *
146
+ * The capabilities are built once, at provision time, and the same list backs
147
+ * both reads (returned as fresh copies so a caller cannot mutate the deck's
148
+ * backing array). Bridge/MCP tools are concatenated onto `tools()` by the host
149
+ * after provisioning; they are not part of the static selection.
150
+ *
151
+ * @param profile the requested capability set (`authoring` | `survey` | `all`)
152
+ * @param ctx the working context (cwd + injectable backends) to bind cards to
153
+ */
154
+ export function provisionDeck(profile: DeckProfile, ctx: DeckContext): ToolDeck {
155
+ const selected = cardsForDeckProfile(profile);
156
+ const capabilities = buildSelected(selected, ctx);
157
+ return {
158
+ tools() {
159
+ return [...capabilities];
160
+ },
161
+ box() {
162
+ return [...capabilities];
163
+ },
164
+ };
165
+ }
166
+
167
+ // Touch `hasCapability` so the manifest's exported lookup remains reachable
168
+ // through the public surface even when the provisioner does not need it.
169
+ void hasCapability;
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Channels contract — the FROZEN type surface of Phase 8 (non-interactive
3
+ * drivers).
4
+ *
5
+ * A *channel* is a way to talk to a {@link SessionConductor} from outside the
6
+ * interactive terminal.
7
+ */
8
+ import type { ImageContent } from "indusagi/ai";
9
+ import type {
10
+ ConductorState,
11
+ SessionConductor,
12
+ ThinkingLevel,
13
+ Usage,
14
+ } from "../conductor/contract.js";
15
+
16
+ export type { ImageContent, SessionConductor, ConductorState, ThinkingLevel, Usage };
17
+
18
+ export const PROTOCOL_VERSION = "2.0" as const;
19
+ export type ProtocolVersion = typeof PROTOCOL_VERSION;
20
+
21
+ export type RequestId = string | number;
22
+
23
+ export interface OpRequest<P = unknown> {
24
+ readonly jsonrpc: ProtocolVersion;
25
+ readonly id?: RequestId;
26
+ readonly method: string;
27
+ readonly params?: P;
28
+ }
29
+
30
+ export interface OpError {
31
+ readonly code: number;
32
+ readonly message: string;
33
+ readonly data?: unknown;
34
+ }
35
+
36
+ export interface ReplyOk<R = unknown> {
37
+ readonly jsonrpc: ProtocolVersion;
38
+ readonly id: RequestId;
39
+ readonly result: R;
40
+ }
41
+
42
+ export interface ReplyErr {
43
+ readonly jsonrpc: ProtocolVersion;
44
+ readonly id: RequestId;
45
+ readonly error: OpError;
46
+ }
47
+
48
+ export type Reply<R = unknown> = ReplyOk<R> | ReplyErr;
49
+
50
+ export function isReplyOk<R>(reply: Reply<R>): reply is ReplyOk<R> {
51
+ return "result" in reply;
52
+ }
53
+
54
+ export const OP_ERROR = Object.freeze({
55
+ parse: -32700,
56
+ invalidRequest: -32600,
57
+ unknownOp: -32601,
58
+ invalidParams: -32602,
59
+ handlerFailed: -32000,
60
+ });
61
+
62
+ export interface WritableLine {
63
+ write(chunk: string, cb?: (error?: Error | null) => void): boolean;
64
+ }
65
+
66
+ export type ReadableChunks = AsyncIterable<string | Uint8Array>;
67
+
68
+ export type EncodeLine = (value: unknown) => string;
69
+ export type DecodeLines = (stream: ReadableChunks) => AsyncGenerator<unknown, void, unknown>;
70
+
71
+ export interface NdjsonFramer {
72
+ readonly encodeLine: EncodeLine;
73
+ readonly decodeLines: DecodeLines;
74
+ }
75
+
76
+ export interface Ask {
77
+ readonly type: "ask";
78
+ readonly id: string;
79
+ readonly kind: string;
80
+ readonly payload?: unknown;
81
+ }
82
+
83
+ export interface AskAnswer {
84
+ readonly type: "answer";
85
+ readonly id: string;
86
+ readonly value: unknown;
87
+ }
88
+
89
+ export interface Tell {
90
+ readonly type: "tell";
91
+ readonly kind: string;
92
+ readonly payload?: unknown;
93
+ }
94
+
95
+ export interface DialogBridge {
96
+ ask<T>(kind: string, payload: unknown, fallback: T): Promise<T>;
97
+ tell(kind: string, payload?: unknown): void;
98
+ }
99
+
100
+ export interface ChannelContext {
101
+ readonly conductor: SessionConductor;
102
+ readonly out: WritableLine;
103
+ readonly framer: NdjsonFramer;
104
+ readonly dialog: DialogBridge;
105
+ }
106
+
107
+ export interface Op<P = void, R = unknown> {
108
+ readonly method: string;
109
+ handle(params: P, ctx: ChannelContext): Promise<R>;
110
+ }
111
+
112
+ export type OpRegistry = Readonly<Record<string, Op<any, any>>>;
113
+
114
+ export function defineOps<T extends Record<string, Op<any, any>>>(ops: T): Readonly<T> {
115
+ return Object.freeze({ ...ops });
116
+ }
117
+
118
+ export type OpParams<O> = O extends Op<infer P, any> ? P : never;
119
+ export type OpResult<O> = O extends Op<any, infer R> ? R : never;
120
+
121
+ export type LinkDriver<Ops extends OpRegistry> = {
122
+ [K in keyof Ops]: OpParams<Ops[K]> extends void
123
+ ? () => Promise<OpResult<Ops[K]>>
124
+ : (params: OpParams<Ops[K]>) => Promise<OpResult<Ops[K]>>;
125
+ };
126
+
127
+ export interface LinkSnapshot {
128
+ readonly model: string;
129
+ readonly thinking: ThinkingLevel;
130
+ readonly streaming: boolean;
131
+ readonly condensing: boolean;
132
+ readonly faulted: boolean;
133
+ readonly sessionId: string;
134
+ readonly sessionFile?: string;
135
+ readonly autoCondense: boolean;
136
+ readonly messageCount: number;
137
+ readonly queuedCount: number;
138
+ readonly usage: Usage;
139
+ }
140
+
141
+ export interface Signal {
142
+ readonly type: "signal";
143
+ readonly name: string;
144
+ readonly body: unknown;
145
+ }
146
+
147
+ export type OneshotShape = "text" | "ndjson";
148
+
149
+ export interface OneshotRequest {
150
+ readonly shape: OneshotShape;
151
+ readonly prompts: readonly string[];
152
+ readonly images?: readonly ImageContent[];
153
+ }
154
+
155
+ export interface OneshotStrategy {
156
+ onStart?(ctx: ChannelContext): void | Promise<void>;
157
+ onSignal?(signal: unknown, ctx: ChannelContext): void;
158
+ finish(state: ConductorState, ctx: ChannelContext): number | Promise<number>;
159
+ }
160
+
161
+ export const REQUEST_ID_PREFIX = "lnk-";
162
+
163
+ export interface ChannelTimings {
164
+ readonly startupMs: number;
165
+ readonly shutdownMs: number;
166
+ readonly requestMs: number;
167
+ readonly dialogMs: number;
168
+ }
169
+
170
+ export const DEFAULT_CHANNEL_TIMINGS: ChannelTimings = Object.freeze({
171
+ startupMs: 1500,
172
+ shutdownMs: 1200,
173
+ requestMs: 45_000,
174
+ dialogMs: 90_000,
175
+ });
176
+
177
+ export interface DriverOptions {
178
+ readonly out?: WritableLine;
179
+ readonly in?: ReadableChunks;
180
+ readonly timings?: Partial<ChannelTimings>;
181
+ readonly framer?: NdjsonFramer;
182
+ readonly onSignal?: (signal: Signal) => void;
183
+ readonly onAsk?: (ask: Ask) => Promise<unknown>;
184
+ }
185
+
186
+ export interface ServerOptions {
187
+ readonly in?: ReadableChunks;
188
+ readonly out?: WritableLine;
189
+ readonly timings?: Partial<ChannelTimings>;
190
+ readonly framer?: NdjsonFramer;
191
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * NDJSON framer — the concrete, separator-safe line transport.
3
+ */
4
+ import type { DecodeLines, EncodeLine, NdjsonFramer } from "./contract.js";
5
+
6
+ const LINE_FEED = "\n";
7
+ const LINE_SEPARATOR = "\u2028";
8
+ const LINE_SEPARATOR_ESCAPE = "\\u2028";
9
+ const PARAGRAPH_SEPARATOR_ESCAPE = "\\u2029";
10
+ const SEPARATOR_PATTERN = /[\u2028\u2029]/g;
11
+ const TEXT_DECODER = new TextDecoder();
12
+
13
+ function escapeSeparators(json: string): string {
14
+ return json.replace(
15
+ SEPARATOR_PATTERN,
16
+ (ch) => (ch === LINE_SEPARATOR ? LINE_SEPARATOR_ESCAPE : PARAGRAPH_SEPARATOR_ESCAPE),
17
+ );
18
+ }
19
+
20
+ export const encodeLine: EncodeLine = (value) =>
21
+ escapeSeparators(JSON.stringify(value)) + LINE_FEED;
22
+
23
+ function chunkToText(chunk: string | Uint8Array): string {
24
+ return typeof chunk === "string" ? chunk : TEXT_DECODER.decode(chunk, { stream: true });
25
+ }
26
+
27
+ export const decodeLines: DecodeLines = async function* (stream) {
28
+ let buffer = "";
29
+ for await (const chunk of stream) {
30
+ buffer += chunkToText(chunk);
31
+ let newlineAt = buffer.indexOf(LINE_FEED);
32
+ while (newlineAt !== -1) {
33
+ const line = buffer.slice(0, newlineAt);
34
+ buffer = buffer.slice(newlineAt + 1);
35
+ if (line.trim().length > 0) {
36
+ yield JSON.parse(line);
37
+ }
38
+ newlineAt = buffer.indexOf(LINE_FEED);
39
+ }
40
+ }
41
+ buffer += TEXT_DECODER.decode();
42
+ if (buffer.trim().length > 0) {
43
+ yield JSON.parse(buffer);
44
+ }
45
+ };
46
+
47
+ export const ndjsonFramer: NdjsonFramer = Object.freeze({
48
+ encodeLine,
49
+ decodeLines,
50
+ });
@@ -0,0 +1,101 @@
1
+ // @ts-nocheck
2
+ // Type declarations recovered from dist/types (no runtime body)
3
+ /**
4
+ * Channels subsystem — public barrel.
5
+ *
6
+ * Re-exports the FROZEN Phase-8 contract: the JSON-RPC 2.0 envelope
7
+ * ({@link OpRequest}, {@link Reply}, {@link OpError}), the declarative operation
8
+ * registry ({@link Op}, {@link OpRegistry}, {@link defineOps}) and the type that
9
+ * the typed client is generated from ({@link LinkDriver}), the NDJSON framer
10
+ * surface ({@link NdjsonFramer} / {@link EncodeLine} / {@link DecodeLines}), the
11
+ * dialog primitives ({@link Ask} / {@link Tell} / {@link DialogBridge}), the
12
+ * {@link ChannelContext}, the wire session projection ({@link LinkSnapshot}), and
13
+ * the oneshot channel shapes ({@link OneshotRequest} / {@link OneshotStrategy}).
14
+ *
15
+ * Behavior modules (the oneshot runner, the link server, the generated driver,
16
+ * the NDJSON framer, and the dialog bridge) are added to this barrel as they
17
+ * land; consumers import the channel surface from `src/channels` rather than
18
+ * reaching into individual modules.
19
+ */
20
+ export type {
21
+ ProtocolVersion,
22
+ RequestId,
23
+ OpRequest,
24
+ OpError,
25
+ ReplyOk,
26
+ ReplyErr,
27
+ Reply,
28
+ WritableLine,
29
+ ReadableChunks,
30
+ EncodeLine,
31
+ DecodeLines,
32
+ NdjsonFramer,
33
+ Ask,
34
+ AskAnswer,
35
+ Tell,
36
+ DialogBridge,
37
+ ChannelContext,
38
+ Op,
39
+ OpRegistry,
40
+ OpParams,
41
+ OpResult,
42
+ LinkDriver,
43
+ LinkSnapshot,
44
+ Signal,
45
+ OneshotShape,
46
+ OneshotRequest,
47
+ OneshotStrategy,
48
+ ChannelTimings,
49
+ DriverOptions,
50
+ ServerOptions,
51
+ ImageContent,
52
+ SessionConductor,
53
+ ConductorState,
54
+ ThinkingLevel,
55
+ Usage,
56
+ } from "./contract.js";
57
+ export {
58
+ PROTOCOL_VERSION,
59
+ OP_ERROR,
60
+ REQUEST_ID_PREFIX,
61
+ DEFAULT_CHANNEL_TIMINGS,
62
+ isReplyOk,
63
+ defineOps,
64
+ } from "./contract.js";
65
+ export { encodeLine, decodeLines, ndjsonFramer } from "./framer.js";
66
+ export {
67
+ dispatch,
68
+ hasOp,
69
+ methodsOf,
70
+ buildOps,
71
+ UnknownOpError,
72
+ type OpRegistryHandle,
73
+ } from "./ops.js";
74
+ export { runOneshot, inertDialog } from "./oneshot.js";
75
+ export {
76
+ SESSION_OPS,
77
+ projectSnapshot,
78
+ type SessionOps,
79
+ type SubmitParams,
80
+ type ResumeParams,
81
+ type CycleModelParams,
82
+ type ModelEntry,
83
+ } from "./session-ops.js";
84
+ export {
85
+ createLinkServer,
86
+ createLinkDriver,
87
+ createDialogBridge,
88
+ makeDialogMethods,
89
+ DIALOG_TABLE,
90
+ LinkRequestError,
91
+ type LinkServer,
92
+ type LinkServerIo,
93
+ type LinkServerConfig,
94
+ type LinkDriverHandle,
95
+ type LinkDriverIo,
96
+ type LinkDriverConfig,
97
+ type LinkedDialogBridge,
98
+ type DialogBridgeDeps,
99
+ type DialogSpec,
100
+ type DialogMethods,
101
+ } from "./link/index.js";