maestro-agent-sdk 0.1.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 (196) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +24 -0
  3. package/README.md +133 -0
  4. package/dist/agents/contracts.d.ts +49 -0
  5. package/dist/agents/contracts.d.ts.map +1 -0
  6. package/dist/agents/contracts.js +2 -0
  7. package/dist/agents/contracts.js.map +1 -0
  8. package/dist/agents/rollout/shared.d.ts +24 -0
  9. package/dist/agents/rollout/shared.d.ts.map +1 -0
  10. package/dist/agents/rollout/shared.js +105 -0
  11. package/dist/agents/rollout/shared.js.map +1 -0
  12. package/dist/core/agent.d.ts +71 -0
  13. package/dist/core/agent.d.ts.map +1 -0
  14. package/dist/core/agent.js +22 -0
  15. package/dist/core/agent.js.map +1 -0
  16. package/dist/core/loop.d.ts +26 -0
  17. package/dist/core/loop.d.ts.map +1 -0
  18. package/dist/core/loop.js +317 -0
  19. package/dist/core/loop.js.map +1 -0
  20. package/dist/index.d.ts +49 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +53 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/mcp/client.d.ts +79 -0
  25. package/dist/mcp/client.d.ts.map +1 -0
  26. package/dist/mcp/client.js +176 -0
  27. package/dist/mcp/client.js.map +1 -0
  28. package/dist/mcp/pool-cache.d.ts +103 -0
  29. package/dist/mcp/pool-cache.d.ts.map +1 -0
  30. package/dist/mcp/pool-cache.js +249 -0
  31. package/dist/mcp/pool-cache.js.map +1 -0
  32. package/dist/mcp/pool.d.ts +65 -0
  33. package/dist/mcp/pool.d.ts.map +1 -0
  34. package/dist/mcp/pool.js +86 -0
  35. package/dist/mcp/pool.js.map +1 -0
  36. package/dist/media/file-events.d.ts +8 -0
  37. package/dist/media/file-events.d.ts.map +1 -0
  38. package/dist/media/file-events.js +15 -0
  39. package/dist/media/file-events.js.map +1 -0
  40. package/dist/memory/active-task-template.d.ts +34 -0
  41. package/dist/memory/active-task-template.d.ts.map +1 -0
  42. package/dist/memory/active-task-template.js +63 -0
  43. package/dist/memory/active-task-template.js.map +1 -0
  44. package/dist/memory/compressor.d.ts +87 -0
  45. package/dist/memory/compressor.d.ts.map +1 -0
  46. package/dist/memory/compressor.js +164 -0
  47. package/dist/memory/compressor.js.map +1 -0
  48. package/dist/memory/hash.d.ts +17 -0
  49. package/dist/memory/hash.d.ts.map +1 -0
  50. package/dist/memory/hash.js +20 -0
  51. package/dist/memory/hash.js.map +1 -0
  52. package/dist/memory/prune.d.ts +117 -0
  53. package/dist/memory/prune.d.ts.map +1 -0
  54. package/dist/memory/prune.js +416 -0
  55. package/dist/memory/prune.js.map +1 -0
  56. package/dist/memory/reminder.d.ts +57 -0
  57. package/dist/memory/reminder.d.ts.map +1 -0
  58. package/dist/memory/reminder.js +57 -0
  59. package/dist/memory/reminder.js.map +1 -0
  60. package/dist/memory/scrubber.d.ts +28 -0
  61. package/dist/memory/scrubber.d.ts.map +1 -0
  62. package/dist/memory/scrubber.js +147 -0
  63. package/dist/memory/scrubber.js.map +1 -0
  64. package/dist/memory/token-estimate.d.ts +10 -0
  65. package/dist/memory/token-estimate.d.ts.map +1 -0
  66. package/dist/memory/token-estimate.js +69 -0
  67. package/dist/memory/token-estimate.js.map +1 -0
  68. package/dist/platform/config.d.ts +12 -0
  69. package/dist/platform/config.d.ts.map +1 -0
  70. package/dist/platform/config.js +54 -0
  71. package/dist/platform/config.js.map +1 -0
  72. package/dist/platform/jsonl.d.ts +15 -0
  73. package/dist/platform/jsonl.d.ts.map +1 -0
  74. package/dist/platform/jsonl.js +80 -0
  75. package/dist/platform/jsonl.js.map +1 -0
  76. package/dist/platform/lifecycle.d.ts +22 -0
  77. package/dist/platform/lifecycle.d.ts.map +1 -0
  78. package/dist/platform/lifecycle.js +60 -0
  79. package/dist/platform/lifecycle.js.map +1 -0
  80. package/dist/platform/logger.d.ts +26 -0
  81. package/dist/platform/logger.d.ts.map +1 -0
  82. package/dist/platform/logger.js +41 -0
  83. package/dist/platform/logger.js.map +1 -0
  84. package/dist/platform/mcp-config.d.ts +15 -0
  85. package/dist/platform/mcp-config.d.ts.map +1 -0
  86. package/dist/platform/mcp-config.js +8 -0
  87. package/dist/platform/mcp-config.js.map +1 -0
  88. package/dist/provider.d.ts +81 -0
  89. package/dist/provider.d.ts.map +1 -0
  90. package/dist/provider.js +444 -0
  91. package/dist/provider.js.map +1 -0
  92. package/dist/providers/anthropic.d.ts +132 -0
  93. package/dist/providers/anthropic.d.ts.map +1 -0
  94. package/dist/providers/anthropic.js +518 -0
  95. package/dist/providers/anthropic.js.map +1 -0
  96. package/dist/providers/base.d.ts +140 -0
  97. package/dist/providers/base.d.ts.map +1 -0
  98. package/dist/providers/base.js +2 -0
  99. package/dist/providers/base.js.map +1 -0
  100. package/dist/providers/deepseek.d.ts +118 -0
  101. package/dist/providers/deepseek.d.ts.map +1 -0
  102. package/dist/providers/deepseek.js +467 -0
  103. package/dist/providers/deepseek.js.map +1 -0
  104. package/dist/registry.d.ts +3 -0
  105. package/dist/registry.d.ts.map +1 -0
  106. package/dist/registry.js +94 -0
  107. package/dist/registry.js.map +1 -0
  108. package/dist/session-store.d.ts +133 -0
  109. package/dist/session-store.d.ts.map +1 -0
  110. package/dist/session-store.js +277 -0
  111. package/dist/session-store.js.map +1 -0
  112. package/dist/skills/curator.d.ts +104 -0
  113. package/dist/skills/curator.d.ts.map +1 -0
  114. package/dist/skills/curator.js +162 -0
  115. package/dist/skills/curator.js.map +1 -0
  116. package/dist/skills/index-builder.d.ts +42 -0
  117. package/dist/skills/index-builder.d.ts.map +1 -0
  118. package/dist/skills/index-builder.js +94 -0
  119. package/dist/skills/index-builder.js.map +1 -0
  120. package/dist/skills/loader.d.ts +107 -0
  121. package/dist/skills/loader.d.ts.map +1 -0
  122. package/dist/skills/loader.js +286 -0
  123. package/dist/skills/loader.js.map +1 -0
  124. package/dist/skills/preprocess.d.ts +45 -0
  125. package/dist/skills/preprocess.d.ts.map +1 -0
  126. package/dist/skills/preprocess.js +126 -0
  127. package/dist/skills/preprocess.js.map +1 -0
  128. package/dist/skills/usage.d.ts +75 -0
  129. package/dist/skills/usage.d.ts.map +1 -0
  130. package/dist/skills/usage.js +147 -0
  131. package/dist/skills/usage.js.map +1 -0
  132. package/dist/state/todos.d.ts +95 -0
  133. package/dist/state/todos.d.ts.map +1 -0
  134. package/dist/state/todos.js +198 -0
  135. package/dist/state/todos.js.map +1 -0
  136. package/dist/storage/conversations.d.ts +28 -0
  137. package/dist/storage/conversations.d.ts.map +1 -0
  138. package/dist/storage/conversations.js +8 -0
  139. package/dist/storage/conversations.js.map +1 -0
  140. package/dist/sub-agent/runner.d.ts +78 -0
  141. package/dist/sub-agent/runner.d.ts.map +1 -0
  142. package/dist/sub-agent/runner.js +215 -0
  143. package/dist/sub-agent/runner.js.map +1 -0
  144. package/dist/tools/builtin/agent.d.ts +33 -0
  145. package/dist/tools/builtin/agent.d.ts.map +1 -0
  146. package/dist/tools/builtin/agent.js +76 -0
  147. package/dist/tools/builtin/agent.js.map +1 -0
  148. package/dist/tools/builtin/bash.d.ts +11 -0
  149. package/dist/tools/builtin/bash.d.ts.map +1 -0
  150. package/dist/tools/builtin/bash.js +91 -0
  151. package/dist/tools/builtin/bash.js.map +1 -0
  152. package/dist/tools/builtin/edit.d.ts +21 -0
  153. package/dist/tools/builtin/edit.d.ts.map +1 -0
  154. package/dist/tools/builtin/edit.js +238 -0
  155. package/dist/tools/builtin/edit.js.map +1 -0
  156. package/dist/tools/builtin/read.d.ts +17 -0
  157. package/dist/tools/builtin/read.d.ts.map +1 -0
  158. package/dist/tools/builtin/read.js +139 -0
  159. package/dist/tools/builtin/read.js.map +1 -0
  160. package/dist/tools/builtin/sandbox.d.ts +16 -0
  161. package/dist/tools/builtin/sandbox.d.ts.map +1 -0
  162. package/dist/tools/builtin/sandbox.js +58 -0
  163. package/dist/tools/builtin/sandbox.js.map +1 -0
  164. package/dist/tools/builtin/skill_view.d.ts +37 -0
  165. package/dist/tools/builtin/skill_view.d.ts.map +1 -0
  166. package/dist/tools/builtin/skill_view.js +82 -0
  167. package/dist/tools/builtin/skill_view.js.map +1 -0
  168. package/dist/tools/builtin/todo_write.d.ts +29 -0
  169. package/dist/tools/builtin/todo_write.d.ts.map +1 -0
  170. package/dist/tools/builtin/todo_write.js +96 -0
  171. package/dist/tools/builtin/todo_write.js.map +1 -0
  172. package/dist/tools/builtin/web_fetch.d.ts +10 -0
  173. package/dist/tools/builtin/web_fetch.d.ts.map +1 -0
  174. package/dist/tools/builtin/web_fetch.js +150 -0
  175. package/dist/tools/builtin/web_fetch.js.map +1 -0
  176. package/dist/tools/builtin/write.d.ts +35 -0
  177. package/dist/tools/builtin/write.d.ts.map +1 -0
  178. package/dist/tools/builtin/write.js +70 -0
  179. package/dist/tools/builtin/write.js.map +1 -0
  180. package/dist/tools/file-state.d.ts +99 -0
  181. package/dist/tools/file-state.d.ts.map +1 -0
  182. package/dist/tools/file-state.js +133 -0
  183. package/dist/tools/file-state.js.map +1 -0
  184. package/dist/tools/hooks/sandbox-fs.d.ts +25 -0
  185. package/dist/tools/hooks/sandbox-fs.d.ts.map +1 -0
  186. package/dist/tools/hooks/sandbox-fs.js +48 -0
  187. package/dist/tools/hooks/sandbox-fs.js.map +1 -0
  188. package/dist/tools/registry.d.ts +102 -0
  189. package/dist/tools/registry.d.ts.map +1 -0
  190. package/dist/tools/registry.js +93 -0
  191. package/dist/tools/registry.js.map +1 -0
  192. package/dist/types.d.ts +109 -0
  193. package/dist/types.d.ts.map +1 -0
  194. package/dist/types.js +20 -0
  195. package/dist/types.js.map +1 -0
  196. package/package.json +72 -0
