indusagi-coding-agent 0.2.2 → 0.2.4
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 +46 -0
- package/dist/entry.js +12434 -9445
- package/dist/guardrails.js +897 -37
- package/dist/index.js +14081 -11111
- package/dist/types/boot/heap.d.ts +31 -0
- package/dist/types/boot/runners/delegate-runner.d.ts +27 -1
- package/dist/types/boot/runners/server-mode.d.ts +71 -0
- package/dist/types/boot/runners/session.d.ts +26 -18
- package/dist/types/boot/runners/session.test.d.ts +6 -1
- package/dist/types/boot/server-token.d.ts +97 -0
- package/dist/types/capability-deck/cards/index.d.ts +1 -0
- package/dist/types/capability-deck/cards/task-card.d.ts +26 -2
- package/dist/types/capability-deck/cards/workflow-card.d.ts +55 -0
- package/dist/types/capability-deck/cards/workflow-card.test.d.ts +12 -0
- package/dist/types/capability-deck/contract.d.ts +7 -6
- package/dist/types/capability-deck/index.d.ts +1 -1
- package/dist/types/conductor/conductor.d.ts +24 -0
- package/dist/types/conductor/contract.d.ts +79 -7
- package/dist/types/conductor/index.d.ts +3 -3
- package/dist/types/conductor/permissions.d.ts +74 -4
- package/dist/types/conductor/post-edit-diagnostics.test.d.ts +8 -3
- package/dist/types/conductor/quota-error.d.ts +35 -0
- package/dist/types/conductor/signal-hub/translate.d.ts +4 -1
- package/dist/types/console/auth-status.d.ts +28 -0
- package/dist/types/console/components/AgentsView.d.ts +41 -0
- package/dist/types/console/components/BackgroundAgents.d.ts +63 -0
- package/dist/types/console/components/BackgroundAgents.test.d.ts +8 -0
- package/dist/types/console/components/Banner.d.ts +67 -33
- package/dist/types/console/components/TerminalConsole.d.ts +0 -5
- package/dist/types/console/components/welcome.d.ts +115 -0
- package/dist/types/console/components/welcome.test.d.ts +9 -0
- package/dist/types/console/contract.d.ts +16 -1
- package/dist/types/console/index.d.ts +3 -0
- package/dist/types/console/input/index.d.ts +1 -1
- package/dist/types/console/input/keymap.d.ts +2 -2
- package/dist/types/console/input/paste.d.ts +58 -6
- package/dist/types/console/overlays/approval-queue.d.ts +18 -1
- package/dist/types/console/overlays/boards.d.ts +55 -0
- package/dist/types/console/overlays/index.d.ts +1 -1
- package/dist/types/console/theme/adapter.d.ts +1 -1
- package/dist/types/console/theme/index.d.ts +1 -1
- package/dist/types/console/theme/palette.d.ts +10 -0
- package/dist/types/launch/login.d.ts +68 -0
- package/dist/types/launch/oauth.test.d.ts +20 -0
- package/dist/types/window-budget/summarize/condense.d.ts +6 -0
- package/dist/types/workflow-engine/agent-runner.d.ts +124 -0
- package/dist/types/workflow-engine/agent-runner.test.d.ts +8 -0
- package/dist/types/workflow-engine/display.d.ts +148 -0
- package/dist/types/workflow-engine/display.test.d.ts +1 -0
- package/dist/types/workflow-engine/engine.d.ts +183 -0
- package/dist/types/workflow-engine/engine.test.d.ts +1 -0
- package/dist/types/workflow-engine/index.d.ts +21 -0
- package/dist/types/workflow-engine/parse.d.ts +64 -0
- package/dist/types/workflow-engine/parse.test.d.ts +1 -0
- package/dist/types/workflow-engine/structured-output.d.ts +51 -0
- package/dist/types/workflow-engine/structured-output.test.d.ts +1 -0
- package/dist/types/workspace/brand.d.ts +1 -1
- package/package.json +2 -2
- package/dist/types/console/components/Emblem.d.ts +0 -49
|
@@ -97,11 +97,20 @@ export declare function conductorFault(kind: FaultKind, message: string, cause?:
|
|
|
97
97
|
* - `text` — a chunk of assistant answer text streamed in.
|
|
98
98
|
* - `thinking` — a chunk of reasoning/thinking text streamed in.
|
|
99
99
|
* - `tool_start`— a tool invocation began (correlate by `id`).
|
|
100
|
+
* - `tool_update`— a running tool emitted partial progress (correlate by `id`);
|
|
101
|
+
* `name` is the tool name and `details` is the tool's own typed
|
|
102
|
+
* partial-result detail (e.g. the live `◆ Workflow` snapshot).
|
|
100
103
|
* - `tool_end` — a tool invocation finished (`ok` = no error).
|
|
101
104
|
* - `turn_end` — the assistant turn settled; `usage` reports token spend.
|
|
102
105
|
* - `persisted` — the latest node was committed to the transcript (`entryId`).
|
|
103
|
-
* - `compacted` — the transcript
|
|
104
|
-
*
|
|
106
|
+
* - `compacted` — the transcript WAS condensed (emitted on completion, not at
|
|
107
|
+
* the start). `manual` marks a user-driven `/compact` — a view may then
|
|
108
|
+
* reset its visible transcript — versus mid-turn auto-compaction, where the
|
|
109
|
+
* display must keep the in-flight exchange on screen.
|
|
110
|
+
* - `fault` — a typed {@link ConductorFault} occurred. `transient` marks a
|
|
111
|
+
* fault surfaced purely as an in-turn notice (e.g. a fallback-model swap on
|
|
112
|
+
* provider overload) — the turn keeps running, so a consumer must NOT treat
|
|
113
|
+
* it as the turn's end (must not clear a busy/in-flight indicator on it).
|
|
105
114
|
* - `queue` — the pending-input queue changed; `count` is its new depth.
|
|
106
115
|
* - `idle` — the conductor has no in-flight work and is ready for input.
|
|
107
116
|
*/
|
|
@@ -118,6 +127,11 @@ export type SessionSignal = {
|
|
|
118
127
|
readonly kind: "tool_start";
|
|
119
128
|
readonly id: string;
|
|
120
129
|
readonly name: string;
|
|
130
|
+
} | {
|
|
131
|
+
readonly kind: "tool_update";
|
|
132
|
+
readonly id: string;
|
|
133
|
+
readonly name: string;
|
|
134
|
+
readonly details: unknown;
|
|
121
135
|
} | {
|
|
122
136
|
readonly kind: "tool_end";
|
|
123
137
|
readonly id: string;
|
|
@@ -130,9 +144,11 @@ export type SessionSignal = {
|
|
|
130
144
|
readonly entryId: string;
|
|
131
145
|
} | {
|
|
132
146
|
readonly kind: "compacted";
|
|
147
|
+
readonly manual?: boolean;
|
|
133
148
|
} | {
|
|
134
149
|
readonly kind: "fault";
|
|
135
150
|
readonly fault: ConductorFault;
|
|
151
|
+
readonly transient?: boolean;
|
|
136
152
|
} | {
|
|
137
153
|
readonly kind: "queue";
|
|
138
154
|
readonly count: number;
|
|
@@ -420,6 +436,18 @@ export interface SessionConductorOptions {
|
|
|
420
436
|
* the swap entirely (behavior-preserving default).
|
|
421
437
|
*/
|
|
422
438
|
readonly fallbackModelId?: string;
|
|
439
|
+
/**
|
|
440
|
+
* Per-provider indus-gateway base URLs ("server mode"), keyed by provider slug
|
|
441
|
+
* (e.g. `{ minimax: "http://host/gateway/minimax", sarvam: "…/gateway/sarvam" }`).
|
|
442
|
+
* Set by the session runner for every gateway-eligible provider the user has no
|
|
443
|
+
* local key for but holds a valid server token. At EVERY model bind (including a
|
|
444
|
+
* runtime `/model` switch) the conductor looks up the BOUND model's provider in
|
|
445
|
+
* this map and, when present, binds a CLONE of the framework model with its
|
|
446
|
+
* `baseUrl` swapped to that URL — so any server-tier model routes through the
|
|
447
|
+
* quota-enforcing server while the session token (via {@link getApiKey})
|
|
448
|
+
* authenticates it. A provider absent from the map keeps the direct path.
|
|
449
|
+
*/
|
|
450
|
+
readonly gatewayBaseUrls?: Record<string, string>;
|
|
423
451
|
/** Working directory the session is scoped to (defaults to process cwd). */
|
|
424
452
|
readonly workspace?: string;
|
|
425
453
|
/**
|
|
@@ -488,6 +516,11 @@ export interface SessionConductorOptions {
|
|
|
488
516
|
*/
|
|
489
517
|
readonly checkpoint?: CheckpointPort;
|
|
490
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* What a manual {@link SessionConductor.condense} run amounted to — the honest
|
|
521
|
+
* completion vocabulary `/compact` reports from (see the method doc).
|
|
522
|
+
*/
|
|
523
|
+
export type CondenseOutcome = "condensed" | "nothing" | "cancelled" | "failed" | "busy";
|
|
491
524
|
/**
|
|
492
525
|
* The conductor of a single coding-agent session.
|
|
493
526
|
*
|
|
@@ -529,6 +562,15 @@ export interface SessionConductor {
|
|
|
529
562
|
pendingInputs(): readonly QueuedInput[];
|
|
530
563
|
/** Discard every queued input. Emits a `{ kind: "queue" }` signal. */
|
|
531
564
|
clearQueue(): void;
|
|
565
|
+
/**
|
|
566
|
+
* Promote the NEWEST queued input to run immediately: the in-flight turn (if
|
|
567
|
+
* any) is aborted — its work stops — while the rest of the queue is kept, and
|
|
568
|
+
* the promoted input runs as the very next turn. The user-facing "run my new
|
|
569
|
+
* message NOW" affordance for a long/stuck turn (issue #19), distinct from
|
|
570
|
+
* {@link abort} (which stops everything and clears the queue). Returns `false`
|
|
571
|
+
* when no input is queued.
|
|
572
|
+
*/
|
|
573
|
+
steerNow(): boolean;
|
|
532
574
|
/**
|
|
533
575
|
* Remove and return the text of the most-recently queued input, or `undefined`
|
|
534
576
|
* when the queue is empty. Lets a UI pop the last entry back into its prompt.
|
|
@@ -562,6 +604,20 @@ export interface SessionConductor {
|
|
|
562
604
|
* @param id canonical id of the model to switch to
|
|
563
605
|
*/
|
|
564
606
|
selectModel(id: string): void;
|
|
607
|
+
/**
|
|
608
|
+
* Replace the server-tier gateway routing map and immediately re-bind the
|
|
609
|
+
* currently selected model against it (without changing which model is
|
|
610
|
+
* selected). Lets an interactive mid-session sign-in (see `/login` ->
|
|
611
|
+
* "Indus Server") take effect right away: the gateway base-url map is
|
|
612
|
+
* otherwise frozen at conductor construction, so a login that happens after
|
|
613
|
+
* boot would silently never route the bound model through the gateway even
|
|
614
|
+
* though the per-request key resolver already started vending the fresh
|
|
615
|
+
* session token as the provider key.
|
|
616
|
+
*
|
|
617
|
+
* @param map provider id -> gateway base URL, as produced by
|
|
618
|
+
* `resolveServerGatewayUrls` for the current vault/token state
|
|
619
|
+
*/
|
|
620
|
+
updateGatewayBaseUrls(map: Record<string, string>): void;
|
|
565
621
|
/**
|
|
566
622
|
* Replace the agent's tool deck for subsequent turns.
|
|
567
623
|
*
|
|
@@ -576,11 +632,27 @@ export interface SessionConductor {
|
|
|
576
632
|
*/
|
|
577
633
|
registerTools(tools: AgentTool[]): void;
|
|
578
634
|
/**
|
|
579
|
-
* Manually run the
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
|
|
583
|
-
|
|
635
|
+
* Manually run the transcript-condense path (`/compact`) and report what
|
|
636
|
+
* happened, so the caller can give honest feedback instead of announcing
|
|
637
|
+
* "condensed" regardless:
|
|
638
|
+
* - `"condensed"` — the branch shrank and was rebound (emits `compacted`).
|
|
639
|
+
* - `"nothing"` — nothing older to fold (single-turn session, or already
|
|
640
|
+
* compacted); the transcript is untouched.
|
|
641
|
+
* - `"cancelled"` — {@link cancelCondense} fired mid-run; the digest was
|
|
642
|
+
* discarded and the transcript is untouched.
|
|
643
|
+
* - `"failed"` — the condense hook threw; a typed fault was emitted.
|
|
644
|
+
* - `"busy"` — a turn is in flight; compact after it settles (or abort
|
|
645
|
+
* it first).
|
|
646
|
+
* While the condense runs, {@link submit} queues instead of racing it, and the
|
|
647
|
+
* queue drains once the condense settles.
|
|
648
|
+
*/
|
|
649
|
+
condense(): Promise<CondenseOutcome>;
|
|
650
|
+
/**
|
|
651
|
+
* Cancel an in-flight manual {@link condense} (the `/compact` Esc affordance).
|
|
652
|
+
* The summarizer's result is discarded and the transcript stays untouched; a
|
|
653
|
+
* no-op when no manual condense is running.
|
|
654
|
+
*/
|
|
655
|
+
cancelCondense(): void;
|
|
584
656
|
/**
|
|
585
657
|
* Branch the transcript from a prior node. A new branch is opened whose parent
|
|
586
658
|
* is `entryId`; the agent's message list is rebound to that branch's root→leaf
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
* land; consumers import the conductor surface from `src/conductor` rather than
|
|
15
15
|
* reaching into individual modules.
|
|
16
16
|
*/
|
|
17
|
-
export type { FaultKind, ConductorFault, SessionSignal, SignalKind, SignalOf, SignalHandler, TranscriptSchema, TranscriptRole, TranscriptEntry, SessionHead, ModelCardRef, MatchQuery, ConductorPhase, ConductorState, QueueMode, QueuedInput, SessionStats, ExecuteBashOptions, BashOutcome, SessionConductor, SessionConductorOptions, AgentMessage, AgentTool, CanUseToolFn, ThinkingLevel, Model, Usage, KnownProvider, PermissionMode, } from "./contract";
|
|
17
|
+
export type { FaultKind, ConductorFault, SessionSignal, SignalKind, SignalOf, SignalHandler, TranscriptSchema, TranscriptRole, TranscriptEntry, SessionHead, ModelCardRef, MatchQuery, ConductorPhase, ConductorState, QueueMode, QueuedInput, SessionStats, ExecuteBashOptions, BashOutcome, SessionConductor, SessionConductorOptions, CondenseOutcome, AgentMessage, AgentTool, CanUseToolFn, ThinkingLevel, Model, Usage, KnownProvider, PermissionMode, } from "./contract";
|
|
18
18
|
export { conductorFault, TRANSCRIPT_SCHEMA } from "./contract";
|
|
19
|
-
export { createSessionConductor, reduceState, noopCondense, type AgentLike, type ConductorDeps, type CondenseFn, type RetryPolicy, } from "./conductor";
|
|
19
|
+
export { createSessionConductor, reduceState, noopCondense, withGatewayBaseUrl, type AgentLike, type ConductorDeps, type CondenseFn, type RetryPolicy, } from "./conductor";
|
|
20
20
|
export { SignalHub, translateAgentEvent, type SignalHubOptions } from "./signal-hub";
|
|
21
21
|
export { ModelCatalog, ModelMatcher, canonicalId, toCardRef, type CatalogCard, type CatalogSource, type ResolveInput, } from "./catalog";
|
|
22
22
|
export { TranscriptStore, memoryBackend, fsBackend, replay, type TranscriptBackend, type TranscriptState, type TranscriptClock, type TranscriptStoreOptions, } from "./transcript-store";
|
|
23
23
|
export { parseSkillInvocation, type SkillInvocation } from "./skill-parse";
|
|
24
|
-
export { resolveRuleDecision, parseRule, makeRule, toolMatchesRule, createPermissionGate, isReadOnlyToolName, isEditToolName, READ_ONLY_TOOL_NAMES, EDIT_TOOL_NAMES, type PermissionBehavior, type PermissionRule, type PermissionDecision, type CanUseToolFn as PermissionCanUseToolFn, type ApprovalChoice, type ApprovalResolver, type PermissionGateConfig, } from "./permissions";
|
|
24
|
+
export { resolveRuleDecision, parseRule, makeRule, toolMatchesRule, createPermissionGate, createSubagentPermissionGate, collectReadOnlyToolNames, allowAlwaysRuleStrings, isReadOnlyToolName, isEditToolName, READ_ONLY_TOOL_NAMES, EDIT_TOOL_NAMES, type PermissionBehavior, type PermissionRule, type PermissionDecision, type CanUseToolFn as PermissionCanUseToolFn, type ApprovalChoice, type ApprovalOutcome, type ApprovalResolver, type PermissionGateConfig, type SessionPermissionPolicy, } from "./permissions";
|
|
25
25
|
export { parseBashCommand, catastrophicReason, isCatastrophicCommand, evaluateCatastrophic, bashSubcommandSubjects, type ParsedCommand, } from "./bash-guard";
|
|
26
26
|
export { DiagnosticsEngine, createDiagnosticKey, deduplicateAndCap, formatDiagnosticsSummary, getSeveritySymbol, parseTscOutput, parseEslintOutput, runTscDiagnostics, runEslintDiagnostics, hasTsConfig, hasEslintConfig, isTypeScriptOrJs, areDiagnosticsEqual, MAX_PER_FILE, MAX_TOTAL, MAX_SUMMARY_CHARS, type Diagnostic, type DiagnosticFile, type DiagnosticSeverity, type DiagnosticsConfig, type DiagnosticRunner, type DedupOptions, type Position, } from "./diagnostics";
|
|
@@ -74,16 +74,29 @@ export type CanUseToolFn = (toolName: string, input: unknown, opts: {
|
|
|
74
74
|
* - `deny` — block this call.
|
|
75
75
|
*/
|
|
76
76
|
export type ApprovalChoice = "allow-once" | "allow-always" | "deny";
|
|
77
|
+
/**
|
|
78
|
+
* What an {@link ApprovalResolver} may resolve to: a user's {@link ApprovalChoice},
|
|
79
|
+
* or `"unavailable"` — the conductor's stable delegate answers that when NO
|
|
80
|
+
* interactive resolver is installed behind it (a headless boot, or the console not
|
|
81
|
+
* yet mounted). The gate maps `"unavailable"` to the actionable "requires
|
|
82
|
+
* approval" deny (pointing at `--permission-mode` / settings allow rules) rather
|
|
83
|
+
* than the "denied by the user" message, which would be false when no user ever
|
|
84
|
+
* saw a prompt.
|
|
85
|
+
*/
|
|
86
|
+
export type ApprovalOutcome = ApprovalChoice | "unavailable";
|
|
77
87
|
/**
|
|
78
88
|
* The OPTIONAL host approval resolver. When present, an `ask` decision awaits it;
|
|
79
89
|
* the host (an interactive overlay) returns the user's choice. It MUST resolve to
|
|
80
90
|
* `"deny"` on abort so a cancelled turn never hangs on a pending prompt. When the
|
|
81
91
|
* resolver is absent (non-interactive boot / oneshot / link), an `ask` decision
|
|
82
|
-
* deterministically denies.
|
|
92
|
+
* deterministically denies. A stable pass-through delegate (the conductor's)
|
|
93
|
+
* resolves `"unavailable"` while no real resolver is installed behind it, so the
|
|
94
|
+
* gate can surface the actionable non-interactive deny message instead of a
|
|
95
|
+
* fictitious user denial.
|
|
83
96
|
*/
|
|
84
97
|
export type ApprovalResolver = (toolName: string, input: unknown, opts: {
|
|
85
98
|
signal?: AbortSignal;
|
|
86
|
-
}) => Promise<
|
|
99
|
+
}) => Promise<ApprovalOutcome>;
|
|
87
100
|
/**
|
|
88
101
|
* Tool names known to only inspect state (never mutate). Mirrors the framework's
|
|
89
102
|
* `READ_ONLY_TOOL_NAMES`; matched case-insensitively. A tool the framework marks
|
|
@@ -172,6 +185,22 @@ export declare function toolMatchesRule(toolName: string, input: unknown, rule:
|
|
|
172
185
|
* Pure and total: no I/O, no async, deterministic for a given input.
|
|
173
186
|
*/
|
|
174
187
|
export declare function resolveRuleDecision(toolName: string, input: unknown, rules: readonly PermissionRule[], mode: PermissionMode, readOnlyExtra?: ReadonlySet<string>): PermissionBehavior;
|
|
188
|
+
/**
|
|
189
|
+
* The rule strings an `allow-always` approval mints — i.e. what the session will
|
|
190
|
+
* REMEMBER for this tool call.
|
|
191
|
+
*
|
|
192
|
+
* For the shell tool the remembered rules are scoped to the command: one
|
|
193
|
+
* `Bash(<sub-command>)` rule per constituent sub-command (so approving
|
|
194
|
+
* `git status && npm test` remembers both halves, and re-running either — or the
|
|
195
|
+
* same compound — auto-allows), but approving one command never whitelists the
|
|
196
|
+
* whole shell. Every other tool remembers the bare tool name (`Edit`), matching
|
|
197
|
+
* the prompt's "remember the tool for this session" copy.
|
|
198
|
+
*
|
|
199
|
+
* Exported so the approval overlay can show the user exactly what "Allow always"
|
|
200
|
+
* will remember (the `suggestions` line), and so the gate and the UI can never
|
|
201
|
+
* disagree about it.
|
|
202
|
+
*/
|
|
203
|
+
export declare function allowAlwaysRuleStrings(toolName: string, input: unknown): string[];
|
|
175
204
|
/** Configuration for {@link createPermissionGate}. */
|
|
176
205
|
export interface PermissionGateConfig {
|
|
177
206
|
/**
|
|
@@ -188,8 +217,11 @@ export interface PermissionGateConfig {
|
|
|
188
217
|
readonly requestApproval?: ApprovalResolver;
|
|
189
218
|
/**
|
|
190
219
|
* Append a session-scoped allow rule when the host returns `allow-always`. The
|
|
191
|
-
*
|
|
192
|
-
*
|
|
220
|
+
* boot layer owns the mutable rule list (the SAME array instance `rules` refers
|
|
221
|
+
* to) and passes a push here, so the appended rule is visible to every
|
|
222
|
+
* subsequent gate consultation within the session — and to every other gate
|
|
223
|
+
* built over the same list (sub-agent gates included). Session-scoped only:
|
|
224
|
+
* the rule is never persisted to settings.
|
|
193
225
|
*/
|
|
194
226
|
readonly appendAllowRule?: (rule: PermissionRule) => void;
|
|
195
227
|
/**
|
|
@@ -215,3 +247,41 @@ export interface PermissionGateConfig {
|
|
|
215
247
|
* The result is assignable to `indusagi/agent`'s `CanUseToolFn`.
|
|
216
248
|
*/
|
|
217
249
|
export declare function createPermissionGate(config: PermissionGateConfig): CanUseToolFn;
|
|
250
|
+
/**
|
|
251
|
+
* The live permission policy a session shares with its sub-agent runners (the
|
|
252
|
+
* `task` and `workflow` tools): the SAME mutable rule list the parent gate reads
|
|
253
|
+
* — so a session-scoped `allow-always` rule and the settings deny/ask rules are
|
|
254
|
+
* enforced inside delegations too — plus a live getter onto the parent
|
|
255
|
+
* conductor's permission mode, so a mid-run Shift+Tab (bypass → default, plan,
|
|
256
|
+
* back to bypass, …) retargets the very next sub-agent tool call.
|
|
257
|
+
*/
|
|
258
|
+
export interface SessionPermissionPolicy {
|
|
259
|
+
/** The session's ordered rule list — the live array, never a snapshot. */
|
|
260
|
+
readonly rules: readonly PermissionRule[];
|
|
261
|
+
/** Live getter onto the parent session's current permission mode. */
|
|
262
|
+
readonly mode: () => PermissionMode;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Collect the names of every tool flagged `readOnly: true` (structurally probed,
|
|
266
|
+
* so any deck/framework/MCP tool shape works). These names are auto-allowed by
|
|
267
|
+
* the gate in `default`/`acceptEdits`/`plan` beyond the static
|
|
268
|
+
* {@link READ_ONLY_TOOL_NAMES}.
|
|
269
|
+
*/
|
|
270
|
+
export declare function collectReadOnlyToolNames(tools: ReadonlyArray<{
|
|
271
|
+
readonly name: string;
|
|
272
|
+
}>): ReadonlySet<string>;
|
|
273
|
+
/**
|
|
274
|
+
* Build the RESOLVER-LESS gate a sub-agent runs under.
|
|
275
|
+
*
|
|
276
|
+
* A sub-agent cannot prompt the user, so no {@link ApprovalResolver} is wired:
|
|
277
|
+
* an `ask` decision deterministically denies with an actionable message, while
|
|
278
|
+
* deny rules, plan-mode enforcement, the catastrophic-bash blocklist, read-only
|
|
279
|
+
* auto-allow, and bypass/acceptEdits behaviour all apply per inner tool call —
|
|
280
|
+
* against the LIVE parent mode, so mid-run mode switches reach delegations too.
|
|
281
|
+
*
|
|
282
|
+
* @param policy the session's shared rules + live mode getter
|
|
283
|
+
* @param tools the sub-agent's actual deck, probed for `readOnly: true` flags
|
|
284
|
+
*/
|
|
285
|
+
export declare function createSubagentPermissionGate(policy: SessionPermissionPolicy, tools: ReadonlyArray<{
|
|
286
|
+
readonly name: string;
|
|
287
|
+
}>): CanUseToolFn;
|
|
@@ -6,8 +6,13 @@
|
|
|
6
6
|
* over a scripted in-memory runner (no real tsc spawn). Verifies:
|
|
7
7
|
* - a turn that introduces a NEW diagnostic enqueues the summary follow-up;
|
|
8
8
|
* - a clean edit (no new diagnostics) enqueues nothing;
|
|
9
|
-
* -
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* - a still-unfixed diagnostic is delivered AT MOST ONCE per session — a
|
|
10
|
+
* follow-up turn whose "fix" edits fail to eliminate the same error must
|
|
11
|
+
* NOT be re-prompted with it (the endless self-continuation of issue #15);
|
|
12
|
+
* - even genuinely NEW errors per fix attempt stop re-prompting at the
|
|
13
|
+
* consecutive follow-up cap, and a fresh user prompt re-arms the budget;
|
|
14
|
+
* - `idle` is not emitted between a turn and its auto-drained follow-up (the
|
|
15
|
+
* spinner must not drop while the agent keeps working);
|
|
16
|
+
* - a non-TS edit never triggers the checker.
|
|
12
17
|
*/
|
|
13
18
|
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* quota-error.ts — maps the indus model-gateway's usage-limit response into a
|
|
3
|
+
* friendly, user-facing fault message.
|
|
4
|
+
*
|
|
5
|
+
* When a no-local-key, logged-in user runs a turn, the framework adapter is
|
|
6
|
+
* pointed at `${INDUS_SERVER_URL}/gateway/<provider>` (see the conductor's
|
|
7
|
+
* baseUrl rewrite). If that user is over their monthly token allowance, the
|
|
8
|
+
* server replies — *before* forwarding upstream — with:
|
|
9
|
+
*
|
|
10
|
+
* HTTP/1.1 429 Too Many Requests
|
|
11
|
+
* Content-Type: application/json
|
|
12
|
+
*
|
|
13
|
+
* { "error": "quota_exceeded", "used": <number>, "limit": <number> }
|
|
14
|
+
*
|
|
15
|
+
* The provider SDK / raw-fetch adapter turns that 429 into a thrown error. By
|
|
16
|
+
* the time it reaches the conductor it may be wrapped (an SDK `APIError`, a
|
|
17
|
+
* generic `Error`, a nested `cause` chain, or a plain string), so detection must
|
|
18
|
+
* be tolerant and walk the whole error chain rather than trust a single shape.
|
|
19
|
+
*
|
|
20
|
+
* This module is intentionally transport-agnostic and dependency-free so it can
|
|
21
|
+
* be unit-tested in isolation and imported from the conductor's retry chokepoint
|
|
22
|
+
* without pulling in any network/runtime modules.
|
|
23
|
+
*/
|
|
24
|
+
/** Detects the gateway's 429 quota body anywhere in the error chain. */
|
|
25
|
+
export declare function isQuotaFault(error: unknown): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Friendly user-facing text; `undefined` if `error` is not a quota fault.
|
|
28
|
+
*
|
|
29
|
+
* Includes the `<used>/<limit>` parenthetical when both numbers are parseable,
|
|
30
|
+
* and otherwise falls back to the same sentence without it. The `indus signin
|
|
31
|
+
* <provider>` hint steers the user toward supplying their own key (which takes
|
|
32
|
+
* the direct, un-metered local-key path), and the upgrade hint covers raising
|
|
33
|
+
* the server-side allowance.
|
|
34
|
+
*/
|
|
35
|
+
export declare function quotaErrorMessage(error: unknown): string | undefined;
|
|
@@ -24,7 +24,10 @@
|
|
|
24
24
|
* (the turn is now committed), one `fault` for
|
|
25
25
|
* an errored *assistant* message, else `[]`
|
|
26
26
|
* - `tool_execution_start` → one `tool_start` { id, name }
|
|
27
|
-
* - `tool_execution_update` → `
|
|
27
|
+
* - `tool_execution_update` → one `tool_update` { id, name, details } — the
|
|
28
|
+
* running tool's partial-result detail (e.g. the
|
|
29
|
+
* live `◆ Workflow` snapshot) re-projected so the
|
|
30
|
+
* console can update the transcript in place
|
|
28
31
|
* - `tool_execution_end` → one `tool_end` { id, ok: !isError }
|
|
29
32
|
* - `turn_end` → one `turn_end` { usage }
|
|
30
33
|
* - `message_update` → delegated to the inner streaming dispatch on
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared "does the user have a usable credential for this provider" probe.
|
|
3
|
+
*
|
|
4
|
+
* Used anywhere the console needs to know which providers are actually
|
|
5
|
+
* callable — the `/model` picker (only list authenticated providers) and the
|
|
6
|
+
* banner's Session panel (don't display an unauthenticated model as if it were
|
|
7
|
+
* ready to use) both need the exact same answer, so it lives here once.
|
|
8
|
+
*/
|
|
9
|
+
import type { OverlayServices } from "./contract";
|
|
10
|
+
/**
|
|
11
|
+
* Load the set of provider ids the user has USABLE credentials for, live, so a
|
|
12
|
+
* mid-session `/login` (either a local vault sign-in or the "Indus Server"
|
|
13
|
+
* server-tier device flow) is reflected without a restart.
|
|
14
|
+
*
|
|
15
|
+
* Two independent sources count: (1) any saved account in the local vault for a
|
|
16
|
+
* provider `listLoginProviders()` names, and (2) a valid server session token,
|
|
17
|
+
* which makes every gateway-eligible provider (`serverTierProviders()` —
|
|
18
|
+
* minimax, sarvam) usable even though the server tier never writes into the
|
|
19
|
+
* vault. Returns `null` until the asynchronous probe settles.
|
|
20
|
+
*
|
|
21
|
+
* `refreshKey` re-runs the probe whenever it changes by reference/value — a
|
|
22
|
+
* short-lived overlay (the `/model` picker) can leave it at its default since
|
|
23
|
+
* it remounts fresh on every open anyway, but a component mounted once for the
|
|
24
|
+
* whole session (the banner, the status bar) MUST pass something that changes
|
|
25
|
+
* right when a sign-in completes (e.g. the console's current status toast),
|
|
26
|
+
* otherwise this only ever reflects whatever was true at session start.
|
|
27
|
+
*/
|
|
28
|
+
export declare function useAuthenticatedProviders(services: OverlayServices | undefined, refreshKey?: unknown): Set<string> | null;
|
|
@@ -0,0 +1,41 @@
|
|
|
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;
|
|
@@ -0,0 +1,63 @@
|
|
|
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;
|
|
@@ -0,0 +1,8 @@
|
|
|
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,18 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Banner — the masthead the console renders above the
|
|
2
|
+
* Banner — the "IndusCode Saffron" masthead the console renders above the
|
|
3
|
+
* transcript.
|
|
3
4
|
*
|
|
4
|
-
* The startup chrome the surface mounts
|
|
5
|
-
*
|
|
6
|
-
* with the accent/signal role, a version + brand line beneath it, and a compact
|
|
7
|
-
* bordered "Session" panel of at-a-glance facts (the bound model id and the
|
|
8
|
-
* working directory). It reads nothing but its props, holds no state, and runs
|
|
9
|
-
* no effects — purely presentational Ink primitives themed through the framework
|
|
10
|
-
* {@link InkThemeAdapter}.
|
|
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}:
|
|
11
7
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
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.
|
|
16
28
|
*/
|
|
17
29
|
import { type InkThemeAdapter } from "indusagi/react-ink";
|
|
18
30
|
import type { StartupChangelog, StartupMap, StartupNotice } from "../startup";
|
|
@@ -26,19 +38,27 @@ export interface BannerProps {
|
|
|
26
38
|
readonly workspace: string;
|
|
27
39
|
/** The product version shown on the brand line (e.g. the package VERSION). */
|
|
28
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;
|
|
29
50
|
/** Whether to render the extra diagnostics line. */
|
|
30
51
|
readonly verbose?: boolean;
|
|
31
52
|
/**
|
|
32
|
-
* When set, the
|
|
33
|
-
*
|
|
53
|
+
* When set, the welcome card is suppressed in favour of a single compact
|
|
54
|
+
* header line. Wired from the verbose / quiet-startup flag.
|
|
34
55
|
*/
|
|
35
56
|
readonly quiet?: boolean;
|
|
36
57
|
/**
|
|
37
58
|
* When set, the masthead auto-condenses to a single emblem + brand + model
|
|
38
|
-
* line (the repeat-launch presentation)
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* banner, but `compact` keeps the small emblem and the welcome line.
|
|
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.
|
|
42
62
|
*/
|
|
43
63
|
readonly compact?: boolean;
|
|
44
64
|
/**
|
|
@@ -47,15 +67,30 @@ export interface BannerProps {
|
|
|
47
67
|
*/
|
|
48
68
|
readonly name?: string;
|
|
49
69
|
/**
|
|
50
|
-
* Opt-in static colour-sweep flourish
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* non-TTY; this prop is simply the resolved on/off decision.
|
|
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.
|
|
54
73
|
*/
|
|
55
74
|
readonly sweep?: boolean;
|
|
56
|
-
/**
|
|
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
|
+
*/
|
|
57
92
|
readonly startup?: StartupMap;
|
|
58
|
-
/** Out-of-band lines drawn above the
|
|
93
|
+
/** Out-of-band lines drawn above the card (errors, warnings, info). */
|
|
59
94
|
readonly notices?: readonly StartupNotice[];
|
|
60
95
|
/** The changelog survey rendered as a "What is new" block on a version bump. */
|
|
61
96
|
readonly changelog?: StartupChangelog;
|
|
@@ -63,14 +98,13 @@ export interface BannerProps {
|
|
|
63
98
|
/**
|
|
64
99
|
* Render the console masthead.
|
|
65
100
|
*
|
|
66
|
-
* In the default (loud) mode this is the
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* all of that to a single compact header line
|
|
71
|
-
*
|
|
72
|
-
* changelog so nothing important is silently dropped.
|
|
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.
|
|
73
107
|
*
|
|
74
|
-
* @param props the
|
|
108
|
+
* @param props the brand/version context, session facts, and startup chrome
|
|
75
109
|
*/
|
|
76
|
-
export declare function Banner({ theme, modelId, workspace, version,
|
|
110
|
+
export declare function Banner({ theme, modelId, workspace, version, started, branch, quiet, compact, name, variantSeed, whatsNew, notices, changelog, }: BannerProps): JSX.Element;
|
|
@@ -24,9 +24,4 @@
|
|
|
24
24
|
* `indusagi/react-ink`.
|
|
25
25
|
*/
|
|
26
26
|
import type { ConsoleProps } from "../contract";
|
|
27
|
-
/**
|
|
28
|
-
* The interactive console surface.
|
|
29
|
-
*
|
|
30
|
-
* @param props the conductor to drive, the resolved theme, and the slash registry
|
|
31
|
-
*/
|
|
32
27
|
export declare function TerminalConsole(props: ConsoleProps): JSX.Element;
|