@multiclawcli/core 0.3.2 → 0.5.0

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 (81) hide show
  1. package/dist/agents/arch-design-reviewer.d.ts +4 -0
  2. package/dist/agents/architect.d.ts +4 -0
  3. package/dist/agents/backend-developer.d.ts +4 -0
  4. package/dist/agents/code-reviewer.d.ts +4 -0
  5. package/dist/agents/devops.d.ts +4 -0
  6. package/dist/agents/frontend-developer.d.ts +4 -0
  7. package/dist/agents/index.d.ts +26 -0
  8. package/dist/agents/leader.d.ts +4 -0
  9. package/dist/agents/product-manager.d.ts +4 -0
  10. package/dist/agents/reviewer.d.ts +4 -0
  11. package/dist/agents/tester.d.ts +4 -0
  12. package/dist/agents/ui-design-reviewer.d.ts +4 -0
  13. package/dist/agents/ui-designer.d.ts +4 -0
  14. package/dist/config/defineConfig.d.ts +2 -0
  15. package/dist/event/EventBus.d.ts +7 -0
  16. package/dist/index.d.ts +11 -0
  17. package/dist/index.js +2207 -811
  18. package/dist/orchestrator/AgentRunner.d.ts +19 -0
  19. package/dist/orchestrator/ContextManager.d.ts +7 -0
  20. package/dist/orchestrator/Orchestrator.d.ts +109 -0
  21. package/dist/orchestrator/StageBuilder.d.ts +2 -0
  22. package/dist/providers/bridge.d.ts +29 -0
  23. package/dist/providers/catalog.d.ts +73 -0
  24. package/dist/providers/detect.d.ts +34 -0
  25. package/dist/providers/index.d.ts +4 -0
  26. package/dist/providers/resolve.d.ts +26 -0
  27. package/dist/runtime/AcpRuntime.d.ts +17 -0
  28. package/dist/runtime/RuntimeBase.d.ts +6 -0
  29. package/dist/runtime/index.d.ts +12 -0
  30. package/dist/types/agent.d.ts +96 -0
  31. package/dist/types/config.d.ts +126 -0
  32. package/dist/types/event.d.ts +115 -0
  33. package/dist/types/index.d.ts +5 -0
  34. package/dist/types/leader.d.ts +36 -0
  35. package/dist/types/runtime.d.ts +146 -0
  36. package/dist/utils/abort.d.ts +4 -0
  37. package/dist/utils/conversation.d.ts +29 -0
  38. package/dist/utils/errors.d.ts +16 -0
  39. package/dist/utils/json.d.ts +10 -0
  40. package/dist/utils/leaderDecision.d.ts +17 -0
  41. package/dist/utils/prompt.d.ts +1 -0
  42. package/dist/utils/resumePlan.d.ts +35 -0
  43. package/dist/utils/retry.d.ts +36 -0
  44. package/dist/utils/timeout.d.ts +1 -0
  45. package/dist/utils/toolSummary.d.ts +13 -0
  46. package/dist/utils/upstream.d.ts +69 -0
  47. package/package.json +18 -4
  48. package/src/agents/arch-design-reviewer.ts +0 -45
  49. package/src/agents/architect.ts +0 -72
  50. package/src/agents/backend-developer.ts +0 -54
  51. package/src/agents/code-reviewer.ts +0 -54
  52. package/src/agents/devops.ts +0 -59
  53. package/src/agents/frontend-developer.ts +0 -56
  54. package/src/agents/index.ts +0 -27
  55. package/src/agents/leader.ts +0 -37
  56. package/src/agents/product-manager.ts +0 -43
  57. package/src/agents/reviewer.ts +0 -47
  58. package/src/agents/tester.ts +0 -53
  59. package/src/agents/ui-design-reviewer.ts +0 -48
  60. package/src/agents/ui-designer.ts +0 -61
  61. package/src/config/defineConfig.ts +0 -4
  62. package/src/event/EventBus.ts +0 -19
  63. package/src/index.ts +0 -8
  64. package/src/orchestrator/AgentRunner.ts +0 -104
  65. package/src/orchestrator/ContextManager.ts +0 -11
  66. package/src/orchestrator/Orchestrator.ts +0 -180
  67. package/src/orchestrator/StageBuilder.ts +0 -30
  68. package/src/runtime/ClaudeRuntime.ts +0 -41
  69. package/src/runtime/RuntimeBase.ts +0 -7
  70. package/src/runtime/index.ts +0 -20
  71. package/src/types/agent.ts +0 -48
  72. package/src/types/config.ts +0 -26
  73. package/src/types/event.ts +0 -21
  74. package/src/types/index.ts +0 -4
  75. package/src/types/runtime.ts +0 -23
  76. package/src/utils/prompt.ts +0 -24
  77. package/src/utils/retry.ts +0 -24
  78. package/src/utils/timeout.ts +0 -16
  79. package/tsconfig.build.json +0 -9
  80. package/tsconfig.json +0 -5
  81. package/tsup.config.ts +0 -10
