salmon-loop 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 (227) hide show
  1. package/dist/cli/authorization/non-interactive.js +9 -13
  2. package/dist/cli/authorization/provider.js +2 -10
  3. package/dist/cli/chat.js +12 -6
  4. package/dist/cli/commands/allowlist.js +1 -1
  5. package/dist/cli/commands/chat.js +13 -13
  6. package/dist/cli/commands/config.js +2 -2
  7. package/dist/cli/commands/mode.js +2 -2
  8. package/dist/cli/commands/parallel.js +1 -1
  9. package/dist/cli/commands/run/handler.js +9 -4
  10. package/dist/cli/commands/run/loop-params.js +2 -0
  11. package/dist/cli/commands/run/parse-options.js +14 -26
  12. package/dist/cli/commands/run/runtime-llm.js +15 -12
  13. package/dist/cli/commands/run/runtime-options.js +3 -1
  14. package/dist/cli/config.js +0 -8
  15. package/dist/cli/headless/openai-responses-canonical-applier.js +1 -7
  16. package/dist/cli/locales/en.js +2 -2
  17. package/dist/cli/reporters/standard.js +12 -3
  18. package/dist/cli/reporters/stream-json.js +2 -1
  19. package/dist/cli/slash/runtime.js +2 -2
  20. package/dist/cli/ui/hooks/useLoopEvents.js +1 -1
  21. package/dist/cli/ui/hooks/useLoopState.js +1 -1
  22. package/dist/core/adapters/fs/file-adapter.js +3 -1
  23. package/dist/core/adapters/git/git-adapter.js +6 -3
  24. package/dist/core/adapters/git/git-runner.js +5 -2
  25. package/dist/core/adapters/git/lock-manager.js +7 -4
  26. package/dist/core/ast/parser.js +18 -9
  27. package/dist/core/checkpoint-domain/manifest-store.js +21 -13
  28. package/dist/core/checkpoint-domain/service.js +3 -1
  29. package/dist/core/config/limits.js +1 -1
  30. package/dist/core/config/model-pricing.js +61 -0
  31. package/dist/core/config/schema.js +738 -0
  32. package/dist/core/config/validate.js +11 -922
  33. package/dist/core/context/ast/skeleton-extractor.js +225 -0
  34. package/dist/core/context/ast/source-outline.js +24 -1
  35. package/dist/core/context/budget/dynamic-adjuster.js +20 -5
  36. package/dist/core/context/builder.js +7 -3
  37. package/dist/core/context/cache/store-factory.js +3 -1
  38. package/dist/core/context/dependencies.js +2 -1
  39. package/dist/core/context/effectiveness/persistence.js +50 -0
  40. package/dist/core/context/effectiveness/tracker.js +24 -0
  41. package/dist/core/context/gatherers/architecture-gatherer.js +2 -1
  42. package/dist/core/context/gatherers/artifact-gatherer.js +7 -4
  43. package/dist/core/context/gatherers/ast-gatherer.js +34 -40
  44. package/dist/core/context/gatherers/ghost-dependency-gatherer.js +0 -1
  45. package/dist/core/context/gatherers/git-history-gatherer.js +3 -1
  46. package/dist/core/context/gatherers/knowledge-gatherer.js +21 -2
  47. package/dist/core/context/gatherers/metadata-gatherer.js +12 -7
  48. package/dist/core/context/gatherers/ripgrep-gatherer.js +6 -3
  49. package/dist/core/context/service.js +12 -2
  50. package/dist/core/context/steps/context-gather.js +14 -3
  51. package/dist/core/context/steps/context-targets.js +1 -0
  52. package/dist/core/context/targeting/target-resolver.js +29 -11
  53. package/dist/core/context/token/cache.js +5 -2
  54. package/dist/core/context/token/encoding-registry.js +7 -6
  55. package/dist/core/context/truncation/strategies/json.js +5 -2
  56. package/dist/core/context/truncation/type-detector.js +3 -1
  57. package/dist/core/extensions/index.js +48 -3
  58. package/dist/core/extensions/load.js +3 -2
  59. package/dist/core/extensions/merge.js +5 -1
  60. package/dist/core/extensions/paths.js +8 -2
  61. package/dist/core/extensions/schemas.js +21 -0
  62. package/dist/core/facades/cli-authorization-provider.js +1 -0
  63. package/dist/core/facades/cli-command-chat.js +2 -0
  64. package/dist/core/facades/cli-run-handler.js +1 -0
  65. package/dist/core/facades/cli-utils-serialize.js +2 -0
  66. package/dist/core/feedback/parsers.js +290 -1
  67. package/dist/core/grizzco/dsl/llm-strategy.js +4 -3
  68. package/dist/core/grizzco/engine/observability/loop-telemetry.js +5 -2
  69. package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +30 -13
  70. package/dist/core/grizzco/engine/pipeline/pipeline.js +149 -240
  71. package/dist/core/grizzco/engine/transaction/attempt-failure.js +49 -24
  72. package/dist/core/grizzco/engine/transaction/authorization-summary.js +2 -1
  73. package/dist/core/grizzco/engine/transaction/transaction-runner.js +40 -34
  74. package/dist/core/grizzco/execution/RejectionManager.js +7 -5
  75. package/dist/core/grizzco/runtime/apply-back-runtime.js +5 -2
  76. package/dist/core/grizzco/services/implementations/default/GitConfigService.js +2 -1
  77. package/dist/core/grizzco/services/registry.js +18 -0
  78. package/dist/core/grizzco/steps/audit.js +20 -10
  79. package/dist/core/grizzco/steps/autopilot.js +21 -32
  80. package/dist/core/grizzco/steps/display-report.js +4 -11
  81. package/dist/core/grizzco/steps/explore.js +14 -4
  82. package/dist/core/grizzco/steps/generateReview.js +3 -1
  83. package/dist/core/grizzco/steps/patch/prompt-input.js +4 -1
  84. package/dist/core/grizzco/steps/patch.js +1 -0
  85. package/dist/core/grizzco/steps/plan.js +58 -49
  86. package/dist/core/grizzco/steps/research.js +3 -1
  87. package/dist/core/grizzco/steps/tool-runtime.js +3 -0
  88. package/dist/core/grizzco/steps/verify.js +7 -1
  89. package/dist/core/grizzco/validation/AstValidationService.js +3 -1
  90. package/dist/core/grizzco/workers/strata-sync-worker.js +2 -1
  91. package/dist/core/history/input-history.js +3 -1
  92. package/dist/core/intent/chat-intent.js +3 -1
  93. package/dist/core/llm/ai-sdk/message-mapper.js +37 -26
  94. package/dist/core/llm/ai-sdk/request-params.js +2 -6
  95. package/dist/core/llm/ai-sdk/result-mapper.js +14 -8
  96. package/dist/core/llm/ai-sdk/retry-classifier.js +17 -7
  97. package/dist/core/llm/ai-sdk/retry-executor.js +1 -1
  98. package/dist/core/llm/contracts/repair.js +16 -8
  99. package/dist/core/llm/errors.js +18 -14
  100. package/dist/core/llm/output-policy.js +8 -0
  101. package/dist/core/llm/redact.js +1 -3
  102. package/dist/core/llm/retry-utils.js +8 -2
  103. package/dist/core/llm/stream-utils.js +5 -3
  104. package/dist/core/llm/sub-agent-factory.js +51 -0
  105. package/dist/core/llm/tool-calling-stub.js +48 -0
  106. package/dist/core/llm/utils.js +17 -6
  107. package/dist/core/mcp/bridge/prompt-command-provider.js +4 -3
  108. package/dist/core/mcp/bridge/resource-context-provider.js +3 -1
  109. package/dist/core/mcp/bridge/tool-bridge.js +5 -14
  110. package/dist/core/mcp/catalog/discovery.js +3 -1
  111. package/dist/core/mcp/client/connection-manager.js +7 -4
  112. package/dist/core/mcp/client/transport-factory.js +7 -3
  113. package/dist/core/mcp/host/sampling-provider.js +1 -1
  114. package/dist/core/mcp/schema/json-schema-to-zod.js +2 -1
  115. package/dist/core/memory/relevant-retrieval.js +6 -4
  116. package/dist/core/observability/audit-file.js +2 -1
  117. package/dist/core/observability/audit-trail.js +3 -1
  118. package/dist/core/observability/authorization-decisions.js +13 -12
  119. package/dist/core/observability/error-mapping.js +2 -1
  120. package/dist/core/observability/logger.js +2 -1
  121. package/dist/core/observability/monitor.js +24 -0
  122. package/dist/core/observability/run-outcome-reporter.js +1 -0
  123. package/dist/core/observability/token-usage.js +5 -4
  124. package/dist/core/permission-gate/default-gate.js +5 -8
  125. package/dist/core/plan/storage.js +7 -4
  126. package/dist/core/plugin/loader.js +8 -5
  127. package/dist/core/prompts/registry.js +12 -30
  128. package/dist/core/prompts/runtime.js +3 -1
  129. package/dist/core/prompts/templates/system/autopilot_system.hbs +28 -4
  130. package/dist/core/protocols/a2a/sdk/executor.js +3 -1
  131. package/dist/core/protocols/a2a/sdk/server.js +5 -4
  132. package/dist/core/protocols/acp/acp-command-runner.js +7 -6
  133. package/dist/core/protocols/acp/acp-session-persistence.js +13 -10
  134. package/dist/core/protocols/acp/formal-agent.js +13 -6
  135. package/dist/core/protocols/acp/permission-provider.js +3 -2
  136. package/dist/core/protocols/acp/stdio-server.js +6 -6
  137. package/dist/core/reflection/engine.js +114 -14
  138. package/dist/core/runtime/agent-server-runtime.js +3 -2
  139. package/dist/core/runtime/batch-runner.js +81 -0
  140. package/dist/core/runtime/initialize.js +71 -6
  141. package/dist/core/runtime/loop-finalize.js +3 -0
  142. package/dist/core/runtime/loop-session-runner.js +5 -0
  143. package/dist/core/runtime/loop.js +4 -0
  144. package/dist/core/runtime/paths.js +9 -6
  145. package/dist/core/runtime/spawn-interactive.js +5 -4
  146. package/dist/core/security/redaction.js +3 -2
  147. package/dist/core/session/compaction/index.js +4 -3
  148. package/dist/core/session/compression.js +3 -1
  149. package/dist/core/session/manager.js +26 -38
  150. package/dist/core/session/pruning-strategy.js +2 -1
  151. package/dist/core/session/token-tracker.js +27 -9
  152. package/dist/core/skills/parser.js +3 -2
  153. package/dist/core/skills/permissions.js +2 -2
  154. package/dist/core/skills/runtime/MicroTaskRunner.js +1 -1
  155. package/dist/core/skills/runtime/SkillRunner.js +5 -2
  156. package/dist/core/slash/steps/slash-execute.js +7 -5
  157. package/dist/core/slash/strategy.js +1 -1
  158. package/dist/core/strata/checkpoint/manager.js +16 -10
  159. package/dist/core/strata/checkpoint/snapshot-create.js +5 -4
  160. package/dist/core/strata/checkpoint/snapshot-write-tree.js +7 -3
  161. package/dist/core/strata/engine/shadow-merge-engine.js +4 -2
  162. package/dist/core/strata/interaction/file-system-provider.js +2 -1
  163. package/dist/core/strata/layers/file-state-resolver.js +9 -7
  164. package/dist/core/strata/layers/immutable-git-layer.js +3 -1
  165. package/dist/core/strata/layers/shadow-driver/readonly-lock.js +8 -6
  166. package/dist/core/strata/layers/shadow-driver/shadow-driver.js +2 -1
  167. package/dist/core/strata/layers/worktree.js +9 -10
  168. package/dist/core/strata/runtime/environment.js +2 -1
  169. package/dist/core/strata/runtime/synchronizer.js +28 -26
  170. package/dist/core/streaming/canonical/parts-from-llm-stream-chunk.js +1 -11
  171. package/dist/core/structured-output/json-extract.js +3 -1
  172. package/dist/core/structured-output/json-schema-validator.js +1 -13
  173. package/dist/core/sub-agent/artifacts/store.js +2 -1
  174. package/dist/core/sub-agent/context-snapshot.js +12 -6
  175. package/dist/core/sub-agent/controller.js +70 -1
  176. package/dist/core/sub-agent/core/loop.js +25 -3
  177. package/dist/core/sub-agent/core/manager.js +343 -117
  178. package/dist/core/sub-agent/registry-defaults.js +12 -0
  179. package/dist/core/sub-agent/registry.js +8 -0
  180. package/dist/core/sub-agent/summary.js +96 -0
  181. package/dist/core/sub-agent/team.js +98 -0
  182. package/dist/core/sub-agent/tools/task-await.js +109 -0
  183. package/dist/core/sub-agent/tools/task-spawn.js +52 -7
  184. package/dist/core/sub-agent/tools/team.js +92 -0
  185. package/dist/core/sub-agent/types.js +11 -2
  186. package/dist/core/target-runtime/profile.js +3 -1
  187. package/dist/core/tools/audit.js +3 -2
  188. package/dist/core/tools/budget.js +7 -12
  189. package/dist/core/tools/builtin/ast.js +144 -0
  190. package/dist/core/tools/builtin/code-search/backends/powershell.js +3 -1
  191. package/dist/core/tools/builtin/code-search/backends/rg.js +3 -1
  192. package/dist/core/tools/builtin/code-search/executor.js +46 -43
  193. package/dist/core/tools/builtin/code-search/parse/plain-grep.js +3 -1
  194. package/dist/core/tools/builtin/code-search/parse/rg-json.js +3 -1
  195. package/dist/core/tools/builtin/fs.js +90 -7
  196. package/dist/core/tools/builtin/git.js +242 -0
  197. package/dist/core/tools/builtin/glob.js +79 -0
  198. package/dist/core/tools/builtin/index.js +53 -111
  199. package/dist/core/tools/builtin/interaction.js +13 -15
  200. package/dist/core/tools/builtin/knowledge.js +146 -4
  201. package/dist/core/tools/builtin/proposal.js +14 -3
  202. package/dist/core/tools/builtin/verify.js +35 -3
  203. package/dist/core/tools/capability/executor.js +5 -5
  204. package/dist/core/tools/headless-payload.js +1 -3
  205. package/dist/core/tools/mapper.js +8 -42
  206. package/dist/core/tools/parallel/persistence.js +17 -5
  207. package/dist/core/tools/parallel/scheduler.js +23 -21
  208. package/dist/core/tools/permissions/permission-rules.js +69 -115
  209. package/dist/core/tools/plugins/loader.js +4 -3
  210. package/dist/core/tools/router.js +112 -58
  211. package/dist/core/tools/session.js +64 -102
  212. package/dist/core/tools/streaming/ToolCallAccumulator.js +1 -3
  213. package/dist/core/tools/tool-visibility.js +2 -1
  214. package/dist/core/tools/types.js +10 -0
  215. package/dist/core/types/batch.js +2 -0
  216. package/dist/core/utils/error.js +79 -0
  217. package/dist/core/utils/sanitizer.js +5 -2
  218. package/dist/core/utils/serialize.js +66 -0
  219. package/dist/core/utils/zod.js +29 -0
  220. package/dist/core/verification/detect-runner.js +86 -0
  221. package/dist/core/verification/runner.js +76 -0
  222. package/dist/core/version.js +3 -1
  223. package/dist/core/workspace/capabilities.js +3 -2
  224. package/dist/integrations/langfuse/litellm-langfuse-outcome-reporter.js +9 -8
  225. package/dist/languages/python/index.js +154 -0
  226. package/dist/locales/en.js +8 -1
  227. package/package.json +2 -1