@@ -0,0 +1,215 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { AIAgent } from "../core/agent.js";
6
+ import { runConversation } from "../core/loop.js";
7
+ import { buildSystemReminder } from "../memory/reminder.js";
8
+ import { effortToThinkingBudget } from "../providers/anthropic.js";
9
+ import { providerForModel } from "../provider.js";
10
+ import { deleteMaestroSession } from "../session-store.js";
11
+ import { loadSkillsCached } from "../skills/loader.js";
12
+ import { bashTool } from "../tools/builtin/bash.js";
13
+ import { createEditTool } from "../tools/builtin/edit.js";
14
+ import { createReadTool } from "../tools/builtin/read.js";
15
+ import { createSkillViewTool } from "../tools/builtin/skill_view.js";
16
+ import { webFetchTool } from "../tools/builtin/web_fetch.js";
17
+ import { createWriteTool } from "../tools/builtin/write.js";
18
+ import { getFileStateTracker } from "../tools/file-state.js";
19
+ import { createSandboxFsHook } from "../tools/hooks/sandbox-fs.js";
20
+ import { ToolRegistry } from "../tools/registry.js";
21
+ import { logger } from "../platform/logger.js";
22
+ /** Hard cap on the sub-agent's per-API-call max output tokens. Defaults
23
+ * to 4096 (same as parent's default in AIAgent.config). Env-override for
24
+ * large delegated reports. */
25
+ function resolveMaxTokens() {
26
+ const env = process.env.MAESTRO_SUBAGENT_MAX_TOKENS;
27
+ if (env) {
28
+ const n = Number.parseInt(env, 10);
29
+ if (Number.isFinite(n) && n > 0)
30
+ return n;
31
+ }
32
+ return 4096;
33
+ }
34
+ /** Where the sub-agent overlay prompts live on disk. Co-located with the
35
+ * other prompt resources under `src/prompts/`. Resolved via `fileURLToPath`
36
+ * for Node compatibility (clawgram's Bun build used `import.meta.dir`). */
37
+ const __dirname = dirname(fileURLToPath(import.meta.url));
38
+ const OVERLAY_DIR = join(__dirname, "..", "prompts", "sub-agents");
39
+ function loadOverlay(kind) {
40
+ const path = join(OVERLAY_DIR, `${kind}.md`);
41
+ try {
42
+ return readFileSync(path, "utf8");
43
+ }
44
+ catch (e) {
45
+ // Fall back to a tiny inline reminder so a missing prompt file doesn't
46
+ // crash the whole call. The sub-agent will still know it's scoped.
47
+ logger.warn({ err: e, path }, "runSubAgent: overlay file missing, using fallback");
48
+ return "You are a focused sub-agent. Return one final text answer to the parent.";
49
+ }
50
+ }
51
+ /**
52
+ * Build the per-subagent-type tool registry.
53
+ *
54
+ * `general` — bash + Read + Write + Edit + WebFetch + skill_view.
55
+ * `explore` — Read + WebFetch + skill_view only. NO bash, write, edit —
56
+ * the role is read-only by construction.
57
+ *
58
+ * Both types share the same sandbox-fs hook. Neither registers `Agent`
59
+ * (recursion cap) or `todo_write` (sub-agents don't plan iteratively).
60
+ */
61
+ function buildToolRegistry(kind, subSessionId, skills, abortSignal) {
62
+ void abortSignal; // reserved for future bash abort wiring
63
+ const tools = new ToolRegistry();
64
+ tools.use(createSandboxFsHook());
65
+ // Sub-agent's OWN file-state tracker — keyed off subSessionId, NOT the
66
+ // parent's. Sharing would mean the parent's Read could let the sub-agent
67
+ // skip Read-before-Edit (or vice-versa), defeating the invariant.
68
+ const fileTracker = getFileStateTracker(subSessionId);
69
+ tools.register(createReadTool({ tracker: fileTracker }));
70
+ tools.register(webFetchTool);
71
+ if (skills.length > 0) {
72
+ tools.register(createSkillViewTool({ skills, sessionId: subSessionId }));
73
+ }
74
+ if (kind === "general") {
75
+ tools.register(bashTool);
76
+ tools.register(createWriteTool({ tracker: fileTracker }));
77
+ tools.register(createEditTool({ tracker: fileTracker }));
78
+ }
79
+ // `explore` stops here — read-only.
80
+ return tools;
81
+ }
82
+ /**
83
+ * Run a sub-agent to completion. Returns its final text + accumulated
84
+ * usage; the caller (Agent tool) decides how to surface that to the
85
+ * parent model.
86
+ *
87
+ * Cleanup contract (load-bearing):
88
+ * - Clean drain or thrown error → `deleteMaestroSession(subSessionId)`
89
+ * in the finally block. Frees the JSONL + file-state tracker + (any)
90
+ * todo store for this sub-session.
91
+ * - Abort → leave JSONL on disk. The 30-day TTL sweep will eventually
92
+ * clear it; meanwhile it's available for postmortem.
93
+ */
94
+ export async function runSubAgent(opts) {
95
+ const subSessionId = randomUUID();
96
+ let provider;
97
+ try {
98
+ provider = providerForModel(opts.parentModel);
99
+ }
100
+ catch (e) {
101
+ return {
102
+ text: `[sub-agent failed to start: ${e instanceof Error ? e.message : String(e)}]`,
103
+ usage: { inputTokens: 0, outputTokens: 0 },
104
+ subSessionId,
105
+ aborted: false,
106
+ };
107
+ }
108
+ const tools = buildToolRegistry(opts.subagentType, subSessionId, opts.skills, opts.parentAbortSignal);
109
+ const overlay = loadOverlay(opts.subagentType);
110
+ const systemPrompt = `${opts.parentSystemPrompt}\n\n${overlay}`;
111
+ const maxTokens = resolveMaxTokens();
112
+ const thinkingBudget = opts.parentEffort ? effortToThinkingBudget(opts.parentEffort) : undefined;
113
+ // Sub-agent's user message follows the parent contract: prompt + own
114
+ // system reminder. The reminder reflects the SUB-SESSION's state
115
+ // (its own session id), not the parent's.
116
+ const reminderText = buildSystemReminder({ sessionId: subSessionId });
117
+ const userBlocks = [
118
+ { type: "text", text: opts.prompt },
119
+ { type: "text", text: reminderText },
120
+ ];
121
+ const messages = [{ role: "user", content: userBlocks }];
122
+ const agent = new AIAgent(provider, tools, {
123
+ model: opts.parentModel,
124
+ systemPrompt,
125
+ maxTokens,
126
+ ...(thinkingBudget ? { thinkingBudget } : {}),
127
+ ...(opts.parentEffort ? { effort: opts.parentEffort } : {}),
128
+ ...(opts.parentAbortSignal ? { abortSignal: opts.parentAbortSignal } : {}),
129
+ });
130
+ logger.info({
131
+ parentSessionId: opts.parentSessionId,
132
+ subSessionId,
133
+ subagentType: opts.subagentType,
134
+ model: opts.parentModel,
135
+ }, "runSubAgent: starting");
136
+ let finalText = "";
137
+ let usage = { inputTokens: 0, outputTokens: 0 };
138
+ let aborted = false;
139
+ let crashed = false;
140
+ try {
141
+ for await (const event of runConversation(agent, messages)) {
142
+ // Silent-by-default: we only consume terminal events. text_deltas,
143
+ // tool_uses, tool_results all stay inside the sub-agent's loop.
144
+ if (event.type === "result") {
145
+ finalText = event.content;
146
+ if (event.usage)
147
+ usage = event.usage;
148
+ }
149
+ else if (event.type === "error") {
150
+ // Surface as part of the final text so the parent sees the failure
151
+ // reason. The sub-agent's error event is its terminal state when
152
+ // it can't return a normal result.
153
+ finalText = finalText
154
+ ? `${finalText}\n\n[sub-agent error: ${event.content}]`
155
+ : `[sub-agent error: ${event.content}]`;
156
+ }
157
+ }
158
+ }
159
+ catch (e) {
160
+ if (isAbortError(e) || opts.parentAbortSignal?.aborted) {
161
+ aborted = true;
162
+ }
163
+ else {
164
+ crashed = true;
165
+ const msg = e instanceof Error ? e.message : String(e);
166
+ finalText = finalText
167
+ ? `${finalText}\n\n[sub-agent crashed: ${msg}]`
168
+ : `[sub-agent crashed: ${msg}]`;
169
+ }
170
+ }
171
+ finally {
172
+ if (!aborted) {
173
+ // Clean drain OR provider-crashed: nuke the sub-session JSONL +
174
+ // in-memory caches. Aborts intentionally skip this so a parent
175
+ // interrupt leaves the JSONL for postmortem; the 30-day TTL sweep
176
+ // (cleanupStaleMaestroSessions) eventually clears it.
177
+ try {
178
+ deleteMaestroSession(subSessionId);
179
+ }
180
+ catch (e) {
181
+ logger.warn({ err: e, subSessionId }, "runSubAgent: cleanup failed");
182
+ }
183
+ }
184
+ logger.info({
185
+ parentSessionId: opts.parentSessionId,
186
+ subSessionId,
187
+ subagentType: opts.subagentType,
188
+ aborted,
189
+ crashed,
190
+ textLen: finalText.length,
191
+ usage,
192
+ }, "runSubAgent: finished");
193
+ }
194
+ return { text: finalText, usage, subSessionId, aborted };
195
+ }
196
+ /**
197
+ * Mirror of `maestroProvider`'s `isAbortError`. Inlined to avoid an extra
198
+ * import path and keep this module self-contained for the sub-agent
199
+ * boundary — the abort-shape detection is small and the runner is the
200
+ * only sub-agent caller in v1.
201
+ */
202
+ function isAbortError(err) {
203
+ if (!err || typeof err !== "object")
204
+ return false;
205
+ const e = err;
206
+ if (e.name === "AbortError")
207
+ return true;
208
+ if (e.code === 20 || e.code === "ABORT_ERR")
209
+ return true;
210
+ return false;
211
+ }
212
+ /** Convenience re-export for test setup — lets tests prime the loaded
213
+ * catalog without re-fetching from disk. */
214
+ export { loadSkillsCached };
215
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/sub-agent/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { type RunSubAgentOptions } from "../../sub-agent/runner.js";
2
+ import type { ToolHandler } from "../../tools/registry.js";
3
+ /**
4
+ * `Agent` builtin — spawn a focused sub-agent for one delegated task.
5
+ *
6
+ * Returns only the sub-agent's final text to the parent model — tool calls,
7
+ * intermediate text, and the sub-agent's own session id are not surfaced
8
+ * mid-stream. This is the same contract Claude Code's Task tool exposes.
9
+ *
10
+ * Two scoped types in v1:
11
+ * - `general` — full builtin toolkit (bash + Read + Write + Edit +
12
+ * WebFetch + skill_view). Use for self-contained units of work.
13
+ * - `explore` — read-only (Read + WebFetch + skill_view). Use for
14
+ * finding / surveying / reporting tasks where you don't want the
15
+ * sub-agent mutating files by accident.
16
+ *
17
+ * `parallelSafe: false` — sub-agent invocation spawns a child loop with
18
+ * side effects (file writes for `general`, MCP-less Anthropic API calls
19
+ * for both). Running two in parallel would race the API rate limits + the
20
+ * shared file-state tracker registry.
21
+ *
22
+ * No `description` field on the schema (advisor): the model would either
23
+ * skip it or duplicate the prompt into it. We derive a log label from the
24
+ * prompt's first line internally.
25
+ */
26
+ export interface AgentToolFactoryOptions {
27
+ /** Parent context the sub-agent inherits from. The runner uses these to
28
+ * build the sub-agent's system prompt, model, abort signal, and skill
29
+ * catalog — none of which the model needs to (or should) pass. */
30
+ parent: Pick<RunSubAgentOptions, "parentSessionId" | "parentSystemPrompt" | "parentModel" | "parentEffort" | "parentAbortSignal" | "skills">;
31
+ }
32
+ export declare function createAgentTool(opts: AgentToolFactoryOptions): ToolHandler;
33
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAGxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,uBAAuB;IACtC;;uEAEmE;IACnE,MAAM,EAAE,IAAI,CACV,kBAAkB,EAChB,iBAAiB,GACjB,oBAAoB,GACpB,aAAa,GACb,cAAc,GACd,mBAAmB,GACnB,QAAQ,CACX,CAAC;CACH;AAID,wBAAgB,eAAe,CAAC,IAAI,EAAE,uBAAuB,GAAG,WAAW,CAiF1E"}
@@ -0,0 +1,76 @@
1
+ import { runSubAgent, } from "../../sub-agent/runner.js";
2
+ const VALID_TYPES = new Set(["general", "explore"]);
3
+ export function createAgentTool(opts) {
4
+ return {
5
+ parallelSafe: false,
6
+ schema: {
7
+ name: "Agent",
8
+ description: "Spawn a focused sub-agent to do ONE delegated task and return its final text. " +
9
+ "The sub-agent has its own context — your tool calls, files-Read state, and todo list " +
10
+ "are NOT shared with it. Use `general` for self-contained work that may need bash/Write/Edit, " +
11
+ "and `explore` for read-only surveys (Read/WebFetch/skill_view only). " +
12
+ "The sub-agent cannot spawn its own sub-agents (no recursion). Pass a self-contained " +
13
+ "prompt — the sub-agent sees ONLY that prompt and the inherited system context.",
14
+ input_schema: {
15
+ type: "object",
16
+ properties: {
17
+ subagent_type: {
18
+ type: "string",
19
+ description: "Sub-agent role. 'general' = full builtin toolkit. 'explore' = read-only " +
20
+ "(Read/WebFetch/skill_view only — no bash, no write, no edit).",
21
+ },
22
+ prompt: {
23
+ type: "string",
24
+ description: "Self-contained task brief. The sub-agent sees ONLY this text as its initial " +
25
+ "user message. State the goal, any constraints, and what 'done' looks like.",
26
+ },
27
+ },
28
+ required: ["subagent_type", "prompt"],
29
+ },
30
+ },
31
+ async execute(input) {
32
+ const subagentTypeRaw = input.subagent_type;
33
+ const prompt = input.prompt;
34
+ if (typeof subagentTypeRaw !== "string" ||
35
+ !VALID_TYPES.has(subagentTypeRaw)) {
36
+ return JSON.stringify({
37
+ error: `Agent: subagent_type must be one of ${Array.from(VALID_TYPES).join(", ")}, got '${subagentTypeRaw}'`,
38
+ });
39
+ }
40
+ if (typeof prompt !== "string" || prompt.trim().length === 0) {
41
+ return JSON.stringify({
42
+ error: "Agent: prompt must be a non-empty string",
43
+ });
44
+ }
45
+ const subagentType = subagentTypeRaw;
46
+ const result = await runSubAgent({
47
+ subagentType,
48
+ prompt,
49
+ parentSessionId: opts.parent.parentSessionId,
50
+ parentSystemPrompt: opts.parent.parentSystemPrompt,
51
+ parentModel: opts.parent.parentModel,
52
+ ...(opts.parent.parentEffort ? { parentEffort: opts.parent.parentEffort } : {}),
53
+ ...(opts.parent.parentAbortSignal
54
+ ? { parentAbortSignal: opts.parent.parentAbortSignal }
55
+ : {}),
56
+ skills: opts.parent.skills,
57
+ });
58
+ if (result.aborted) {
59
+ // Aborted sub-agent: don't pretend a normal result. The parent
60
+ // model's next turn (if any) sees this and can decide.
61
+ return JSON.stringify({
62
+ error: "Agent: sub-agent was aborted (parent abort signal fired)",
63
+ subSessionId: result.subSessionId,
64
+ });
65
+ }
66
+ // Final text + a one-line provenance footer the model can use to
67
+ // attribute facts ("from the explore sub-agent: ...") and so the
68
+ // unified conversation log carries traceability without needing a
69
+ // separate event type. Usage is included for cost transparency.
70
+ const footer = `\n\n— end of ${subagentType} sub-agent (${result.subSessionId.slice(0, 8)}) — ` +
71
+ `${result.usage.inputTokens} in / ${result.usage.outputTokens} out`;
72
+ return `${result.text}${footer}`;
73
+ },
74
+ };
75
+ }
76
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/tools/builtin/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ToolHandler } from "../../tools/registry.js";
2
+ /**
3
+ * Bash tool — PoC for Phase 1.
4
+ *
5
+ * Minimal: shell out, capture stdout/stderr, enforce a 30s timeout and a
6
+ * 16KB output cap. NOT a long-term solution — Phase 5 will replace this with
7
+ * an adapter to Clawgram's MCP terminal tool so the Maestro loop inherits
8
+ * Clawgram's permission system instead of having an unguarded subprocess.
9
+ */
10
+ export declare const bashTool: ToolHandler;
11
+ //# sourceMappingURL=bash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/bash.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKpD;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,EAAE,WAmFtB,CAAC"}
@@ -0,0 +1,91 @@
1
+ import { spawn } from "node:child_process";
2
+ const BASH_TIMEOUT_MS = 30_000;
3
+ const BASH_MAX_OUTPUT = 16_000;
4
+ /**
5
+ * Bash tool — PoC for Phase 1.
6
+ *
7
+ * Minimal: shell out, capture stdout/stderr, enforce a 30s timeout and a
8
+ * 16KB output cap. NOT a long-term solution — Phase 5 will replace this with
9
+ * an adapter to Clawgram's MCP terminal tool so the Maestro loop inherits
10
+ * Clawgram's permission system instead of having an unguarded subprocess.
11
+ */
12
+ export const bashTool = {
13
+ schema: {
14
+ name: "bash",
15
+ description: "Execute a bash command and return stdout/stderr. 30s timeout, 16KB output cap.",
16
+ input_schema: {
17
+ type: "object",
18
+ properties: {
19
+ command: {
20
+ type: "string",
21
+ description: "Bash command to execute",
22
+ },
23
+ cwd: {
24
+ type: "string",
25
+ description: "Working directory (optional)",
26
+ },
27
+ },
28
+ required: ["command"],
29
+ },
30
+ },
31
+ async execute(input) {
32
+ const command = String(input.command ?? "");
33
+ if (!command.trim()) {
34
+ return JSON.stringify({ error: "empty command" });
35
+ }
36
+ const cwd = typeof input.cwd === "string" ? input.cwd : undefined;
37
+ return new Promise((resolve) => {
38
+ const child = spawn("bash", ["-c", command], {
39
+ ...(cwd ? { cwd } : {}),
40
+ env: process.env,
41
+ });
42
+ let stdout = "";
43
+ let stderr = "";
44
+ let truncated = false;
45
+ const timer = setTimeout(() => {
46
+ child.kill("SIGKILL");
47
+ resolve(JSON.stringify({
48
+ error: `timeout after ${BASH_TIMEOUT_MS}ms`,
49
+ stdout,
50
+ stderr,
51
+ }));
52
+ }, BASH_TIMEOUT_MS);
53
+ child.stdout?.on("data", (chunk) => {
54
+ const text = chunk.toString("utf-8");
55
+ if (stdout.length + text.length > BASH_MAX_OUTPUT) {
56
+ stdout += text.slice(0, BASH_MAX_OUTPUT - stdout.length);
57
+ truncated = true;
58
+ child.stdout?.destroy();
59
+ }
60
+ else {
61
+ stdout += text;
62
+ }
63
+ });
64
+ child.stderr?.on("data", (chunk) => {
65
+ const text = chunk.toString("utf-8");
66
+ if (stderr.length + text.length > BASH_MAX_OUTPUT) {
67
+ stderr += text.slice(0, BASH_MAX_OUTPUT - stderr.length);
68
+ truncated = true;
69
+ child.stderr?.destroy();
70
+ }
71
+ else {
72
+ stderr += text;
73
+ }
74
+ });
75
+ child.on("close", (code) => {
76
+ clearTimeout(timer);
77
+ resolve(JSON.stringify({
78
+ exitCode: code,
79
+ stdout,
80
+ stderr,
81
+ ...(truncated ? { truncated: true } : {}),
82
+ }));
83
+ });
84
+ child.on("error", (err) => {
85
+ clearTimeout(timer);
86
+ resolve(JSON.stringify({ error: err.message }));
87
+ });
88
+ });
89
+ },
90
+ };
91
+ //# sourceMappingURL=bash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.js","sourceRoot":"","sources":["../../../src/tools/builtin/bash.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { FileStateTracker } from "../../tools/file-state.js";
2
+ import type { ToolHandler } from "../../tools/registry.js";
3
+ export interface EditToolOptions {
4
+ /**
5
+ * Per-session file-state tracker. When provided, Edit enforces the
6
+ * Read-before-Edit invariant: the path must have been Read in this session
7
+ * AND its mtime/size must still match the recorded values.
8
+ */
9
+ tracker?: FileStateTracker;
10
+ }
11
+ export declare function createEditTool(opts?: EditToolOptions): ToolHandler;
12
+ /** Backwards-compatible singleton (no tracker — Read-before-Edit gate off). */
13
+ export declare const editTool: ToolHandler;
14
+ /**
15
+ * Count non-overlapping occurrences of `needle` in `haystack`. We use this
16
+ * to drive the unique-match check; `indexOf` in a loop is fast enough for
17
+ * the 10MB cap and avoids the regex escaping the model would have to do.
18
+ */
19
+ export declare function countOccurrences(haystack: string, needle: string): number;
20
+ export declare const __MAX_FILE_BYTES: number;
21
+ //# sourceMappingURL=edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/edit.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAqCpD,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,IAAI,GAAE,eAAoB,GAAG,WAAW,CA4JtE;AAED,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,EAAE,WAA8B,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAUzE;AAqCD,eAAO,MAAM,gBAAgB,QAAiB,CAAC"}