indusagi-coding-agent 0.2.8 → 0.2.10
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.
- package/CHANGELOG.md +7 -0
- package/dist/entry.js +4 -4
- package/dist/index.js +4 -4
- package/package.json +3 -2
- package/src/_decls/entry.ts +18 -0
- package/src/_decls/guardrails.ts +35 -0
- package/src/_decls/index.ts +26 -0
- package/src/addons/contract.ts +236 -0
- package/src/addons/dispatch/event-dispatcher.ts +164 -0
- package/src/addons/dispatch/index.ts +25 -0
- package/src/addons/dispatch/tool-interceptor.ts +208 -0
- package/src/addons/host.ts +225 -0
- package/src/addons/index.ts +112 -0
- package/src/addons/manifest.ts +158 -0
- package/src/addons/sandbox.ts +170 -0
- package/src/addons/surface.ts +78 -0
- package/src/boot/auth-vault.ts +195 -0
- package/src/boot/boot.ts +138 -0
- package/src/boot/contract.ts +238 -0
- package/src/boot/heap.ts +59 -0
- package/src/boot/index.ts +28 -0
- package/src/boot/invocation.ts +93 -0
- package/src/boot/runners/addon-wiring.ts +153 -0
- package/src/boot/runners/checkpoint.ts +169 -0
- package/src/boot/runners/delegate-runner.ts +294 -0
- package/src/boot/runners/index.ts +13 -0
- package/src/boot/runners/link-runner.ts +45 -0
- package/src/boot/runners/memdir.ts +168 -0
- package/src/boot/runners/oneshot-runner.ts +58 -0
- package/src/boot/runners/read-state.ts +90 -0
- package/src/boot/runners/registry.ts +42 -0
- package/src/boot/runners/repl-runner.ts +143 -0
- package/src/boot/runners/server-mode.ts +121 -0
- package/src/boot/runners/session.ts +641 -0
- package/src/boot/server-token.ts +148 -0
- package/src/boot/stages.ts +167 -0
- package/src/boot/upgrade/apply.ts +94 -0
- package/src/boot/upgrade/index.ts +13 -0
- package/src/boot/upgrade/upgrades.ts +289 -0
- package/src/briefing/compose.ts +150 -0
- package/src/briefing/context-docs.ts +19 -0
- package/src/briefing/contract.ts +717 -0
- package/src/briefing/index.ts +31 -0
- package/src/briefing/macros.ts +97 -0
- package/src/briefing/skills.ts +47 -0
- package/src/capability-deck/bridge-ledger/index.ts +27 -0
- package/src/capability-deck/bridge-ledger/key.ts +67 -0
- package/src/capability-deck/bridge-ledger/ledger.ts +131 -0
- package/src/capability-deck/bridge-ledger/network.ts +117 -0
- package/src/capability-deck/builtin-bridge.ts +312 -0
- package/src/capability-deck/cards/bg-process-card.ts +335 -0
- package/src/capability-deck/cards/index.ts +115 -0
- package/src/capability-deck/cards/memory-card.ts +146 -0
- package/src/capability-deck/cards/plan-file.ts +97 -0
- package/src/capability-deck/cards/plan-tools.ts +185 -0
- package/src/capability-deck/cards/saas-card.ts +183 -0
- package/src/capability-deck/cards/task-card.ts +207 -0
- package/src/capability-deck/cards/todo-card.ts +168 -0
- package/src/capability-deck/cards/workflow-card.ts +247 -0
- package/src/capability-deck/contract.ts +388 -0
- package/src/capability-deck/index.ts +48 -0
- package/src/capability-deck/manifest.ts +109 -0
- package/src/capability-deck/provision.ts +169 -0
- package/src/channels/contract.ts +191 -0
- package/src/channels/framer.ts +50 -0
- package/src/channels/index.ts +101 -0
- package/src/channels/link/dialog.ts +129 -0
- package/src/channels/link/driver.ts +190 -0
- package/src/channels/link/index.ts +34 -0
- package/src/channels/link/server.ts +134 -0
- package/src/channels/oneshot.ts +90 -0
- package/src/channels/ops.ts +65 -0
- package/src/channels/session-ops.ts +81 -0
- package/src/conductor/bash-guard.ts +599 -0
- package/src/conductor/catalog/catalog.ts +116 -0
- package/src/conductor/catalog/index.ts +8 -0
- package/src/conductor/catalog/matcher.ts +134 -0
- package/src/conductor/conductor.ts +234 -0
- package/src/conductor/contract.ts +842 -0
- package/src/conductor/diagnostics.ts +227 -0
- package/src/conductor/index.ts +33 -0
- package/src/conductor/permissions.ts +588 -0
- package/src/conductor/quota-error.ts +49 -0
- package/src/conductor/signal-hub/hub.ts +46 -0
- package/src/conductor/signal-hub/index.ts +2 -0
- package/src/conductor/signal-hub/translate.test.ts +81 -0
- package/src/conductor/signal-hub/translate.ts +74 -0
- package/src/conductor/skill-parse/index.ts +2 -0
- package/src/conductor/skill-parse/parse.ts +108 -0
- package/src/conductor/transcript-store/index.ts +22 -0
- package/src/conductor/transcript-store/serialize.ts +116 -0
- package/src/conductor/transcript-store/store.ts +205 -0
- package/src/console/auth-status.ts +56 -0
- package/src/console/components/AgentsView.ts +165 -0
- package/src/console/components/BackgroundAgents.ts +155 -0
- package/src/console/components/Banner.ts +334 -0
- package/src/console/components/Composer.ts +94 -0
- package/src/console/components/StatusBar.ts +49 -0
- package/src/console/components/TerminalConsole.ts +1090 -0
- package/src/console/components/WorkingIndicator.ts +98 -0
- package/src/console/components/banner-sweep.ts +24 -0
- package/src/console/components/welcome.ts +74 -0
- package/src/console/contract.ts +630 -0
- package/src/console/index.ts +34 -0
- package/src/console/input/complete.ts +127 -0
- package/src/console/input/dir-reader.ts +34 -0
- package/src/console/input/index.ts +23 -0
- package/src/console/input/keymap.ts +159 -0
- package/src/console/input/paste.ts +104 -0
- package/src/console/mount.ts +56 -0
- package/src/console/overlays/approval-queue.ts +57 -0
- package/src/console/overlays/approval.ts +130 -0
- package/src/console/overlays/auth.ts +342 -0
- package/src/console/overlays/boards.ts +308 -0
- package/src/console/overlays/host.ts +36 -0
- package/src/console/overlays/index.ts +26 -0
- package/src/console/overlays/pickers.ts +258 -0
- package/src/console/overlays/sessions.ts +190 -0
- package/src/console/reducer.ts +182 -0
- package/src/console/slash/builtins.ts +81 -0
- package/src/console/slash/commands/dynamic.ts +83 -0
- package/src/console/slash/commands/integrations.ts +695 -0
- package/src/console/slash/commands/shared.ts +75 -0
- package/src/console/slash/commands/transcript.ts +263 -0
- package/src/console/slash/commands/workbench.ts +246 -0
- package/src/console/slash/index.ts +15 -0
- package/src/console/slash/registry.ts +70 -0
- package/src/console/slash/resolve.ts +63 -0
- package/src/console/startup.ts +209 -0
- package/src/console/theme/adapter.ts +45 -0
- package/src/console/theme/index.ts +7 -0
- package/src/console/theme/palette.ts +68 -0
- package/src/console/theme/resolve.ts +39 -0
- package/src/console/theme/tokens.ts +71 -0
- package/src/entry.ts +55 -0
- package/src/guardrails.ts +37 -0
- package/src/index.ts +18 -0
- package/src/insight/channel.ts +88 -0
- package/src/insight/contract.ts +185 -0
- package/src/insight/index.ts +110 -0
- package/src/insight/recorder.ts +213 -0
- package/src/insight/redaction.ts +157 -0
- package/src/insight/replay.ts +158 -0
- package/src/insight/sampling.ts +70 -0
- package/src/insight/serialize.ts +50 -0
- package/src/insight/sinks/console.ts +64 -0
- package/src/insight/sinks/file.ts +40 -0
- package/src/insight/sinks/index.ts +24 -0
- package/src/insight/sinks/stream.ts +54 -0
- package/src/integrations/sarvam/attach.ts +239 -0
- package/src/integrations/sarvam/config.ts +156 -0
- package/src/integrations/sarvam/index.ts +25 -0
- package/src/integrations/sarvam/sarvam.test.ts +60 -0
- package/src/integrations/sarvam/types.ts +27 -0
- package/src/integrations/zoho/attach.ts +342 -0
- package/src/integrations/zoho/config.ts +125 -0
- package/src/integrations/zoho/index.ts +27 -0
- package/src/integrations/zoho/types.ts +21 -0
- package/src/integrations/zoho/zoho.test.ts +50 -0
- package/src/kit/clipboard-image.ts +107 -0
- package/src/kit/external-editor.ts +48 -0
- package/src/kit/image.ts +59 -0
- package/src/kit/index.ts +51 -0
- package/src/kit/shell.ts +19 -0
- package/src/kit/tool-fetch.ts +85 -0
- package/src/launch/catalog.ts +148 -0
- package/src/launch/contract.ts +187 -0
- package/src/launch/credentials.ts +625 -0
- package/src/launch/index.ts +98 -0
- package/src/launch/invocation/attachments.ts +179 -0
- package/src/launch/invocation/flags.ts +196 -0
- package/src/launch/invocation/index.ts +25 -0
- package/src/launch/invocation/read.ts +260 -0
- package/src/launch/invocation/usage.ts +67 -0
- package/src/launch/login.ts +324 -0
- package/src/launch/oauth.test.ts +18 -0
- package/src/launch/oauth.ts +203 -0
- package/src/launch/packages.ts +194 -0
- package/src/launch/pickers.ts +189 -0
- package/src/runtime-bridge/bridges/_drive.ts +96 -0
- package/src/runtime-bridge/bridges/builtins.ts +68 -0
- package/src/runtime-bridge/bridges/claude-cli.ts +123 -0
- package/src/runtime-bridge/bridges/codex-cli.ts +142 -0
- package/src/runtime-bridge/bridges/index.ts +33 -0
- package/src/runtime-bridge/bridges/indusagi-cli.ts +155 -0
- package/src/runtime-bridge/broker.ts +227 -0
- package/src/runtime-bridge/contract.ts +122 -0
- package/src/runtime-bridge/index.ts +79 -0
- package/src/runtime-bridge/sink.ts +180 -0
- package/src/sessions/contract.ts +81 -0
- package/src/sessions/index.ts +13 -0
- package/src/sessions/library.ts +229 -0
- package/src/settings/contract.ts +114 -0
- package/src/settings/index.ts +32 -0
- package/src/settings/manager.ts +117 -0
- package/src/transcript-export/index.ts +45 -0
- package/src/transcript-export/publish.ts +260 -0
- package/src/transcript-export/sgr.ts +315 -0
- package/src/transcript-export/template.ts +272 -0
- package/src/transcript-export/theme-bridge.ts +150 -0
- package/src/window-budget/budget/estimate.ts +135 -0
- package/src/window-budget/budget/gate.ts +33 -0
- package/src/window-budget/budget/index.ts +16 -0
- package/src/window-budget/budget/slice.ts +56 -0
- package/src/window-budget/condenser.ts +58 -0
- package/src/window-budget/contract.ts +184 -0
- package/src/window-budget/index.ts +19 -0
- package/src/window-budget/microcompact.ts +95 -0
- package/src/window-budget/rehydrate.ts +136 -0
- package/src/window-budget/summarize/condense.ts +103 -0
- package/src/window-budget/summarize/index.ts +14 -0
- package/src/window-budget/summarize/prompt.ts +149 -0
- package/src/workflow-engine/agent-runner.ts +181 -0
- package/src/workflow-engine/display.ts +224 -0
- package/src/workflow-engine/engine.ts +294 -0
- package/src/workflow-engine/index.ts +23 -0
- package/src/workflow-engine/parse.ts +172 -0
- package/src/workflow-engine/structured-output.ts +35 -0
- package/src/workspace/brand.ts +29 -0
- package/src/workspace/index.ts +18 -0
- package/src/workspace/locator.ts +103 -0
- 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";
|