@@ -115,4 +115,246 @@ export async function executeGitStatus(input, ctx) {
115
115
  status: res.stdout.toString('utf8'),
116
116
  };
117
117
  }
118
+ // ── git.blame ─────────────────────────────────────────────────────────
119
+ export const gitBlameSpec = {
120
+ name: 'git.blame',
121
+ source: 'builtin',
122
+ intent: 'READ',
123
+ description: text.tools.gitBlameDescription,
124
+ riskLevel: 'low',
125
+ sideEffects: ['git_read'],
126
+ concurrency: 'parallel_ok',
127
+ computeResources: (_input, ctx) => [repoResource(ctx)],
128
+ inputSchema: z.object({
129
+ file: z.string().describe('Relative path to the file'),
130
+ ref: z.string().optional().describe('Git reference (default: HEAD)'),
131
+ range: z
132
+ .object({
133
+ start: z.number().int().min(1).describe('Start line number'),
134
+ end: z.number().int().min(1).describe('End line number'),
135
+ })
136
+ .optional()
137
+ .describe('Line range to blame'),
138
+ }),
139
+ outputSchema: z.object({
140
+ file: z.string(),
141
+ lines: z.array(z.object({
142
+ line: z.number(),
143
+ content: z.string(),
144
+ commit: z.string(),
145
+ author: z.string(),
146
+ authorTime: z.number(),
147
+ })),
148
+ }),
149
+ allowedPhases: [Phase.SLASH, Phase.CONTEXT, Phase.EXPLORE, Phase.PLAN, Phase.AUTOPILOT],
150
+ };
151
+ export async function executeGitBlame(input, ctx) {
152
+ const { file, ref, range } = input;
153
+ if (file.includes('..') || file.startsWith('/') || /^[a-zA-Z]:/.test(file)) {
154
+ throw new Error(text.tools.invalidRelativePath(file));
155
+ }
156
+ const args = ['blame', '--porcelain'];
157
+ if (range)
158
+ args.push('-L', `${range.start},${range.end}`);
159
+ if (ref)
160
+ args.push(ref);
161
+ args.push('--', file);
162
+ const repoRoot = ctx.worktreeRoot || ctx.repoRoot;
163
+ const git = new GitAdapter(repoRoot);
164
+ const res = await git.execMeta(args, {
165
+ cwd: repoRoot,
166
+ env: ctx.env,
167
+ limits: { maxStdoutBytes: LIMITS.maxToolOutputBytes, maxStderrChars: 16_384 },
168
+ timeoutMs: LIMITS.gitTimeoutMs,
169
+ });
170
+ if (!res.ok) {
171
+ if (res.error?.message)
172
+ throw new Error(text.git.processError(res.error.message));
173
+ throw new Error(text.git.commandFailedDetailed(res.code, res.stderr.trim()));
174
+ }
175
+ if (res.stdoutTruncated)
176
+ throw new Error(text.git.outputTruncated(LIMITS.maxToolOutputBytes));
177
+ const lines = parseBlamePorcelain(res.stdout.toString('utf8'));
178
+ return { file, lines };
179
+ }
180
+ function parseBlamePorcelain(raw) {
181
+ const result = [];
182
+ const commitMeta = new Map();
183
+ let currentCommit = '';
184
+ let currentAuthor = '';
185
+ let currentAuthorTime = 0;
186
+ for (const line of raw.split('\n')) {
187
+ if (!line)
188
+ continue;
189
+ // Header line: "hash origLine finalLine [numLines]"
190
+ const headerMatch = /^([0-9a-f]{40})\s+\d+\s+(\d+)/.exec(line);
191
+ if (headerMatch) {
192
+ currentCommit = headerMatch[1];
193
+ if (!commitMeta.has(currentCommit)) {
194
+ const meta = commitMeta.get(currentCommit);
195
+ if (meta) {
196
+ currentAuthor = meta.author;
197
+ currentAuthorTime = meta.authorTime;
198
+ }
199
+ }
200
+ continue;
201
+ }
202
+ if (line.startsWith('author ')) {
203
+ currentAuthor = line.slice(7);
204
+ commitMeta.set(currentCommit, { author: currentAuthor, authorTime: currentAuthorTime });
205
+ continue;
206
+ }
207
+ if (line.startsWith('author-time ')) {
208
+ currentAuthorTime = Number(line.slice(12));
209
+ const existing = commitMeta.get(currentCommit);
210
+ if (existing)
211
+ existing.authorTime = currentAuthorTime;
212
+ else
213
+ commitMeta.set(currentCommit, { author: currentAuthor, authorTime: currentAuthorTime });
214
+ continue;
215
+ }
216
+ // Content line starts with tab
217
+ if (line.startsWith('\t')) {
218
+ const meta = commitMeta.get(currentCommit) || {
219
+ author: currentAuthor,
220
+ authorTime: currentAuthorTime,
221
+ };
222
+ result.push({
223
+ line: result.length + 1,
224
+ content: line.slice(1),
225
+ commit: currentCommit,
226
+ author: meta.author,
227
+ authorTime: meta.authorTime,
228
+ });
229
+ }
230
+ }
231
+ return result;
232
+ }
233
+ // ── git.log ───────────────────────────────────────────────────────────
234
+ export const gitLogSpec = {
235
+ name: 'git.log',
236
+ source: 'builtin',
237
+ intent: 'READ',
238
+ description: text.tools.gitLogDescription,
239
+ riskLevel: 'low',
240
+ sideEffects: ['git_read'],
241
+ concurrency: 'parallel_ok',
242
+ computeResources: (_input, ctx) => [repoResource(ctx)],
243
+ inputSchema: z.object({
244
+ ref: z.string().optional().describe('Starting ref (default: HEAD)'),
245
+ maxCount: z.number().int().min(1).max(200).default(20).describe('Max commits to return'),
246
+ file: z.string().optional().describe('Limit to commits touching this file'),
247
+ diffStat: z.boolean().default(false).describe('Include diffstat for each commit'),
248
+ }),
249
+ outputSchema: z.object({
250
+ commits: z.array(z.object({
251
+ hash: z.string(),
252
+ subject: z.string(),
253
+ author: z.string(),
254
+ date: z.string(),
255
+ parentHashes: z.string(),
256
+ stat: z.string().optional(),
257
+ })),
258
+ }),
259
+ allowedPhases: [Phase.SLASH, Phase.CONTEXT, Phase.EXPLORE, Phase.PLAN, Phase.AUTOPILOT],
260
+ };
261
+ export async function executeGitLog(input, ctx) {
262
+ const { ref, maxCount, file, diffStat } = input;
263
+ const args = ['log', `--format=%H%x00%s%x00%an%x00%aI%x00%P`, '-z', `-n${maxCount}`];
264
+ if (diffStat)
265
+ args.push('--stat');
266
+ if (ref)
267
+ args.push(ref);
268
+ if (file)
269
+ args.push('--', file);
270
+ const repoRoot = ctx.worktreeRoot || ctx.repoRoot;
271
+ const git = new GitAdapter(repoRoot);
272
+ const res = await git.execMeta(args, {
273
+ cwd: repoRoot,
274
+ env: ctx.env,
275
+ limits: { maxStdoutBytes: LIMITS.maxToolOutputBytes, maxStderrChars: 16_384 },
276
+ timeoutMs: LIMITS.gitTimeoutMs,
277
+ });
278
+ if (!res.ok) {
279
+ if (res.error?.message)
280
+ throw new Error(text.git.processError(res.error.message));
281
+ throw new Error(text.git.commandFailedDetailed(res.code, res.stderr.trim()));
282
+ }
283
+ if (res.stdoutTruncated)
284
+ throw new Error(text.git.outputTruncated(LIMITS.maxToolOutputBytes));
285
+ const commits = parseLogOutput(res.stdout.toString('utf8'), diffStat);
286
+ return { commits };
287
+ }
288
+ function parseLogOutput(raw, includeStat) {
289
+ // With -z, records are NUL-separated. Each record is: hash\0subject\0author\0date\0parents[\0stat...]
290
+ const records = raw.split('\0');
291
+ const commits = [];
292
+ // Each commit has 5 core fields; stat is optional extra
293
+ const fieldsPerCommit = 5;
294
+ let i = 0;
295
+ while (i + fieldsPerCommit - 1 < records.length) {
296
+ const hash = records[i].replace(/^\n/, '');
297
+ const subject = records[i + 1];
298
+ const author = records[i + 2];
299
+ const date = records[i + 3];
300
+ const parentHashes = records[i + 4];
301
+ i += fieldsPerCommit;
302
+ let stat;
303
+ if (includeStat && i < records.length) {
304
+ // The stat portion may contain newlines; collect until next commit header or end
305
+ const nextCommitIdx = records.findIndex((r, idx) => idx >= i && /^[0-9a-f]{40}/.test(r.replace(/^\n/, '')));
306
+ const endIdx = nextCommitIdx > i ? nextCommitIdx : records.length;
307
+ stat = records.slice(i, endIdx).join('\0').trim() || undefined;
308
+ i = endIdx;
309
+ }
310
+ commits.push({ hash, subject, author, date, parentHashes, stat });
311
+ }
312
+ return commits;
313
+ }
314
+ // ── git.show ──────────────────────────────────────────────────────────
315
+ export const gitShowSpec = {
316
+ name: 'git.show',
317
+ source: 'builtin',
318
+ intent: 'READ',
319
+ description: text.tools.gitShowDescription,
320
+ riskLevel: 'low',
321
+ sideEffects: ['git_read'],
322
+ concurrency: 'parallel_ok',
323
+ computeResources: (_input, ctx) => [repoResource(ctx)],
324
+ inputSchema: z.object({
325
+ ref: z.string().describe('Git reference (commit hash, branch, tag)'),
326
+ stat: z.boolean().default(true).describe('Include diffstat'),
327
+ }),
328
+ outputSchema: z.object({
329
+ ref: z.string(),
330
+ content: z.string(),
331
+ }),
332
+ allowedPhases: [Phase.SLASH, Phase.CONTEXT, Phase.EXPLORE, Phase.PLAN, Phase.AUTOPILOT],
333
+ };
334
+ export async function executeGitShow(input, ctx) {
335
+ const { ref, stat } = input;
336
+ const args = ['show'];
337
+ if (stat)
338
+ args.push('--stat');
339
+ args.push(ref);
340
+ const repoRoot = ctx.worktreeRoot || ctx.repoRoot;
341
+ const git = new GitAdapter(repoRoot);
342
+ const res = await git.execMeta(args, {
343
+ cwd: repoRoot,
344
+ env: ctx.env,
345
+ limits: { maxStdoutBytes: LIMITS.maxToolOutputBytes, maxStderrChars: 16_384 },
346
+ timeoutMs: LIMITS.gitTimeoutMs,
347
+ });
348
+ if (!res.ok) {
349
+ if (res.error?.message)
350
+ throw new Error(text.git.processError(res.error.message));
351
+ throw new Error(text.git.commandFailedDetailed(res.code, res.stderr.trim()));
352
+ }
353
+ if (res.stdoutTruncated)
354
+ throw new Error(text.git.outputTruncated(LIMITS.maxToolOutputBytes));
355
+ return {
356
+ ref,
357
+ content: res.stdout.toString('utf8'),
358
+ };
359
+ }
118
360
  //# sourceMappingURL=git.js.map