@@ -0,0 +1,19 @@
1
+ import type { EventBus } from "../event/EventBus";
2
+ import type { AgentDefinition, AgentResult } from "../types/agent";
3
+ import type { MultiClawConfig } from "../types/config";
4
+ import type { ContextManager } from "./ContextManager";
5
+ export declare class AgentRunner {
6
+ private eventBus;
7
+ private contextManager;
8
+ private globalWorkDir;
9
+ private config;
10
+ constructor(eventBus: EventBus, contextManager: ContextManager, globalWorkDir: string, config: MultiClawConfig);
11
+ run(agent: AgentDefinition, signal?: AbortSignal): Promise<AgentResult>;
12
+ /**
13
+ * Publish one chunk of agent output.
14
+ *
15
+ * `kind` is omitted for text so the payload shape is unchanged for every
16
+ * consumer written before tool activity was surfaced.
17
+ */
18
+ private emitOutput;
19
+ }
@@ -0,0 +1,7 @@
1
+ export declare class ContextManager {
2
+ private store;
3
+ constructor(initial?: Record<string, string>);
4
+ set(key: string, value: string): void;
5
+ get(key: string): string | undefined;
6
+ snapshot(): Record<string, string>;
7
+ }
@@ -0,0 +1,109 @@
1
+ import { EventBus } from "../event/EventBus";
2
+ import type { MultiClawConfig, OrchestrationPreview, OrchestratorResult } from "../types/config";
3
+ export declare class Orchestrator {
4
+ private config;
5
+ readonly eventBus: EventBus;
6
+ private contextManager;
7
+ private runner;
8
+ private workDir;
9
+ constructor(config: MultiClawConfig);
10
+ preview(options?: {
11
+ signal?: AbortSignal;
12
+ }): Promise<OrchestrationPreview>;
13
+ run(options?: {
14
+ signal?: AbortSignal;
15
+ }): Promise<OrchestratorResult>;
16
+ private stageInfos;
17
+ /**
18
+ * Order the agents into stages, degrading to declaration order if the graph is
19
+ * broken.
20
+ *
21
+ * `buildStages` throws on a missing dependency and on a cycle. Letting that
22
+ * escape would reject `run()` before `orchestration:complete` is emitted, so
23
+ * the caller sees an unhandled rejection instead of a structured failure. A
24
+ * bad ordering is not a reason to run nothing.
25
+ */
26
+ private buildStagesOrFallback;
27
+ /**
28
+ * Drop last run's task plan before the architect gets a chance to write one.
29
+ *
30
+ * The console runs every turn against the same workspace, so the plan file
31
+ * survives between turns. If a turn's architect fails to write a new one,
32
+ * `applyTaskPlan` would silently re-apply the previous turn's titles, scopes
33
+ * and dependencies to a completely different requirement.
34
+ */
35
+ private clearStaleTaskPlan;
36
+ /**
37
+ * Decide what this turn is: a pipeline, an answer, or a question.
38
+ *
39
+ * Only the leader can answer that, so without one the configured team is the
40
+ * whole story. With one, its prose output is *not* a failure mode to be papered
41
+ * over by running everybody — a leader that answers a greeting has done its
42
+ * job, and that is what `message` records.
43
+ */
44
+ private resolveTurn;
45
+ /**
46
+ * The configured team, as copies.
47
+ *
48
+ * `applyTaskPlan` writes `taskTitle` / `dependsOn` / `agentScope` onto whatever
49
+ * objects it is handed. The console reuses a single config across turns, so
50
+ * returning the config's own objects would leak turn 1's dependency graph into
51
+ * turn 2 — the exact cross-turn contamination `clearStaleTaskPlan` exists to
52
+ * prevent, but for the in-memory fields rather than the file.
53
+ */
54
+ private configuredAgents;
55
+ /**
56
+ * Narrow the configured team to the ids `namedBy` asked for.
57
+ *
58
+ * Always a subset: an id that is not in the config is reported and dropped
59
+ * rather than added, so a typo in a prompt cannot conjure an agent that has no
60
+ * definition behind it.
61
+ *
62
+ * `namedBy` labels the warning. A resume names agents too — with no leader in
63
+ * the run at all — so blaming "the leader" for a bad resumed id would send the
64
+ * reader looking in the wrong place.
65
+ */
66
+ private selectAgents;
67
+ private runStage;
68
+ /**
69
+ * Whether `agent` owns task decomposition.
70
+ *
71
+ * The explicit `role` is the source of truth, so a config can name its planner
72
+ * anything. The id `"architect"` is kept as a fallback so every config written
73
+ * before `role` existed keeps working unchanged.
74
+ */
75
+ private isPlanner;
76
+ private applyTaskPlan;
77
+ /**
78
+ * The `requirement` field for a result, present only when the caller set one.
79
+ *
80
+ * Spread into every result builder so all three outcomes carry it the same
81
+ * way: a completion event doubles as the report a resume driver reads back,
82
+ * and a requirement that never reaches the report cannot be resumed.
83
+ */
84
+ private requirementField;
85
+ /**
86
+ * The `selectionReason` field, present only when the leader explained itself.
87
+ *
88
+ * Omitted rather than sent as `undefined`/`""` so a run without an
89
+ * explanation stays byte-identical to one from before the field existed.
90
+ */
91
+ private reasonField;
92
+ /**
93
+ * Close out a turn the leader answered rather than planned.
94
+ *
95
+ * `success: true` on purpose: the user asked something and got an answer. What
96
+ * keeps that from reading as a completed pipeline is `reply`, which the console
97
+ * uses to say "answered" instead of "done".
98
+ */
99
+ private finishWithMessage;
100
+ private warn;
101
+ /**
102
+ * Close out a turn that scheduled no agents.
103
+ *
104
+ * Reported as a failure rather than a no-op: the user asked for work, and the
105
+ * only honest outcome is to say that none was done. Running the whole team
106
+ * instead would contradict the leader's explicit choice.
107
+ */
108
+ private finishEmpty;
109
+ }
@@ -0,0 +1,2 @@
1
+ import type { AgentDefinition } from "../types/agent";
2
+ export declare function buildStages(agents: AgentDefinition[]): AgentDefinition[][];
@@ -0,0 +1,29 @@
1
+ /**
2
+ * ACP bridges that multiclaw bundles and resolves from its own `node_modules`
3
+ * rather than requiring the user to install them globally.
4
+ *
5
+ * Key = the binary name used in an agent's `command`; value = the npm package
6
+ * that provides it. `opencode` is deliberately absent: it speaks ACP natively,
7
+ * so it *is* the user's agent and is installed by the user.
8
+ */
9
+ export declare const BRIDGE_PACKAGES: Record<string, string>;
10
+ /** True when `command` names an executable file on PATH. */
11
+ export declare function resolvesOnPath(command: string): boolean;
12
+ /**
13
+ * Resolve a bundled bridge binary to an absolute path inside multiclaw's
14
+ * installed `node_modules`. Returns null when `command` is not a bridge we
15
+ * bundle (e.g. a user-supplied binary such as `opencode`).
16
+ *
17
+ * This lets multiclaw drive the ACP bridge without it being on the user's PATH:
18
+ * the user only installs their own agent (`claude` / `codex` / `opencode`), and
19
+ * multiclaw supplies the thin bridge in front of it.
20
+ */
21
+ export declare function resolveBridgeBinary(command: string): string | null;
22
+ /**
23
+ * Resolve the executable multiclaw should spawn for `command`.
24
+ *
25
+ * Prefers the user's own install on PATH (this is also what the test suite
26
+ * relies on — fake binaries are placed on PATH), and falls back to a bridge
27
+ * multiclaw bundles. Returns null when neither is available.
28
+ */
29
+ export declare function resolveExecutable(command: string): string | null;
@@ -0,0 +1,73 @@
1
+ import type { AgentTask } from "../types/runtime";
2
+ export type ProviderId = "claude" | "opencode" | "codex" | "cursor" | (string & {});
3
+ export type ModelTier = "strong" | "balanced" | "fast";
4
+ export interface ProviderModel {
5
+ id: string;
6
+ label: string;
7
+ tier?: ModelTier;
8
+ /** True when this model is the default for its tier within this provider. */
9
+ defaultForTier?: boolean;
10
+ }
11
+ /**
12
+ * How a provider is told which model to run.
13
+ *
14
+ * `"arg"` used to be a member here, but nothing in `AcpRuntime` ever implemented
15
+ * it — so a provider that declared it silently ran with its own default. It is
16
+ * gone rather than kept as a dead branch: re-introducing it means also
17
+ * implementing the `arg` path in `AcpRuntime`, and this note is the cost the
18
+ * next person to add it back has to pay.
19
+ */
20
+ export type ModelSelectionMode = "config-option" | "none";
21
+ export interface ProviderSpec {
22
+ id: ProviderId;
23
+ label: string;
24
+ /** Binary to spawn. */
25
+ command: string;
26
+ /** Arguments after the binary. */
27
+ args: string[];
28
+ /** Additional binary names that resolve to this provider (for detection). */
29
+ aliases?: string[];
30
+ /**
31
+ * Build the `_meta` payload for a session-defining request.
32
+ * Returns `undefined` when there is nothing to say — the role prompt
33
+ * then falls back to a prompt prefix.
34
+ */
35
+ meta?: (task: AgentTask) => Record<string, unknown> | undefined;
36
+ /** Whether this provider honours a tool allowlist at all. */
37
+ tools: boolean;
38
+ /** How model selection is communicated to the agent. */
39
+ modelSelection: ModelSelectionMode;
40
+ /** Models offered by this provider. */
41
+ models: ProviderModel[];
42
+ /** Fallback when no tier or explicit model is configured. */
43
+ defaultModel: string;
44
+ install: {
45
+ hint: string;
46
+ url?: string;
47
+ };
48
+ /** Auth prerequisite — shown as a hint, not a hard gate (v1). */
49
+ auth: {
50
+ kind: "ambient" | "login" | "api-key" | "none";
51
+ hint: string;
52
+ };
53
+ /**
54
+ * When the binary name is ambiguous (e.g. cursor's `agent`),
55
+ * use `--version` output to confirm identity. Mandatory for generic names.
56
+ */
57
+ confirm?: (versionOutput: string) => boolean;
58
+ }
59
+ export declare const PROVIDERS: readonly ProviderSpec[];
60
+ /** Lookup a provider by its id. */
61
+ export declare function specForProvider(id: string): ProviderSpec | undefined;
62
+ /**
63
+ * Lookup a provider by the binary name it is launched with.
64
+ * Keys on basename (strips paths and Windows suffixes) so
65
+ * `/opt/bin/claude-agent-acp` and `claude-agent-acp.exe` both hit.
66
+ */
67
+ export declare function specForCommand(command: string): ProviderSpec | undefined;
68
+ /** All provider ids known to the catalog. */
69
+ export declare function providerIds(): string[];
70
+ /** All commands (primary + aliases) that map to a provider. */
71
+ export declare function providerCommands(): string[];
72
+ /** Resolve a tier to a concrete model id for a given provider. */
73
+ export declare function tierModel(spec: ProviderSpec, tier: ModelTier): string | undefined;
@@ -0,0 +1,34 @@
1
+ export type ProviderStatus = "present" | "missing";
2
+ /**
3
+ * Where the executable for a present provider came from.
4
+ *
5
+ * `path` is the user's own install on PATH — the expected case. `bundled` means
6
+ * multiclaw's own `node_modules` supplied the bridge, so the provider works
7
+ * without the bridge being installed globally; that is worth telling the user,
8
+ * because "present" then says nothing about what they have installed.
9
+ */
10
+ export type ProviderSource = "path" | "bundled";
11
+ export interface DetectedProvider {
12
+ id: string;
13
+ label: string;
14
+ command: string;
15
+ status: ProviderStatus;
16
+ version?: string;
17
+ note?: string;
18
+ /** How the executable resolves. Absent for a missing provider. */
19
+ source?: ProviderSource;
20
+ /** Absolute path actually spawned, set only for a bundled bridge. */
21
+ resolvedPath?: string;
22
+ }
23
+ /**
24
+ * Discover which providers are installed on this machine.
25
+ *
26
+ * Availability comes from PATH lookups (fast, no spawn). When
27
+ * `withVersion` is true, ambiguous binary names (e.g. cursor's `agent`)
28
+ * are confirmed via `--version` output.
29
+ */
30
+ export declare function detectProviders(opts?: {
31
+ withVersion?: boolean;
32
+ }): Promise<DetectedProvider[]>;
33
+ /** Just the ids of providers that are present. */
34
+ export declare function presentProviders(detected: DetectedProvider[]): string[];
@@ -0,0 +1,4 @@
1
+ export { BRIDGE_PACKAGES, resolveBridgeBinary, resolveExecutable, resolvesOnPath, } from "./bridge";
2
+ export { type ModelSelectionMode, type ModelTier, PROVIDERS, type ProviderId, type ProviderModel, type ProviderSpec, providerCommands, providerIds, specForCommand, specForProvider, tierModel, } from "./catalog";
3
+ export { type DetectedProvider, detectProviders, type ProviderSource, type ProviderStatus, presentProviders, } from "./detect";
4
+ export { resolveAgentRuntime, resolveArgs, resolveCommand, resolveModel, resolveProvider, } from "./resolve";
@@ -0,0 +1,26 @@
1
+ import type { AgentDefinition } from "../types/agent";
2
+ import type { MultiClawConfig } from "../types/config";
3
+ import { type ProviderSpec } from "./catalog";
4
+ /** Resolve the provider id for an agent, falling back through config defaults. */
5
+ export declare function resolveProvider(agent: AgentDefinition, config: MultiClawConfig): string;
6
+ /** Resolve the launch command for an agent. */
7
+ export declare function resolveCommand(agent: AgentDefinition, config: MultiClawConfig): string;
8
+ /**
9
+ * Resolve the launch arguments for an agent.
10
+ *
11
+ * Paired with {@link resolveCommand}: the catalog carries per-provider args
12
+ * (`opencode acp` needs `["acp"]`, the bundled bridges need `[]`), so leaving
13
+ * `args` undefined would let the runtime fall back to its `["acp"]` default and
14
+ * launch e.g. `claude-agent-acp acp`. Returns undefined for a truly custom
15
+ * command so the runtime's default still applies.
16
+ */
17
+ export declare function resolveArgs(agent: AgentDefinition, config: MultiClawConfig): string[] | undefined;
18
+ /** Resolve the model id an agent will actually run with. */
19
+ export declare function resolveModel(agent: AgentDefinition, config: MultiClawConfig): string | undefined;
20
+ /** Convenience: full resolution in one call. */
21
+ export declare function resolveAgentRuntime(agent: AgentDefinition, config: MultiClawConfig): {
22
+ provider: string;
23
+ command: string;
24
+ model: string | undefined;
25
+ spec: ProviderSpec | undefined;
26
+ };
@@ -0,0 +1,17 @@
1
+ import type { AgentOutput, AgentTask, RuntimeInfo, RuntimeQuery } from "../types/runtime";
2
+ import { RuntimeBase } from "./RuntimeBase";
3
+ /**
4
+ * Grace period between SIGTERM and SIGKILL when an agent will not stop.
5
+ *
6
+ * This is time a single attempt can still consume *after* its `timeout`: the
7
+ * inner timeout fires a SIGTERM, and a child that ignores it is not reaped until
8
+ * this grace elapses — the reject itself lands on the child's `close`. A caller
9
+ * that budgets for a whole retry sequence must therefore add this to the
10
+ * per-attempt timeout, or its "upper bound" is not one (see `retryBudgetMs`).
11
+ */
12
+ export declare const KILL_ESCALATION_MS = 3000;
13
+ export declare class AcpRuntime extends RuntimeBase {
14
+ readonly name = "acp";
15
+ describe(options?: RuntimeQuery): Promise<RuntimeInfo>;
16
+ execute(task: AgentTask): Promise<AgentOutput>;
17
+ }
@@ -0,0 +1,6 @@
1
+ import type { AgentOutput, AgentRuntime, AgentTask, RuntimeInfo, RuntimeQuery } from "../types/runtime";
2
+ export declare abstract class RuntimeBase implements AgentRuntime {
3
+ abstract readonly name: string;
4
+ abstract describe(options?: RuntimeQuery): Promise<RuntimeInfo>;
5
+ abstract execute(task: AgentTask): Promise<AgentOutput>;
6
+ }
@@ -0,0 +1,12 @@
1
+ import type { AgentRuntime } from "../types/runtime";
2
+ import { AcpRuntime, KILL_ESCALATION_MS } from "./AcpRuntime";
3
+ declare class RuntimeRegistry {
4
+ private runtimes;
5
+ constructor();
6
+ register(r: AgentRuntime): void;
7
+ get(name: string): AgentRuntime;
8
+ has(name: string): boolean;
9
+ list(): string[];
10
+ }
11
+ export declare const runtimeRegistry: RuntimeRegistry;
12
+ export { AcpRuntime, KILL_ESCALATION_MS };
@@ -0,0 +1,96 @@
1
+ import type { AgentOutput } from "./runtime";
2
+ export type ToolName = "Read" | "Write" | "Edit" | "MultiEdit" | "Bash" | "Glob" | "Grep" | "WebFetch";
3
+ export interface AgentDefinition {
4
+ id: string;
5
+ name: string;
6
+ icon?: string;
7
+ runtime?: string;
8
+ /**
9
+ * Agent product (e.g. "claude", "opencode", "codex", "cursor").
10
+ * Distinct from `runtime` (the protocol, always "acp" today).
11
+ * When absent it is inferred from `command` or config defaults.
12
+ */
13
+ provider?: string;
14
+ /**
15
+ * Command to launch for this agent's runtime, when the runtime talks to an
16
+ * external process (e.g. ACP). Generic — "which binary to start", not a
17
+ * protocol detail — so a built-in runtime simply ignores it.
18
+ */
19
+ command?: string;
20
+ /** Arguments for {@link command}. */
21
+ args?: string[];
22
+ model?: string;
23
+ /**
24
+ * Map of provider ids (or the legacy alias "acp") to model names.
25
+ * Provider id is preferred; "acp" is kept for backward compatibility.
26
+ */
27
+ models?: Partial<Record<string, string>>;
28
+ /**
29
+ * Model tier preference. Used when `model` and `models` are absent.
30
+ * The catalog maps each tier to a provider-specific model id.
31
+ */
32
+ modelTier?: "strong" | "balanced" | "fast";
33
+ systemPrompt: string;
34
+ taskPrompt: string;
35
+ /**
36
+ * One-line role, for display. Every built-in agent declares one.
37
+ *
38
+ * Distinct from {@link taskTitle}, which the orchestrator fills in per turn
39
+ * from the leader's task plan — "what this agent was asked to do *this* run".
40
+ * A `description` is "what this agent is for", so it is the one that is still
41
+ * available before the first turn has been planned.
42
+ */
43
+ description?: string;
44
+ /**
45
+ * Marks the agent that owns task decomposition (writes task-plan.json).
46
+ * When absent, the orchestrator falls back to the id "architect" so every
47
+ * existing config keeps working unchanged.
48
+ */
49
+ role?: "planner";
50
+ taskTitle?: string;
51
+ agentScope?: string;
52
+ agentPlan?: string;
53
+ tools?: ToolName[];
54
+ dependsOn?: string[];
55
+ timeout?: number;
56
+ retries?: number;
57
+ workDir?: string;
58
+ }
59
+ export type AgentStatus = "pending" | "running" | "retrying" | "success" | "failed"
60
+ /**
61
+ * The run was stopped by its AbortSignal rather than finishing or erroring.
62
+ * Distinct from `failed` so a Ctrl-C does not read as a crash, and so the
63
+ * roster can mark the agent stopped instead of broken.
64
+ */
65
+ | "cancelled" | "skipped";
66
+ export interface AgentResult {
67
+ agentId: string;
68
+ agentName: string;
69
+ status: AgentStatus;
70
+ output: string;
71
+ duration: number;
72
+ attempts: number;
73
+ error?: string;
74
+ startTime: string;
75
+ endTime: string;
76
+ /** Model actually requested for this agent. */
77
+ model?: string;
78
+ /** Context-window usage the runtime reported; absent when it reported none. */
79
+ usage?: AgentOutput["usage"];
80
+ /** USD cost the runtime reported; absent when the provider does not price in USD. */
81
+ costUsd?: number;
82
+ /** Session the runtime ran under, when it reported one. */
83
+ sessionId?: string;
84
+ }
85
+ export interface SubTask {
86
+ id: string;
87
+ title: string;
88
+ scope: string;
89
+ plan?: string[];
90
+ dependsOn?: string[];
91
+ }
92
+ export interface TaskPlan {
93
+ projectName: string;
94
+ requirement: string;
95
+ tasks: SubTask[];
96
+ }
@@ -0,0 +1,126 @@
1
+ import type { AgentDefinition } from "./agent";
2
+ import type { LeaderMessage } from "./leader";
3
+ /**
4
+ * One finished turn of a session, as dialogue the leader can read back.
5
+ *
6
+ * A requirement alone is not always interpretable: when the leader asked "which
7
+ * database?" and the user answered "Postgres", turn two's requirement is the
8
+ * bare word "Postgres". Paired with the turn that produced the question it is
9
+ * obvious; on its own it is not.
10
+ */
11
+ export interface TurnRecord {
12
+ /** What the user asked for. */
13
+ requirement: string;
14
+ /** How the turn ended in words, when it ended that way. */
15
+ reply?: LeaderMessage;
16
+ }
17
+ export interface MultiClawConfig {
18
+ name: string;
19
+ workDir: string;
20
+ leader?: AgentDefinition;
21
+ agents: AgentDefinition[];
22
+ context?: Record<string, string>;
23
+ /**
24
+ * Earlier turns of this session, oldest first.
25
+ *
26
+ * Core has no notion of a session — the orchestrator is built fresh per turn —
27
+ * so whoever runs several turns in a row (the console) is the one that has to
28
+ * carry them. Rendered into the leader's prompt; a single-turn run leaves it
29
+ * unset and sees no conversation at all.
30
+ */
31
+ history?: TurnRecord[];
32
+ /**
33
+ * Re-run a known set of agents instead of letting the leader route, continuing
34
+ * their sessions where one is known.
35
+ *
36
+ * Set by a resume/retry driver — the CLI's `--resume`, the console's `/retry` —
37
+ * which already knows which agents to redo. Like `history`, it is per-run state
38
+ * the caller carries: core has no session of its own, and a config that never
39
+ * resumes leaves it unset and behaves exactly as before.
40
+ */
41
+ resume?: {
42
+ /** Agent ids to run, in the order they were originally selected. */
43
+ agents: string[];
44
+ /** agentId → session id, for agents whose session is worth continuing. */
45
+ sessions?: Record<string, string>;
46
+ };
47
+ logDir?: string;
48
+ continueOnError?: boolean;
49
+ maxConcurrency?: number;
50
+ useLeader?: boolean;
51
+ /**
52
+ * Project-level defaults applied to every agent that does not override them.
53
+ * Keeps generated configs readable: one line instead of 12 repeated parameters.
54
+ */
55
+ defaults?: {
56
+ provider?: string;
57
+ model?: string;
58
+ command?: string;
59
+ };
60
+ }
61
+ export interface OrchestrationPreview {
62
+ name: string;
63
+ requirement?: string;
64
+ totalAgents: number;
65
+ stages: import("./event").StageInfo[];
66
+ /** Present when the leader answered or asked instead of choosing a pipeline. */
67
+ reply?: LeaderMessage;
68
+ /** The leader's explanation for the agent set, when it gave one. */
69
+ selectionReason?: string;
70
+ }
71
+ export interface DeliverableSummary {
72
+ /** Path relative to the run work directory. */
73
+ path: string;
74
+ status: "created" | "modified";
75
+ size: number;
76
+ modifiedAt: string;
77
+ }
78
+ export interface OrchestratorResult {
79
+ name: string;
80
+ success: boolean;
81
+ totalDuration: number;
82
+ agentResults: import("./agent").AgentResult[];
83
+ startTime: string;
84
+ endTime: string;
85
+ /**
86
+ * Set when the run was stopped via its AbortSignal. Cancellation is a third
87
+ * outcome, not a flavour of failure: the team stopped because it was told to.
88
+ * It still reports `success: false` — a run that never finished must not exit
89
+ * 0 — but the console says "cancelled" rather than "failed", and the CLI can
90
+ * exit with the conventional 130.
91
+ */
92
+ cancelled?: boolean;
93
+ /**
94
+ * Set when the turn ended in words instead of a pipeline — the leader answered
95
+ * or asked a question, so no agent ran. Without it, "the team worked and
96
+ * succeeded" and "nobody worked" look identical: both are `success: true` with
97
+ * an empty `agentResults`.
98
+ */
99
+ reply?: LeaderMessage;
100
+ /**
101
+ * The leader's explanation for the agent set it selected, when it gave one.
102
+ *
103
+ * This is orchestration metadata, not agent state: it answers "why did this
104
+ * turn run these agents?" without asking the leader again. Absent for a
105
+ * resumed run, a leader-less run, and any leader that omitted the field.
106
+ */
107
+ selectionReason?: string;
108
+ /**
109
+ * Sum of the per-agent costs that were actually reported, in USD.
110
+ *
111
+ * Present only when at least one agent reported a cost — "no data" is not the
112
+ * same as "free", so a run in which nobody priced itself must leave this
113
+ * `undefined` rather than reporting `0`.
114
+ */
115
+ totalCostUsd?: number;
116
+ /**
117
+ * The requirement this turn was run for, when the caller supplied one.
118
+ *
119
+ * Carried on the result because the completion event *is* the report a resume
120
+ * driver reads back: without it, a resumed run has no way to recover the
121
+ * requirement it is continuing.
122
+ */
123
+ requirement?: string;
124
+ /** Files created or modified by this run, when the caller collected them. */
125
+ deliverables?: DeliverableSummary[];
126
+ }