@@ -0,0 +1,79 @@
1
+ import { join } from 'path';
2
+ import { z } from 'zod';
3
+ import { text } from '../../../locales/index.js';
4
+ import { spawnCommand } from '../../runtime/process-runner.js';
5
+ import { Phase } from '../../types/runtime.js';
6
+ import { normalizePath } from '../../utils/path.js';
7
+ import { pathPrefixResource } from '../parallel/resource-helpers.js';
8
+ const RG_TIMEOUT_MS = 10_000;
9
+ export const globFindSpec = {
10
+ name: 'glob.find',
11
+ source: 'builtin',
12
+ intent: 'SEARCH',
13
+ description: text.tools.globFindDescription,
14
+ riskLevel: 'low',
15
+ sideEffects: ['fs_read'],
16
+ concurrency: 'parallel_ok',
17
+ computeResources: (_input, ctx) => [pathPrefixResource(ctx, '.')],
18
+ inputSchema: z.object({
19
+ pattern: z.string().describe('Glob pattern (e.g. "**/*.ts", "src/**/*.test.*")'),
20
+ directory: z.string().optional().describe('Directory to search in (relative, default: ".")'),
21
+ maxMatches: z
22
+ .number()
23
+ .int()
24
+ .min(1)
25
+ .max(5000)
26
+ .default(200)
27
+ .describe('Maximum number of files to return'),
28
+ respectGitignore: z.boolean().default(true).describe('Respect .gitignore (default: true)'),
29
+ includeHidden: z.boolean().default(false).describe('Include hidden files (starting with ".")'),
30
+ }),
31
+ outputSchema: z.object({
32
+ files: z.array(z.string()),
33
+ truncated: z.boolean(),
34
+ totalFound: z.number(),
35
+ }),
36
+ allowedPhases: [
37
+ Phase.SLASH,
38
+ Phase.CONTEXT,
39
+ Phase.EXPLORE,
40
+ Phase.PLAN,
41
+ Phase.AUTOPILOT,
42
+ Phase.VERIFY,
43
+ ],
44
+ };
45
+ export async function executeGlobFind(input, ctx) {
46
+ const repoRoot = ctx.worktreeRoot || ctx.repoRoot;
47
+ const cwd = input.directory ? join(repoRoot, input.directory) : repoRoot;
48
+ const args = ['--files'];
49
+ if (!input.respectGitignore)
50
+ args.push('--no-ignore');
51
+ if (input.includeHidden)
52
+ args.push('--hidden');
53
+ args.push('--glob', input.pattern);
54
+ args.push(cwd);
55
+ let stdout = '';
56
+ const result = await spawnCommand({
57
+ command: 'rg',
58
+ args,
59
+ cwd: repoRoot,
60
+ env: ctx.env ?? process.env,
61
+ timeoutMs: RG_TIMEOUT_MS,
62
+ onStdoutChunk: (chunk) => {
63
+ stdout += Buffer.from(chunk).toString();
64
+ },
65
+ onStderrChunk: () => { },
66
+ });
67
+ if (result.error || result.timedOut || (result.code !== 0 && result.code !== 1)) {
68
+ return { files: [], truncated: false, totalFound: 0 };
69
+ }
70
+ const allFiles = stdout
71
+ .split('\n')
72
+ .map((line) => normalizePath(line.trim()).replace(/^(\.\/|\/)+/, ''))
73
+ .filter(Boolean);
74
+ const totalFound = allFiles.length;
75
+ const truncated = totalFound > input.maxMatches;
76
+ const files = allFiles.slice(0, input.maxMatches);
77
+ return { files, truncated, totalFound };
78
+ }
79
+ //# sourceMappingURL=glob.js.map
@@ -1,12 +1,16 @@
1
+ import { agentAwaitTaskSpec } from '../../sub-agent/tools/task-await.js';
1
2
  import { subAgentTaskSpec } from '../../sub-agent/tools/task-spawn.js';
3
+ import { agentTeamSpec } from '../../sub-agent/tools/team.js';
4
+ import { defineTool } from '../types.js';
2
5
  import { artifactReadSpec, executeArtifactRead } from './artifact.js';
3
6
  import { astGrepSpec, executeAstGrep } from './ast-grep.js';
4
- import { astDefsRefsSpec, executeAstDefsRefs } from './ast.js';
7
+ import { astDefsRefsSpec, executeAstDefsRefs, codeFindReferencesSpec, executeCodeFindReferences, } from './ast.js';
5
8
  import { benchmarkReportSpec, executeBenchmarkReport, executeGitApplyCheck, executeGitDiffCheck, executeSweBenchGetReport, executeSweBenchLoadInstance, executeSweBenchSubmitPredictions, executeSweBenchWritePrediction, gitApplyCheckSpec, gitDiffCheckSpec, sweBenchGetReportSpec, sweBenchLoadInstanceSpec, sweBenchSubmitPredictionsSpec, sweBenchWritePredictionSpec, } from './benchmark.js';
6
9
  import { codeSearchExecutor } from './code-search/executor.js';
7
10
  import { CodeSearchSpec } from './code-search/spec.js';
8
- import { codeReadSpec, executeFsCreateDirectory, executeFsList, executeFsListDirectory, executeFsListFiles, executeFsReadFile, executeFsDeleteFile, executeFsWriteFile, fsCreateDirectorySpec, fsDeleteFileSpec, fsListSpec, fsListDirectorySpec, fsListFilesSpec, fsReadFileSpec, fsWriteFileSpec, } from './fs.js';
9
- import { gitCatSpec, executeGitCat, gitStatusSpec, executeGitStatus } from './git.js';
11
+ import { codeReadSpec, executeFsCreateDirectory, executeFsEditFile, executeFsList, executeFsListDirectory, executeFsListFiles, executeFsReadFile, executeFsDeleteFile, executeFsWriteFile, fsCreateDirectorySpec, fsDeleteFileSpec, fsEditFileSpec, fsListSpec, fsListDirectorySpec, fsListFilesSpec, fsReadFileSpec, fsWriteFileSpec, } from './fs.js';
12
+ import { gitCatSpec, executeGitCat, gitStatusSpec, executeGitStatus, gitBlameSpec, executeGitBlame, gitLogSpec, executeGitLog, gitShowSpec, executeGitShow, } from './git.js';
13
+ import { globFindSpec, executeGlobFind } from './glob.js';
10
14
  import { askUserSpec } from './interaction.js';
11
15
  import { updateKnowledgeSpec, executeUpdateKnowledge } from './knowledge.js';
12
16
  import { planInitSpec, planReadSpec, planUpdateSpec } from './plan.js';
@@ -15,120 +19,58 @@ import { shellExecSpec, executeShellExec } from './shell.js';
15
19
  import { verifyRunSpec, executeVerifyRun } from './verify.js';
16
20
  import { workspaceInfoSpec, executeWorkspaceInfo } from './workspace.js';
17
21
  /**
18
- * Registers all builtin tools into the provided registry
22
+ * Registers all builtin tools into the provided registry.
23
+ * Uses defineTool() to pair specs with executors type-safely.
19
24
  */
20
25
  export function registerAllBuiltins(registry) {
21
- // Register sub-agent tool
26
+ // Sub-agent tools (already self-contained)
22
27
  registry.register(subAgentTaskSpec);
23
- registry.register({
24
- ...artifactReadSpec,
25
- executor: executeArtifactRead,
26
- });
27
- registry.register({
28
- ...updateKnowledgeSpec,
29
- executor: executeUpdateKnowledge,
30
- });
31
- registry.register({
32
- ...workspaceInfoSpec,
33
- executor: executeWorkspaceInfo,
34
- });
35
- registry.register({
36
- ...proposalApplySpec,
37
- executor: executeProposalApply,
38
- });
39
- // Register unified code.search with its specific executor
40
- registry.register({
41
- ...CodeSearchSpec,
42
- executor: codeSearchExecutor,
43
- });
44
- registry.register({
45
- ...astDefsRefsSpec,
46
- executor: executeAstDefsRefs,
47
- });
48
- registry.register({
49
- ...gitCatSpec,
50
- executor: executeGitCat,
51
- });
52
- registry.register({
53
- ...gitStatusSpec,
54
- executor: executeGitStatus,
55
- });
56
- registry.register({
57
- ...gitDiffCheckSpec,
58
- executor: executeGitDiffCheck,
59
- });
60
- registry.register({
61
- ...gitApplyCheckSpec,
62
- executor: executeGitApplyCheck,
63
- });
64
- registry.register({
65
- ...benchmarkReportSpec,
66
- executor: executeBenchmarkReport,
67
- });
68
- registry.register({
69
- ...sweBenchLoadInstanceSpec,
70
- executor: executeSweBenchLoadInstance,
71
- });
72
- registry.register({
73
- ...sweBenchWritePredictionSpec,
74
- executor: executeSweBenchWritePrediction,
75
- });
76
- registry.register({
77
- ...sweBenchSubmitPredictionsSpec,
78
- executor: executeSweBenchSubmitPredictions,
79
- });
80
- registry.register({
81
- ...sweBenchGetReportSpec,
82
- executor: executeSweBenchGetReport,
83
- });
84
- registry.register({
85
- ...fsReadFileSpec,
86
- executor: executeFsReadFile,
87
- });
88
- registry.register({
89
- ...codeReadSpec,
90
- executor: executeFsReadFile,
91
- });
92
- registry.register({
93
- ...fsListSpec,
94
- executor: executeFsList,
95
- });
96
- registry.register({
97
- ...fsListDirectorySpec,
98
- executor: executeFsListDirectory,
99
- });
100
- registry.register({
101
- ...fsListFilesSpec,
102
- executor: executeFsListFiles,
103
- });
104
- registry.register({
105
- ...astGrepSpec,
106
- executor: executeAstGrep,
107
- });
108
- registry.register({
109
- ...verifyRunSpec,
110
- executor: executeVerifyRun,
111
- });
112
- registry.register({
113
- ...shellExecSpec,
114
- executor: executeShellExec,
115
- });
116
- registry.register({
117
- ...fsWriteFileSpec,
118
- executor: executeFsWriteFile,
119
- });
120
- registry.register({
121
- ...fsCreateDirectorySpec,
122
- executor: executeFsCreateDirectory,
123
- });
124
- registry.register({
125
- ...fsDeleteFileSpec,
126
- executor: executeFsDeleteFile,
127
- });
28
+ registry.register(agentAwaitTaskSpec);
29
+ registry.register(agentTeamSpec);
30
+ // Artifact & knowledge
31
+ registry.register(defineTool(artifactReadSpec, executeArtifactRead));
32
+ registry.register(defineTool(updateKnowledgeSpec, executeUpdateKnowledge));
33
+ registry.register(defineTool(workspaceInfoSpec, executeWorkspaceInfo));
34
+ registry.register(defineTool(proposalApplySpec, executeProposalApply));
35
+ // Code search & AST
36
+ registry.register(defineTool(CodeSearchSpec, codeSearchExecutor));
37
+ registry.register(defineTool(astDefsRefsSpec, executeAstDefsRefs));
38
+ registry.register(defineTool(codeFindReferencesSpec, executeCodeFindReferences));
39
+ registry.register(defineTool(astGrepSpec, executeAstGrep));
40
+ // Git
41
+ registry.register(defineTool(gitCatSpec, executeGitCat));
42
+ registry.register(defineTool(gitStatusSpec, executeGitStatus));
43
+ registry.register(defineTool(gitBlameSpec, executeGitBlame));
44
+ registry.register(defineTool(gitLogSpec, executeGitLog));
45
+ registry.register(defineTool(gitShowSpec, executeGitShow));
46
+ registry.register(defineTool(gitDiffCheckSpec, executeGitDiffCheck));
47
+ registry.register(defineTool(gitApplyCheckSpec, executeGitApplyCheck));
48
+ // Glob
49
+ registry.register(defineTool(globFindSpec, executeGlobFind));
50
+ // Benchmark / SWE-bench
51
+ registry.register(defineTool(benchmarkReportSpec, executeBenchmarkReport));
52
+ registry.register(defineTool(sweBenchLoadInstanceSpec, executeSweBenchLoadInstance));
53
+ registry.register(defineTool(sweBenchWritePredictionSpec, executeSweBenchWritePrediction));
54
+ registry.register(defineTool(sweBenchSubmitPredictionsSpec, executeSweBenchSubmitPredictions));
55
+ registry.register(defineTool(sweBenchGetReportSpec, executeSweBenchGetReport));
56
+ // Filesystem
57
+ registry.register(defineTool(fsReadFileSpec, executeFsReadFile));
58
+ registry.register(defineTool(codeReadSpec, executeFsReadFile));
59
+ registry.register(defineTool(fsListSpec, executeFsList));
60
+ registry.register(defineTool(fsListDirectorySpec, executeFsListDirectory));
61
+ registry.register(defineTool(fsListFilesSpec, executeFsListFiles));
62
+ registry.register(defineTool(fsWriteFileSpec, executeFsWriteFile));
63
+ registry.register(defineTool(fsEditFileSpec, executeFsEditFile));
64
+ registry.register(defineTool(fsCreateDirectorySpec, executeFsCreateDirectory));
65
+ registry.register(defineTool(fsDeleteFileSpec, executeFsDeleteFile));
66
+ // Execution
67
+ registry.register(defineTool(verifyRunSpec, executeVerifyRun));
68
+ registry.register(defineTool(shellExecSpec, executeShellExec));
69
+ // Plan & interaction
128
70
  registry.register(planInitSpec);
129
71
  registry.register(planReadSpec);
130
72
  registry.register(planUpdateSpec);
131
73
  registry.register(askUserSpec);
132
74
  }
133
- export { CodeSearchSpec, codeSearchExecutor, astDefsRefsSpec as codeAstSpec, executeAstDefsRefs as executeCodeAst, gitCatSpec, executeGitCat, gitStatusSpec, executeGitStatus, codeReadSpec, fsListSpec, executeFsList, fsReadFileSpec as fsReadSpec, executeFsReadFile as executeFsRead, updateKnowledgeSpec, executeUpdateKnowledge, astGrepSpec as codeSearchAstSpec, executeAstGrep as executeCodeSearchAst, verifyRunSpec as testRunSpec, executeVerifyRun as executeTestRun, gitDiffCheckSpec, executeGitDiffCheck, gitApplyCheckSpec, executeGitApplyCheck, benchmarkReportSpec, executeBenchmarkReport, sweBenchLoadInstanceSpec, executeSweBenchLoadInstance, sweBenchWritePredictionSpec, executeSweBenchWritePrediction, sweBenchSubmitPredictionsSpec, executeSweBenchSubmitPredictions, sweBenchGetReportSpec, executeSweBenchGetReport, workspaceInfoSpec, executeWorkspaceInfo, };
75
+ export { CodeSearchSpec, codeSearchExecutor, astDefsRefsSpec as codeAstSpec, executeAstDefsRefs as executeCodeAst, codeFindReferencesSpec, executeCodeFindReferences, gitCatSpec, executeGitCat, gitStatusSpec, executeGitStatus, gitBlameSpec, executeGitBlame, gitLogSpec, executeGitLog, gitShowSpec, executeGitShow, globFindSpec, executeGlobFind, codeReadSpec, fsListSpec, executeFsList, fsReadFileSpec as fsReadSpec, executeFsReadFile as executeFsRead, updateKnowledgeSpec, executeUpdateKnowledge, astGrepSpec as codeSearchAstSpec, executeAstGrep as executeCodeSearchAst, verifyRunSpec as testRunSpec, executeVerifyRun as executeTestRun, gitDiffCheckSpec, executeGitDiffCheck, gitApplyCheckSpec, executeGitApplyCheck, benchmarkReportSpec, executeBenchmarkReport, sweBenchLoadInstanceSpec, executeSweBenchLoadInstance, sweBenchWritePredictionSpec, executeSweBenchWritePrediction, sweBenchSubmitPredictionsSpec, executeSweBenchSubmitPredictions, sweBenchGetReportSpec, executeSweBenchGetReport, workspaceInfoSpec, executeWorkspaceInfo, };
134
76
  //# sourceMappingURL=index.js.map
@@ -75,28 +75,26 @@ export const askUserSpec = {
75
75
  outputSchema: askUserOutputSchema,
76
76
  executor: async (input, ctx) => {
77
77
  if (ctx.agentKind === 'subagent') {
78
- const err = new Error(text.tools.askUserSubagentBlocked);
79
- err.code = 'ASK_USER_SUBAGENT_BLOCKED';
80
- throw err;
78
+ throw Object.assign(new Error(text.tools.askUserSubagentBlocked), {
79
+ code: 'ASK_USER_SUBAGENT_BLOCKED',
80
+ });
81
81
  }
82
82
  if (!ctx.userInputProvider) {
83
- const err = new Error(text.tools.askUserRequired);
84
83
  const inputRequired = buildInputRequired(input);
85
- err.code = 'INTERRUPT_REQUIRED';
86
- err.interrupt = {
87
- type: 'awaiting_input',
88
- reason: inputRequired.reason ?? 'clarification',
89
- prompt: inputRequired.prompt,
90
- data: { inputRequired },
91
- };
92
- throw err;
84
+ throw Object.assign(new Error(text.tools.askUserRequired), {
85
+ code: 'INTERRUPT_REQUIRED',
86
+ interrupt: {
87
+ type: 'awaiting_input',
88
+ reason: inputRequired.reason ?? 'clarification',
89
+ prompt: inputRequired.prompt,
90
+ data: { inputRequired },
91
+ },
92
+ });
93
93
  }
94
94
  const output = await ctx.userInputProvider.askUser(input, { signal: ctx.signal });
95
95
  const validationError = validateAnswers(input, output.answers);
96
96
  if (validationError) {
97
- const err = new Error(validationError);
98
- err.code = 'INVALID_OUTPUT';
99
- throw err;
97
+ throw Object.assign(new Error(validationError), { code: 'INVALID_OUTPUT' });
100
98
  }
101
99
  return { questions: input.questions, answers: output.answers };
102
100
  },