@ikarmic/forge-core 4.5.0 → 5.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 (643) hide show
  1. package/LICENSE +44 -21
  2. package/README.md +1 -1
  3. package/dist/agent/agent.d.ts +8 -1
  4. package/dist/agent/agent.js +143 -23
  5. package/dist/agent/architect.d.ts +0 -1
  6. package/dist/agent/architect.js +0 -1
  7. package/dist/agent/background.d.ts +58 -0
  8. package/dist/agent/background.js +139 -0
  9. package/dist/agent/cache-hints.d.ts +0 -1
  10. package/dist/agent/cache-hints.js +0 -1
  11. package/dist/agent/cost-router.d.ts +0 -1
  12. package/dist/agent/cost-router.js +0 -1
  13. package/dist/agent/enhance-prompt.d.ts +9 -0
  14. package/dist/agent/enhance-prompt.js +34 -0
  15. package/dist/agent/goal.d.ts +54 -0
  16. package/dist/agent/goal.js +65 -0
  17. package/dist/agent/index.d.ts +0 -1
  18. package/dist/agent/index.js +0 -1
  19. package/dist/agent/loop-guard.d.ts +21 -0
  20. package/dist/agent/loop-guard.js +41 -0
  21. package/dist/agent/prompts.d.ts +0 -1
  22. package/dist/agent/prompts.js +0 -1
  23. package/dist/agent/think-tags.d.ts +0 -1
  24. package/dist/agent/think-tags.js +0 -1
  25. package/dist/agent/verify.d.ts +0 -1
  26. package/dist/agent/verify.js +0 -1
  27. package/dist/agents/agent-files.d.ts +43 -0
  28. package/dist/agents/agent-files.js +109 -0
  29. package/dist/ai-comments/index.d.ts +0 -1
  30. package/dist/ai-comments/index.js +0 -1
  31. package/dist/attachments.d.ts +0 -1
  32. package/dist/attachments.js +0 -1
  33. package/dist/browser/cdp.d.ts +0 -1
  34. package/dist/browser/cdp.js +0 -1
  35. package/dist/browser/chrome.d.ts +0 -1
  36. package/dist/browser/chrome.js +0 -1
  37. package/dist/browser/session.d.ts +0 -1
  38. package/dist/browser/session.js +0 -1
  39. package/dist/checkpoints/index.d.ts +0 -1
  40. package/dist/checkpoints/index.js +0 -1
  41. package/dist/checkpoints/store.d.ts +0 -1
  42. package/dist/checkpoints/store.js +5 -2
  43. package/dist/checkpoints/types.d.ts +0 -1
  44. package/dist/checkpoints/types.js +0 -1
  45. package/dist/code-index/builder.d.ts +0 -1
  46. package/dist/code-index/builder.js +0 -1
  47. package/dist/code-index/index-store.d.ts +0 -1
  48. package/dist/code-index/index-store.js +0 -1
  49. package/dist/code-index/parser.d.ts +0 -1
  50. package/dist/code-index/parser.js +0 -1
  51. package/dist/code-index/types.d.ts +0 -1
  52. package/dist/code-index/types.js +0 -1
  53. package/dist/commands/custom-commands.d.ts +9 -5
  54. package/dist/commands/custom-commands.js +13 -3
  55. package/dist/config-file.d.ts +47 -1
  56. package/dist/config-file.js +249 -6
  57. package/dist/config-merge.d.ts +13 -0
  58. package/dist/config-merge.js +67 -0
  59. package/dist/config-schema.d.ts +340 -0
  60. package/dist/config-schema.js +126 -0
  61. package/dist/config.d.ts +0 -1
  62. package/dist/config.js +2 -2
  63. package/dist/context/compaction.d.ts +0 -1
  64. package/dist/context/compaction.js +10 -2
  65. package/dist/context/mask.d.ts +0 -1
  66. package/dist/context/mask.js +1 -2
  67. package/dist/credentials/index.d.ts +0 -1
  68. package/dist/credentials/index.js +0 -1
  69. package/dist/credentials/types.d.ts +0 -1
  70. package/dist/credentials/types.js +0 -1
  71. package/dist/custom-providers.d.ts +95 -0
  72. package/dist/custom-providers.js +120 -0
  73. package/dist/diff/index.d.ts +0 -1
  74. package/dist/diff/index.js +0 -1
  75. package/dist/diff/unified-diff.d.ts +0 -1
  76. package/dist/diff/unified-diff.js +0 -1
  77. package/dist/git/auto-commit.d.ts +3 -4
  78. package/dist/git/auto-commit.js +8 -7
  79. package/dist/git/index.d.ts +0 -1
  80. package/dist/git/index.js +0 -1
  81. package/dist/github/github-tools.d.ts +2 -3
  82. package/dist/github/github-tools.js +0 -1
  83. package/dist/hooks/agent-runner.d.ts +0 -1
  84. package/dist/hooks/agent-runner.js +0 -1
  85. package/dist/hooks/bus.d.ts +0 -1
  86. package/dist/hooks/bus.js +0 -1
  87. package/dist/hooks/config.d.ts +0 -1
  88. package/dist/hooks/config.js +0 -1
  89. package/dist/hooks/events.d.ts +0 -1
  90. package/dist/hooks/events.js +0 -1
  91. package/dist/hooks/index.d.ts +0 -1
  92. package/dist/hooks/index.js +0 -1
  93. package/dist/hooks/loader.d.ts +0 -1
  94. package/dist/hooks/loader.js +0 -1
  95. package/dist/hooks/runner.d.ts +0 -1
  96. package/dist/hooks/runner.js +3 -3
  97. package/dist/hooks/watch-coalescer.d.ts +0 -1
  98. package/dist/hooks/watch-coalescer.js +0 -1
  99. package/dist/hooks/watch-ignore.d.ts +0 -1
  100. package/dist/hooks/watch-ignore.js +0 -1
  101. package/dist/hooks/watcher.d.ts +0 -1
  102. package/dist/hooks/watcher.js +0 -1
  103. package/dist/import/claude-code.d.ts +39 -0
  104. package/dist/import/claude-code.js +254 -0
  105. package/dist/index.d.ts +37 -7
  106. package/dist/index.js +28 -5
  107. package/dist/lazy-model.d.ts +0 -1
  108. package/dist/lazy-model.js +0 -1
  109. package/dist/lint/auto-lint.d.ts +0 -1
  110. package/dist/lint/auto-lint.js +0 -1
  111. package/dist/lint/index.d.ts +0 -1
  112. package/dist/lint/index.js +0 -1
  113. package/dist/lsp/client.d.ts +5 -1
  114. package/dist/lsp/client.js +39 -4
  115. package/dist/lsp/diagnostics.d.ts +0 -1
  116. package/dist/lsp/diagnostics.js +0 -1
  117. package/dist/lsp/index.d.ts +0 -1
  118. package/dist/lsp/index.js +0 -1
  119. package/dist/mcp/catalog.d.ts +0 -1
  120. package/dist/mcp/catalog.js +0 -1
  121. package/dist/mcp/index.d.ts +5 -2
  122. package/dist/mcp/index.js +3 -2
  123. package/dist/mcp/json-schema-to-zod.d.ts +0 -1
  124. package/dist/mcp/json-schema-to-zod.js +0 -1
  125. package/dist/mcp/manager.d.ts +17 -4
  126. package/dist/mcp/manager.js +27 -3
  127. package/dist/mcp/marketplace-types.d.ts +0 -1
  128. package/dist/mcp/marketplace-types.js +0 -1
  129. package/dist/mcp/marketplace.d.ts +2 -1
  130. package/dist/mcp/marketplace.js +10 -5
  131. package/dist/mcp/mcp-client.d.ts +12 -3
  132. package/dist/mcp/mcp-client.js +74 -18
  133. package/dist/mcp/mcp-config.d.ts +2 -1
  134. package/dist/mcp/mcp-config.js +1 -1
  135. package/dist/mcp/oauth.d.ts +55 -0
  136. package/dist/mcp/oauth.js +197 -0
  137. package/dist/mcp/registry.d.ts +0 -1
  138. package/dist/mcp/registry.js +0 -1
  139. package/dist/mcp/resource-tools.d.ts +8 -0
  140. package/dist/mcp/resource-tools.js +56 -0
  141. package/dist/memory/memory-store.d.ts +0 -1
  142. package/dist/memory/memory-store.js +0 -1
  143. package/dist/memory/rank.d.ts +0 -1
  144. package/dist/memory/rank.js +0 -1
  145. package/dist/memory/session-digest.d.ts +12 -0
  146. package/dist/memory/session-digest.js +47 -0
  147. package/dist/memory/stale.d.ts +0 -1
  148. package/dist/memory/stale.js +2 -2
  149. package/dist/model-alias.d.ts +18 -3
  150. package/dist/model-alias.js +27 -4
  151. package/dist/model-catalog.d.ts +0 -1
  152. package/dist/model-catalog.js +0 -2
  153. package/dist/model-list.d.ts +0 -1
  154. package/dist/model-list.js +2 -2
  155. package/dist/model-overrides.d.ts +30 -0
  156. package/dist/model-overrides.js +48 -0
  157. package/dist/orchestrator/board-tools.d.ts +0 -1
  158. package/dist/orchestrator/board-tools.js +0 -1
  159. package/dist/orchestrator/board.d.ts +0 -1
  160. package/dist/orchestrator/board.js +0 -1
  161. package/dist/orchestrator/index.d.ts +0 -1
  162. package/dist/orchestrator/index.js +0 -1
  163. package/dist/orchestrator/orchestrator.d.ts +0 -1
  164. package/dist/orchestrator/orchestrator.js +0 -1
  165. package/dist/orchestrator/router.d.ts +0 -1
  166. package/dist/orchestrator/router.js +0 -1
  167. package/dist/orchestrator/specialists-registry.d.ts +0 -1
  168. package/dist/orchestrator/specialists-registry.js +2 -4
  169. package/dist/orchestrator/specialists.d.ts +0 -1
  170. package/dist/orchestrator/specialists.js +4 -5
  171. package/dist/orchestrator/types.d.ts +0 -1
  172. package/dist/orchestrator/types.js +0 -1
  173. package/dist/plugins/index.d.ts +0 -1
  174. package/dist/plugins/index.js +0 -1
  175. package/dist/plugins/install.d.ts +0 -1
  176. package/dist/plugins/install.js +0 -1
  177. package/dist/plugins/loader.d.ts +0 -1
  178. package/dist/plugins/loader.js +0 -1
  179. package/dist/policy/audit.d.ts +0 -1
  180. package/dist/policy/audit.js +0 -1
  181. package/dist/policy/ca-certs.d.ts +8 -0
  182. package/dist/policy/ca-certs.js +30 -0
  183. package/dist/policy/policy.d.ts +0 -1
  184. package/dist/policy/policy.js +0 -1
  185. package/dist/policy/proxy.d.ts +10 -4
  186. package/dist/policy/proxy.js +33 -7
  187. package/dist/pricing.d.ts +0 -1
  188. package/dist/pricing.js +4 -1
  189. package/dist/providers.d.ts +7 -1
  190. package/dist/providers.js +39 -6
  191. package/dist/repomap/index.d.ts +0 -1
  192. package/dist/repomap/index.js +0 -1
  193. package/dist/repomap/repo-map.d.ts +0 -1
  194. package/dist/repomap/repo-map.js +0 -1
  195. package/dist/semantic/chunker.d.ts +0 -1
  196. package/dist/semantic/chunker.js +0 -1
  197. package/dist/semantic/embedder.d.ts +15 -1
  198. package/dist/semantic/embedder.js +25 -1
  199. package/dist/semantic/semantic-index.d.ts +10 -3
  200. package/dist/semantic/semantic-index.js +16 -8
  201. package/dist/semantic/vector-store.d.ts +0 -1
  202. package/dist/semantic/vector-store.js +0 -1
  203. package/dist/sessions/index.d.ts +1 -1
  204. package/dist/sessions/index.js +1 -1
  205. package/dist/sessions/prune.d.ts +23 -0
  206. package/dist/sessions/prune.js +35 -0
  207. package/dist/sessions/search.d.ts +0 -1
  208. package/dist/sessions/search.js +0 -1
  209. package/dist/sessions/session-export.d.ts +0 -1
  210. package/dist/sessions/session-export.js +0 -1
  211. package/dist/sessions/session-store.d.ts +0 -1
  212. package/dist/sessions/session-store.js +2 -2
  213. package/dist/sessions/watch.d.ts +0 -1
  214. package/dist/sessions/watch.js +0 -1
  215. package/dist/settings-export.d.ts +0 -1
  216. package/dist/settings-export.js +0 -1
  217. package/dist/skills/activator.d.ts +0 -1
  218. package/dist/skills/activator.js +0 -1
  219. package/dist/skills/builtin.d.ts +2 -0
  220. package/dist/skills/builtin.js +68 -0
  221. package/dist/skills/index.d.ts +2 -1
  222. package/dist/skills/index.js +2 -1
  223. package/dist/skills/loader.d.ts +10 -4
  224. package/dist/skills/loader.js +20 -8
  225. package/dist/skills/marketplace-types.d.ts +0 -1
  226. package/dist/skills/marketplace-types.js +0 -1
  227. package/dist/skills/marketplace.d.ts +0 -1
  228. package/dist/skills/marketplace.js +2 -2
  229. package/dist/skills/parser.d.ts +0 -1
  230. package/dist/skills/parser.js +0 -1
  231. package/dist/skills/remote.d.ts +14 -0
  232. package/dist/skills/remote.js +131 -0
  233. package/dist/skills/types.d.ts +10 -1
  234. package/dist/skills/types.js +0 -1
  235. package/dist/specs/generate.d.ts +0 -1
  236. package/dist/specs/generate.js +0 -1
  237. package/dist/specs/index.d.ts +0 -1
  238. package/dist/specs/index.js +0 -1
  239. package/dist/specs/store.d.ts +0 -1
  240. package/dist/specs/store.js +0 -1
  241. package/dist/specs/sync.d.ts +0 -1
  242. package/dist/specs/sync.js +0 -1
  243. package/dist/specs/tasks-parser.d.ts +0 -1
  244. package/dist/specs/tasks-parser.js +0 -1
  245. package/dist/specs/types.d.ts +0 -1
  246. package/dist/specs/types.js +0 -1
  247. package/dist/steering/extra-instructions.d.ts +8 -0
  248. package/dist/steering/extra-instructions.js +104 -0
  249. package/dist/steering/folder-instructions.d.ts +8 -0
  250. package/dist/steering/folder-instructions.js +28 -0
  251. package/dist/steering/glob.d.ts +0 -1
  252. package/dist/steering/glob.js +0 -1
  253. package/dist/steering/index.d.ts +0 -1
  254. package/dist/steering/index.js +0 -1
  255. package/dist/steering/loader.d.ts +0 -1
  256. package/dist/steering/loader.js +0 -1
  257. package/dist/steering/project-instructions.d.ts +0 -1
  258. package/dist/steering/project-instructions.js +0 -1
  259. package/dist/steering/select.d.ts +0 -1
  260. package/dist/steering/select.js +2 -2
  261. package/dist/steering/types.d.ts +0 -1
  262. package/dist/steering/types.js +0 -1
  263. package/dist/structured/index.d.ts +0 -1
  264. package/dist/structured/index.js +0 -1
  265. package/dist/structured/retry.d.ts +0 -1
  266. package/dist/structured/retry.js +0 -1
  267. package/dist/structured/schema.d.ts +0 -1
  268. package/dist/structured/schema.js +0 -1
  269. package/dist/timed-fetch.d.ts +12 -0
  270. package/dist/timed-fetch.js +83 -0
  271. package/dist/tools/apply-patch.d.ts +52 -0
  272. package/dist/tools/apply-patch.js +197 -0
  273. package/dist/tools/ask-user.d.ts +27 -0
  274. package/dist/tools/ask-user.js +32 -0
  275. package/dist/tools/browser-tools.d.ts +6 -7
  276. package/dist/tools/browser-tools.js +3 -14
  277. package/dist/tools/codebase-search.d.ts +4 -3
  278. package/dist/tools/codebase-search.js +2 -3
  279. package/dist/tools/command-allow.d.ts +0 -1
  280. package/dist/tools/command-allow.js +0 -1
  281. package/dist/tools/edit-file.d.ts +0 -1
  282. package/dist/tools/edit-file.js +5 -4
  283. package/dist/tools/fetch-url.d.ts +7 -1
  284. package/dist/tools/fetch-url.js +52 -20
  285. package/dist/tools/find-references.d.ts +0 -1
  286. package/dist/tools/find-references.js +0 -1
  287. package/dist/tools/find-symbol.d.ts +2 -3
  288. package/dist/tools/find-symbol.js +0 -1
  289. package/dist/tools/ignore-rules.d.ts +0 -1
  290. package/dist/tools/ignore-rules.js +2 -2
  291. package/dist/tools/index.d.ts +5 -2
  292. package/dist/tools/index.js +10 -2
  293. package/dist/tools/list-files.d.ts +0 -1
  294. package/dist/tools/list-files.js +0 -1
  295. package/dist/tools/list-symbols.d.ts +0 -1
  296. package/dist/tools/list-symbols.js +0 -1
  297. package/dist/tools/memory.d.ts +6 -7
  298. package/dist/tools/memory.js +0 -1
  299. package/dist/tools/notebook.d.ts +2 -3
  300. package/dist/tools/notebook.js +0 -1
  301. package/dist/tools/permission-rules.d.ts +32 -0
  302. package/dist/tools/permission-rules.js +182 -0
  303. package/dist/tools/policy.d.ts +0 -1
  304. package/dist/tools/policy.js +0 -1
  305. package/dist/tools/read-file.d.ts +5 -1
  306. package/dist/tools/read-file.js +7 -3
  307. package/dist/tools/read-image.d.ts +0 -1
  308. package/dist/tools/read-image.js +0 -1
  309. package/dist/tools/read-only.d.ts +1 -2
  310. package/dist/tools/read-only.js +2 -1
  311. package/dist/tools/redact.d.ts +0 -1
  312. package/dist/tools/redact.js +0 -1
  313. package/dist/tools/result-cache.d.ts +0 -1
  314. package/dist/tools/result-cache.js +0 -1
  315. package/dist/tools/run-command.d.ts +4 -3
  316. package/dist/tools/run-command.js +12 -9
  317. package/dist/tools/sandbox-loader.d.ts +0 -1
  318. package/dist/tools/sandbox-loader.js +3 -14
  319. package/dist/tools/search-files.d.ts +8 -3
  320. package/dist/tools/search-files.js +43 -1
  321. package/dist/tools/shared.d.ts +5 -1
  322. package/dist/tools/shared.js +30 -3
  323. package/dist/tools/shell-env.d.ts +7 -0
  324. package/dist/tools/shell-env.js +9 -0
  325. package/dist/tools/sub-agent-wait.d.ts +29 -0
  326. package/dist/tools/sub-agent-wait.js +60 -0
  327. package/dist/tools/sub-agent.d.ts +50 -5
  328. package/dist/tools/sub-agent.js +210 -126
  329. package/dist/tools/text-encoding.d.ts +10 -0
  330. package/dist/tools/text-encoding.js +40 -0
  331. package/dist/tools/todo.d.ts +36 -0
  332. package/dist/tools/todo.js +42 -0
  333. package/dist/tools/web-search.d.ts +0 -1
  334. package/dist/tools/web-search.js +0 -1
  335. package/dist/tools/write-file.d.ts +0 -1
  336. package/dist/tools/write-file.js +15 -10
  337. package/dist/tools/write-tools.d.ts +12 -0
  338. package/dist/tools/write-tools.js +18 -0
  339. package/dist/types.d.ts +85 -2
  340. package/dist/types.js +0 -1
  341. package/dist/verify/detect.d.ts +0 -1
  342. package/dist/verify/detect.js +0 -1
  343. package/dist/verify/index.d.ts +0 -1
  344. package/dist/verify/index.js +0 -1
  345. package/dist/worktree/branch-ops.d.ts +0 -1
  346. package/dist/worktree/branch-ops.js +0 -1
  347. package/dist/worktree/index.d.ts +0 -1
  348. package/dist/worktree/index.js +0 -1
  349. package/dist/worktree/worktree.d.ts +3 -1
  350. package/dist/worktree/worktree.js +22 -1
  351. package/package.json +3 -2
  352. package/dist/agent/agent.d.ts.map +0 -1
  353. package/dist/agent/agent.js.map +0 -1
  354. package/dist/agent/architect.d.ts.map +0 -1
  355. package/dist/agent/architect.js.map +0 -1
  356. package/dist/agent/cache-hints.d.ts.map +0 -1
  357. package/dist/agent/cache-hints.js.map +0 -1
  358. package/dist/agent/cost-router.d.ts.map +0 -1
  359. package/dist/agent/cost-router.js.map +0 -1
  360. package/dist/agent/index.d.ts.map +0 -1
  361. package/dist/agent/index.js.map +0 -1
  362. package/dist/agent/prompts.d.ts.map +0 -1
  363. package/dist/agent/prompts.js.map +0 -1
  364. package/dist/agent/think-tags.d.ts.map +0 -1
  365. package/dist/agent/think-tags.js.map +0 -1
  366. package/dist/agent/verify.d.ts.map +0 -1
  367. package/dist/agent/verify.js.map +0 -1
  368. package/dist/ai-comments/index.d.ts.map +0 -1
  369. package/dist/ai-comments/index.js.map +0 -1
  370. package/dist/attachments.d.ts.map +0 -1
  371. package/dist/attachments.js.map +0 -1
  372. package/dist/browser/cdp.d.ts.map +0 -1
  373. package/dist/browser/cdp.js.map +0 -1
  374. package/dist/browser/chrome.d.ts.map +0 -1
  375. package/dist/browser/chrome.js.map +0 -1
  376. package/dist/browser/session.d.ts.map +0 -1
  377. package/dist/browser/session.js.map +0 -1
  378. package/dist/checkpoints/index.d.ts.map +0 -1
  379. package/dist/checkpoints/index.js.map +0 -1
  380. package/dist/checkpoints/store.d.ts.map +0 -1
  381. package/dist/checkpoints/store.js.map +0 -1
  382. package/dist/checkpoints/types.d.ts.map +0 -1
  383. package/dist/checkpoints/types.js.map +0 -1
  384. package/dist/code-index/builder.d.ts.map +0 -1
  385. package/dist/code-index/builder.js.map +0 -1
  386. package/dist/code-index/index-store.d.ts.map +0 -1
  387. package/dist/code-index/index-store.js.map +0 -1
  388. package/dist/code-index/parser.d.ts.map +0 -1
  389. package/dist/code-index/parser.js.map +0 -1
  390. package/dist/code-index/types.d.ts.map +0 -1
  391. package/dist/code-index/types.js.map +0 -1
  392. package/dist/commands/custom-commands.d.ts.map +0 -1
  393. package/dist/commands/custom-commands.js.map +0 -1
  394. package/dist/config-file.d.ts.map +0 -1
  395. package/dist/config-file.js.map +0 -1
  396. package/dist/config.d.ts.map +0 -1
  397. package/dist/config.js.map +0 -1
  398. package/dist/context/compaction.d.ts.map +0 -1
  399. package/dist/context/compaction.js.map +0 -1
  400. package/dist/context/mask.d.ts.map +0 -1
  401. package/dist/context/mask.js.map +0 -1
  402. package/dist/credentials/index.d.ts.map +0 -1
  403. package/dist/credentials/index.js.map +0 -1
  404. package/dist/credentials/types.d.ts.map +0 -1
  405. package/dist/credentials/types.js.map +0 -1
  406. package/dist/diff/index.d.ts.map +0 -1
  407. package/dist/diff/index.js.map +0 -1
  408. package/dist/diff/unified-diff.d.ts.map +0 -1
  409. package/dist/diff/unified-diff.js.map +0 -1
  410. package/dist/git/auto-commit.d.ts.map +0 -1
  411. package/dist/git/auto-commit.js.map +0 -1
  412. package/dist/git/index.d.ts.map +0 -1
  413. package/dist/git/index.js.map +0 -1
  414. package/dist/github/github-tools.d.ts.map +0 -1
  415. package/dist/github/github-tools.js.map +0 -1
  416. package/dist/hooks/agent-runner.d.ts.map +0 -1
  417. package/dist/hooks/agent-runner.js.map +0 -1
  418. package/dist/hooks/bus.d.ts.map +0 -1
  419. package/dist/hooks/bus.js.map +0 -1
  420. package/dist/hooks/config.d.ts.map +0 -1
  421. package/dist/hooks/config.js.map +0 -1
  422. package/dist/hooks/events.d.ts.map +0 -1
  423. package/dist/hooks/events.js.map +0 -1
  424. package/dist/hooks/index.d.ts.map +0 -1
  425. package/dist/hooks/index.js.map +0 -1
  426. package/dist/hooks/loader.d.ts.map +0 -1
  427. package/dist/hooks/loader.js.map +0 -1
  428. package/dist/hooks/runner.d.ts.map +0 -1
  429. package/dist/hooks/runner.js.map +0 -1
  430. package/dist/hooks/watch-coalescer.d.ts.map +0 -1
  431. package/dist/hooks/watch-coalescer.js.map +0 -1
  432. package/dist/hooks/watch-ignore.d.ts.map +0 -1
  433. package/dist/hooks/watch-ignore.js.map +0 -1
  434. package/dist/hooks/watcher.d.ts.map +0 -1
  435. package/dist/hooks/watcher.js.map +0 -1
  436. package/dist/index.d.ts.map +0 -1
  437. package/dist/index.js.map +0 -1
  438. package/dist/lazy-model.d.ts.map +0 -1
  439. package/dist/lazy-model.js.map +0 -1
  440. package/dist/lint/auto-lint.d.ts.map +0 -1
  441. package/dist/lint/auto-lint.js.map +0 -1
  442. package/dist/lint/index.d.ts.map +0 -1
  443. package/dist/lint/index.js.map +0 -1
  444. package/dist/lsp/client.d.ts.map +0 -1
  445. package/dist/lsp/client.js.map +0 -1
  446. package/dist/lsp/diagnostics.d.ts.map +0 -1
  447. package/dist/lsp/diagnostics.js.map +0 -1
  448. package/dist/lsp/index.d.ts.map +0 -1
  449. package/dist/lsp/index.js.map +0 -1
  450. package/dist/mcp/catalog.d.ts.map +0 -1
  451. package/dist/mcp/catalog.js.map +0 -1
  452. package/dist/mcp/index.d.ts.map +0 -1
  453. package/dist/mcp/index.js.map +0 -1
  454. package/dist/mcp/json-schema-to-zod.d.ts.map +0 -1
  455. package/dist/mcp/json-schema-to-zod.js.map +0 -1
  456. package/dist/mcp/manager.d.ts.map +0 -1
  457. package/dist/mcp/manager.js.map +0 -1
  458. package/dist/mcp/marketplace-types.d.ts.map +0 -1
  459. package/dist/mcp/marketplace-types.js.map +0 -1
  460. package/dist/mcp/marketplace.d.ts.map +0 -1
  461. package/dist/mcp/marketplace.js.map +0 -1
  462. package/dist/mcp/mcp-client.d.ts.map +0 -1
  463. package/dist/mcp/mcp-client.js.map +0 -1
  464. package/dist/mcp/mcp-config.d.ts.map +0 -1
  465. package/dist/mcp/mcp-config.js.map +0 -1
  466. package/dist/mcp/registry.d.ts.map +0 -1
  467. package/dist/mcp/registry.js.map +0 -1
  468. package/dist/memory/memory-store.d.ts.map +0 -1
  469. package/dist/memory/memory-store.js.map +0 -1
  470. package/dist/memory/rank.d.ts.map +0 -1
  471. package/dist/memory/rank.js.map +0 -1
  472. package/dist/memory/stale.d.ts.map +0 -1
  473. package/dist/memory/stale.js.map +0 -1
  474. package/dist/model-alias.d.ts.map +0 -1
  475. package/dist/model-alias.js.map +0 -1
  476. package/dist/model-catalog.d.ts.map +0 -1
  477. package/dist/model-catalog.js.map +0 -1
  478. package/dist/model-list.d.ts.map +0 -1
  479. package/dist/model-list.js.map +0 -1
  480. package/dist/orchestrator/board-tools.d.ts.map +0 -1
  481. package/dist/orchestrator/board-tools.js.map +0 -1
  482. package/dist/orchestrator/board.d.ts.map +0 -1
  483. package/dist/orchestrator/board.js.map +0 -1
  484. package/dist/orchestrator/index.d.ts.map +0 -1
  485. package/dist/orchestrator/index.js.map +0 -1
  486. package/dist/orchestrator/orchestrator.d.ts.map +0 -1
  487. package/dist/orchestrator/orchestrator.js.map +0 -1
  488. package/dist/orchestrator/router.d.ts.map +0 -1
  489. package/dist/orchestrator/router.js.map +0 -1
  490. package/dist/orchestrator/specialists-registry.d.ts.map +0 -1
  491. package/dist/orchestrator/specialists-registry.js.map +0 -1
  492. package/dist/orchestrator/specialists.d.ts.map +0 -1
  493. package/dist/orchestrator/specialists.js.map +0 -1
  494. package/dist/orchestrator/types.d.ts.map +0 -1
  495. package/dist/orchestrator/types.js.map +0 -1
  496. package/dist/plugins/index.d.ts.map +0 -1
  497. package/dist/plugins/index.js.map +0 -1
  498. package/dist/plugins/install.d.ts.map +0 -1
  499. package/dist/plugins/install.js.map +0 -1
  500. package/dist/plugins/loader.d.ts.map +0 -1
  501. package/dist/plugins/loader.js.map +0 -1
  502. package/dist/policy/audit.d.ts.map +0 -1
  503. package/dist/policy/audit.js.map +0 -1
  504. package/dist/policy/policy.d.ts.map +0 -1
  505. package/dist/policy/policy.js.map +0 -1
  506. package/dist/policy/proxy.d.ts.map +0 -1
  507. package/dist/policy/proxy.js.map +0 -1
  508. package/dist/pricing.d.ts.map +0 -1
  509. package/dist/pricing.js.map +0 -1
  510. package/dist/providers.d.ts.map +0 -1
  511. package/dist/providers.js.map +0 -1
  512. package/dist/repomap/index.d.ts.map +0 -1
  513. package/dist/repomap/index.js.map +0 -1
  514. package/dist/repomap/repo-map.d.ts.map +0 -1
  515. package/dist/repomap/repo-map.js.map +0 -1
  516. package/dist/semantic/chunker.d.ts.map +0 -1
  517. package/dist/semantic/chunker.js.map +0 -1
  518. package/dist/semantic/embedder.d.ts.map +0 -1
  519. package/dist/semantic/embedder.js.map +0 -1
  520. package/dist/semantic/semantic-index.d.ts.map +0 -1
  521. package/dist/semantic/semantic-index.js.map +0 -1
  522. package/dist/semantic/vector-store.d.ts.map +0 -1
  523. package/dist/semantic/vector-store.js.map +0 -1
  524. package/dist/sessions/index.d.ts.map +0 -1
  525. package/dist/sessions/index.js.map +0 -1
  526. package/dist/sessions/search.d.ts.map +0 -1
  527. package/dist/sessions/search.js.map +0 -1
  528. package/dist/sessions/session-export.d.ts.map +0 -1
  529. package/dist/sessions/session-export.js.map +0 -1
  530. package/dist/sessions/session-store.d.ts.map +0 -1
  531. package/dist/sessions/session-store.js.map +0 -1
  532. package/dist/sessions/watch.d.ts.map +0 -1
  533. package/dist/sessions/watch.js.map +0 -1
  534. package/dist/settings-export.d.ts.map +0 -1
  535. package/dist/settings-export.js.map +0 -1
  536. package/dist/skills/activator.d.ts.map +0 -1
  537. package/dist/skills/activator.js.map +0 -1
  538. package/dist/skills/index.d.ts.map +0 -1
  539. package/dist/skills/index.js.map +0 -1
  540. package/dist/skills/loader.d.ts.map +0 -1
  541. package/dist/skills/loader.js.map +0 -1
  542. package/dist/skills/marketplace-types.d.ts.map +0 -1
  543. package/dist/skills/marketplace-types.js.map +0 -1
  544. package/dist/skills/marketplace.d.ts.map +0 -1
  545. package/dist/skills/marketplace.js.map +0 -1
  546. package/dist/skills/parser.d.ts.map +0 -1
  547. package/dist/skills/parser.js.map +0 -1
  548. package/dist/skills/types.d.ts.map +0 -1
  549. package/dist/skills/types.js.map +0 -1
  550. package/dist/specs/generate.d.ts.map +0 -1
  551. package/dist/specs/generate.js.map +0 -1
  552. package/dist/specs/index.d.ts.map +0 -1
  553. package/dist/specs/index.js.map +0 -1
  554. package/dist/specs/store.d.ts.map +0 -1
  555. package/dist/specs/store.js.map +0 -1
  556. package/dist/specs/sync.d.ts.map +0 -1
  557. package/dist/specs/sync.js.map +0 -1
  558. package/dist/specs/tasks-parser.d.ts.map +0 -1
  559. package/dist/specs/tasks-parser.js.map +0 -1
  560. package/dist/specs/types.d.ts.map +0 -1
  561. package/dist/specs/types.js.map +0 -1
  562. package/dist/steering/glob.d.ts.map +0 -1
  563. package/dist/steering/glob.js.map +0 -1
  564. package/dist/steering/index.d.ts.map +0 -1
  565. package/dist/steering/index.js.map +0 -1
  566. package/dist/steering/loader.d.ts.map +0 -1
  567. package/dist/steering/loader.js.map +0 -1
  568. package/dist/steering/project-instructions.d.ts.map +0 -1
  569. package/dist/steering/project-instructions.js.map +0 -1
  570. package/dist/steering/select.d.ts.map +0 -1
  571. package/dist/steering/select.js.map +0 -1
  572. package/dist/steering/types.d.ts.map +0 -1
  573. package/dist/steering/types.js.map +0 -1
  574. package/dist/structured/index.d.ts.map +0 -1
  575. package/dist/structured/index.js.map +0 -1
  576. package/dist/structured/retry.d.ts.map +0 -1
  577. package/dist/structured/retry.js.map +0 -1
  578. package/dist/structured/schema.d.ts.map +0 -1
  579. package/dist/structured/schema.js.map +0 -1
  580. package/dist/tools/browser-tools.d.ts.map +0 -1
  581. package/dist/tools/browser-tools.js.map +0 -1
  582. package/dist/tools/codebase-search.d.ts.map +0 -1
  583. package/dist/tools/codebase-search.js.map +0 -1
  584. package/dist/tools/command-allow.d.ts.map +0 -1
  585. package/dist/tools/command-allow.js.map +0 -1
  586. package/dist/tools/edit-file.d.ts.map +0 -1
  587. package/dist/tools/edit-file.js.map +0 -1
  588. package/dist/tools/fetch-url.d.ts.map +0 -1
  589. package/dist/tools/fetch-url.js.map +0 -1
  590. package/dist/tools/find-references.d.ts.map +0 -1
  591. package/dist/tools/find-references.js.map +0 -1
  592. package/dist/tools/find-symbol.d.ts.map +0 -1
  593. package/dist/tools/find-symbol.js.map +0 -1
  594. package/dist/tools/ignore-rules.d.ts.map +0 -1
  595. package/dist/tools/ignore-rules.js.map +0 -1
  596. package/dist/tools/index.d.ts.map +0 -1
  597. package/dist/tools/index.js.map +0 -1
  598. package/dist/tools/list-files.d.ts.map +0 -1
  599. package/dist/tools/list-files.js.map +0 -1
  600. package/dist/tools/list-symbols.d.ts.map +0 -1
  601. package/dist/tools/list-symbols.js.map +0 -1
  602. package/dist/tools/memory.d.ts.map +0 -1
  603. package/dist/tools/memory.js.map +0 -1
  604. package/dist/tools/notebook.d.ts.map +0 -1
  605. package/dist/tools/notebook.js.map +0 -1
  606. package/dist/tools/policy.d.ts.map +0 -1
  607. package/dist/tools/policy.js.map +0 -1
  608. package/dist/tools/read-file.d.ts.map +0 -1
  609. package/dist/tools/read-file.js.map +0 -1
  610. package/dist/tools/read-image.d.ts.map +0 -1
  611. package/dist/tools/read-image.js.map +0 -1
  612. package/dist/tools/read-only.d.ts.map +0 -1
  613. package/dist/tools/read-only.js.map +0 -1
  614. package/dist/tools/redact.d.ts.map +0 -1
  615. package/dist/tools/redact.js.map +0 -1
  616. package/dist/tools/result-cache.d.ts.map +0 -1
  617. package/dist/tools/result-cache.js.map +0 -1
  618. package/dist/tools/run-command.d.ts.map +0 -1
  619. package/dist/tools/run-command.js.map +0 -1
  620. package/dist/tools/sandbox-loader.d.ts.map +0 -1
  621. package/dist/tools/sandbox-loader.js.map +0 -1
  622. package/dist/tools/search-files.d.ts.map +0 -1
  623. package/dist/tools/search-files.js.map +0 -1
  624. package/dist/tools/shared.d.ts.map +0 -1
  625. package/dist/tools/shared.js.map +0 -1
  626. package/dist/tools/sub-agent.d.ts.map +0 -1
  627. package/dist/tools/sub-agent.js.map +0 -1
  628. package/dist/tools/web-search.d.ts.map +0 -1
  629. package/dist/tools/web-search.js.map +0 -1
  630. package/dist/tools/write-file.d.ts.map +0 -1
  631. package/dist/tools/write-file.js.map +0 -1
  632. package/dist/types.d.ts.map +0 -1
  633. package/dist/types.js.map +0 -1
  634. package/dist/verify/detect.d.ts.map +0 -1
  635. package/dist/verify/detect.js.map +0 -1
  636. package/dist/verify/index.d.ts.map +0 -1
  637. package/dist/verify/index.js.map +0 -1
  638. package/dist/worktree/branch-ops.d.ts.map +0 -1
  639. package/dist/worktree/branch-ops.js.map +0 -1
  640. package/dist/worktree/index.d.ts.map +0 -1
  641. package/dist/worktree/index.js.map +0 -1
  642. package/dist/worktree/worktree.d.ts.map +0 -1
  643. package/dist/worktree/worktree.js.map +0 -1
package/LICENSE CHANGED
@@ -1,21 +1,44 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 IKarmic
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ IKarmic Forge Core: Proprietary License
2
+
3
+ Copyright (c) 2025-2026 IKarmic. All rights reserved.
4
+
5
+ This license covers "@ikarmic/forge-core" version 5.0.0 and later
6
+ (the "Software"). Earlier versions (4.5.0 and before) were released under
7
+ the MIT License and stay under it.
8
+
9
+ 1. Grant. IKarmic grants you a non-exclusive, non-transferable, royalty-free
10
+ licence to install and run the Software, in the form distributed by
11
+ IKarmic, as a dependency of the IKarmic Forge VS Code extension and the
12
+ IKarmic Forge command line tool (the "Forge Clients"), for any purpose,
13
+ including commercial use.
14
+
15
+ 2. Restrictions. You may not, and may not let others:
16
+ a. copy, modify, translate or create derivative works of the Software;
17
+ b. redistribute, sublicense, sell, lease or host the Software, alone or
18
+ bundled in another product, except as part of an unmodified Forge
19
+ Client distributed by IKarmic;
20
+ c. reverse engineer, decompile or disassemble the Software, except to the
21
+ extent applicable law forbids this restriction;
22
+ d. use the Software to build a product or service that competes with the
23
+ Forge Clients or with IKarmic's paid editions;
24
+ e. remove or alter any copyright, licence or attribution notice.
25
+
26
+ 3. Enterprise features. Features marked as enterprise features need a valid
27
+ licence key from IKarmic. Using them without one is not permitted.
28
+
29
+ 4. Ownership. IKarmic and its licensors keep all rights not granted here.
30
+ No right is granted by implication or estoppel.
31
+
32
+ 5. Open-source Forge Clients. The Forge Clients' own source code is licensed
33
+ separately under AGPL-3.0-only (see the LICENSE and NOTICE files of the
34
+ Forge Clients). That licence does not extend to this Software, and
35
+ nothing in it lets you redistribute this Software.
36
+
37
+ 6. No warranty. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
38
+ KIND. IKARMIC IS NOT LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
39
+ ARISING FROM THE SOFTWARE OR ITS USE, TO THE EXTENT THE LAW ALLOWS.
40
+
41
+ 7. Termination. This licence ends automatically if you break it. On
42
+ termination you must stop using and delete all copies of the Software.
43
+
44
+ Contact: ikarmicaiss@gmail.com
package/README.md CHANGED
@@ -154,4 +154,4 @@ MCP tools appear in the agent's prompt with fully-qualified names like `mcp__fil
154
154
 
155
155
  ## License
156
156
 
157
- MIT
157
+ Proprietary, free to run with the Forge extension and CLI. See [LICENSE](LICENSE). Versions 4.5.0 and earlier stay MIT.
@@ -15,6 +15,8 @@ export declare class Agent {
15
15
  private readonly checkpoints;
16
16
  private readonly browser;
17
17
  private readonly audit;
18
+ private readonly permissionRules;
19
+ private todoList;
18
20
  constructor(config: AgentConfig);
19
21
  /** Files whose modification should trigger a pre-tool checkpoint. */
20
22
  private get captureBeforeTools();
@@ -42,6 +44,12 @@ export declare class Agent {
42
44
  * we never want to "skip".
43
45
  */
44
46
  private wrapToolsWithCache;
47
+ /**
48
+ * What the permission rules say about one tool call: `allow` (every target allowed), `deny` (any target denied,
49
+ * with the reason the model sees), `ask` (a target asks, a `.env` file is read, or a command leaves the workspace),
50
+ * or undefined when no rule applies and the normal approval flow decides.
51
+ */
52
+ private decidePermission;
45
53
  private requestApproval;
46
54
  /**
47
55
  * Build the default LLM-based summarizer for compaction. Picks the
@@ -58,4 +66,3 @@ export declare class Agent {
58
66
  * we don't want to fail just because the user typed a stale name.
59
67
  */
60
68
  export declare function applySandbox(tools: ToolDefinition[], sandbox: ToolSandbox | undefined): ToolDefinition[];
61
- //# sourceMappingURL=agent.d.ts.map
@@ -1,6 +1,8 @@
1
1
  import { streamText } from 'ai';
2
2
  import { lintFile, lintMessage } from '../lint/auto-lint.js';
3
3
  import { buildMemoryBlock } from '../memory/memory-store.js';
4
+ import { filesTouchedBy } from '../tools/write-tools.js';
5
+ import { buildExtraInstructionsBlock } from '../steering/extra-instructions.js';
4
6
  import { buildProjectInstructionsBlock } from '../steering/project-instructions.js';
5
7
  import { buildRepoMap, repoMapBlock } from '../repomap/repo-map.js';
6
8
  import { buildLlmSummarizer, compactMessages, effectiveLimitTokens, getModelWindowTokens, shouldCompactForBudget } from '../context/compaction.js';
@@ -15,7 +17,9 @@ import { createGitHubTools, githubFromEnv } from '../github/github-tools.js';
15
17
  import { createWebSearchTool, webSearchFromEnv } from '../tools/web-search.js';
16
18
  import { embedderFromEnv } from '../semantic/embedder.js';
17
19
  import { DEFAULT_VERIFY_RETRIES, failureMessage, runVerification } from './verify.js';
20
+ import { LoopGuard, resultKeyOf } from './loop-guard.js';
18
21
  import { isListedCommand } from '../tools/command-allow.js';
22
+ import { compilePermissionRules, evaluatePermission, isSensitiveFile, permissionFor, touchesOutsideCwd, } from '../tools/permission-rules.js';
19
23
  import { createLanguageModel } from '../providers.js';
20
24
  import { BUILTIN_TOOLS } from '../tools/index.js';
21
25
  import { ToolResultCache, cachedExecute } from '../tools/result-cache.js';
@@ -31,9 +35,9 @@ const DEFAULT_MAX_CONTINUATIONS = 3;
31
35
  export const DEFAULT_MAX_DURATION_MS = 10 * 60 * 1000;
32
36
  const REDACTABLE_TOOLS = new Set(['read_file', 'search_files', 'list_files']);
33
37
  /** Tools whose successful `path` argument can trigger mid-run fileMatch steering. */
34
- const STEERING_FILE_TOOLS = new Set(['read_file', 'write_file', 'edit_file', 'edit_notebook']);
38
+ const STEERING_FILE_TOOLS = new Set(['read_file', 'write_file', 'edit_file', 'edit_notebook', 'apply_patch']);
35
39
  /** Tools that change a file, so auto-lint checks their `path` afterwards. */
36
- const FILE_WRITE_TOOLS = new Set(['write_file', 'edit_file', 'edit_notebook']);
40
+ const FILE_WRITE_TOOLS = new Set(['write_file', 'edit_file', 'edit_notebook', 'apply_patch']);
37
41
  /** Pure reads whose results may be reused within a run. Every other tool invalidates the cache. */
38
42
  const CACHEABLE_TOOLS = new Set(['read_file', 'read_image', 'list_files', 'search_files', 'find_symbol', 'list_symbols', 'find_references', 'codebase_search', 'memory_read', 'fetch_url', 'web_search']);
39
43
  /**
@@ -51,12 +55,16 @@ export class Agent {
51
55
  checkpoints;
52
56
  browser;
53
57
  audit;
58
+ permissionRules;
59
+ todoList = [];
54
60
  constructor(config) {
55
61
  // Organization policy first: everything below sees the already-tightened config.
56
62
  const policy = config.policy === undefined ? getOrgPolicy()?.policy : (config.policy ?? undefined);
57
63
  config = applyPolicy(config, policy);
58
64
  this.audit = config.audit ?? (policy?.audit?.enabled ? createFileAuditSink(policy.audit.file) : undefined);
59
65
  this.config = config;
66
+ this.permissionRules = compilePermissionRules(config.permissionRules);
67
+ this.todoList = config.initialTodos ? [...config.initialTodos] : [];
60
68
  const allTools = (config.disableBuiltins
61
69
  ? [...(config.extraTools ?? [])]
62
70
  : [...BUILTIN_TOOLS, ...(config.extraTools ?? [])]);
@@ -71,12 +79,19 @@ export class Agent {
71
79
  if (webSearch)
72
80
  allTools.push(createWebSearchTool(webSearch));
73
81
  if (config.semanticSearch) {
74
- allTools.push(createCodebaseSearchTool(config.semanticSearch.embedder ?? embedderFromEnv()));
82
+ allTools.push(createCodebaseSearchTool(config.semanticSearch.embedder ?? embedderFromEnv(), {
83
+ ...(config.semanticSearch.extensions ? { extensions: config.semanticSearch.extensions } : {}),
84
+ ...(config.semanticSearch.minScore !== undefined ? { minScore: config.semanticSearch.minScore } : {}),
85
+ ...(config.semanticSearch.defaultLimit ? { defaultLimit: config.semanticSearch.defaultLimit } : {}),
86
+ }));
75
87
  }
76
88
  const memoryFiltered = config.disableMemory
77
89
  ? allTools.filter((t) => t.name !== 'memory_read' && t.name !== 'memory_write' && t.name !== 'memory_forget')
78
90
  : allTools;
79
- const sandboxedTools = applySandbox(memoryFiltered, config.toolSandbox);
91
+ // `ask_user` is offered only when a surface can answer and the run is not autonomous.
92
+ const canAsk = Boolean(config.askUser) && !config.auto && !config.disableAskUser;
93
+ const askFiltered = canAsk ? memoryFiltered : memoryFiltered.filter((t) => t.name !== 'ask_user');
94
+ const sandboxedTools = applySandbox(askFiltered, config.toolSandbox);
80
95
  this.tools = this.wrapToolsWithCache(sandboxedTools, config.cacheSize, config.cacheTtlMs, config.disableCache);
81
96
  this.cache = new ToolResultCache({
82
97
  maxSize: config.disableCache ? 0 : (config.cacheSize ?? 256),
@@ -95,7 +110,7 @@ export class Agent {
95
110
  const cfg = this.checkpoints?.captureBeforeTools;
96
111
  if (!cfg) {
97
112
  // Default: file-mutating tools + run_command (which can mutate via shell).
98
- return new Set(['write_file', 'edit_file', 'edit_notebook', 'run_command']);
113
+ return new Set(['write_file', 'edit_file', 'edit_notebook', 'apply_patch', 'run_command']);
99
114
  }
100
115
  return new Set(cfg);
101
116
  }
@@ -216,6 +231,14 @@ export class Agent {
216
231
  let model = modelFactory(currentModelConfig);
217
232
  let stepPricing = this.pricing;
218
233
  let lastToolNames = [];
234
+ // Stops a run that repeats one identical tool call (off unless `loopGuardThreshold` is set).
235
+ const loopGuard = new LoopGuard(this.config.loopGuardThreshold ?? 0);
236
+ let loopTripped;
237
+ // Every call outcome feeds the guard (results, errors, invalid or denied calls), so a different call in between resets the streak.
238
+ const trackLoop = (tool, args, outcome) => {
239
+ if (loopGuard.record(tool, args, resultKeyOf(outcome)) && !loopTripped)
240
+ loopTripped = { tool, count: loopGuard.streak };
241
+ };
219
242
  // Verify loop state: only run checks when the run actually edited files.
220
243
  let editedSinceVerify = false;
221
244
  const editedFiles = new Set();
@@ -226,12 +249,29 @@ export class Agent {
226
249
  let verification;
227
250
  // Infinite output: text of a reply that hit the output limit and is being continued.
228
251
  let continuedText = '';
252
+ // The answer text of the step now streaming, kept so a Stop does not throw away what was already said.
253
+ let partialStepText = '';
229
254
  let continuations = 0;
230
255
  const maxContinuations = this.config.maxContinuations ?? DEFAULT_MAX_CONTINUATIONS;
231
256
  const ctx = {
232
257
  cwd: this.config.cwd ?? process.cwd(),
233
258
  auto: this.config.auto ?? false,
234
259
  parentModel: this.config.model,
260
+ ...(this.config.subAgentModel ? { subAgentModel: this.config.subAgentModel } : {}),
261
+ ...(this.config.backgroundAgents ? { background: this.config.backgroundAgents } : {}),
262
+ ...(this.config.autoApproveTools ? { autoApproveTools: this.config.autoApproveTools } : {}),
263
+ ...(this.config.permissionRules ? { permissionRules: this.config.permissionRules } : {}),
264
+ ...(this.config.toolSandbox ? { toolSandbox: this.config.toolSandbox } : {}),
265
+ shownFolderInstructions: new Set(),
266
+ ...(this.config.maxToolOutputChars ? { maxOutputChars: this.config.maxToolOutputChars } : {}),
267
+ ...(this.config.askUser ? { askUser: this.config.askUser } : {}),
268
+ todos: {
269
+ get: () => this.todoList,
270
+ set: (todos) => {
271
+ this.todoList = todos;
272
+ emit({ type: 'todo_updated', todos });
273
+ },
274
+ },
235
275
  ...(this.config.commandRunner ? { commandRunner: this.config.commandRunner } : {}),
236
276
  ...(abortSignal ? { abortSignal } : {}),
237
277
  ...(this.config.memoryMaxBodyChars !== undefined ? { memoryMaxBodyChars: this.config.memoryMaxBodyChars } : {}),
@@ -280,13 +320,16 @@ export class Agent {
280
320
  // Track per-turn token deltas so we can compute per-turn cost.
281
321
  const turnStart = { input: inputTokens, output: outputTokens, cacheRead: cacheReadTokens, cacheWrite: cacheWriteTokens };
282
322
  let reasoningText = '';
323
+ partialStepText = '';
283
324
  // Inline <think> blocks (MiniMax over OpenAI-compatible, some open models) become reasoning events.
284
325
  const thinkSplitter = new ThinkSplitter();
285
326
  let wasInThink = false;
286
327
  const emitSegments = (segments) => {
287
328
  for (const seg of segments) {
288
- if (seg.kind === 'text')
329
+ if (seg.kind === 'text') {
330
+ partialStepText += seg.text;
289
331
  emit({ type: 'text_delta', text: seg.text });
332
+ }
290
333
  else {
291
334
  reasoningText += seg.text;
292
335
  emit({ type: 'reasoning_delta', text: seg.text });
@@ -320,6 +363,7 @@ export class Agent {
320
363
  tools: toAiSdkTools(this.tools),
321
364
  abortSignal,
322
365
  ...(this.config.model.reasoningEffort ? { reasoning: this.config.model.reasoningEffort } : {}),
366
+ ...(this.config.model.temperature !== undefined ? { temperature: this.config.model.temperature } : {}),
323
367
  onChunk: ({ chunk }) => {
324
368
  if (chunk.type === 'text-delta') {
325
369
  emitSegments(thinkSplitter.push(chunk.text));
@@ -342,6 +386,7 @@ export class Agent {
342
386
  },
343
387
  onFinish: ({ text: rawText, usage }) => {
344
388
  emitSegments(thinkSplitter.flush());
389
+ partialStepText = '';
345
390
  if (reasoningText) {
346
391
  emit({ type: 'reasoning_done', text: reasoningText });
347
392
  reasoningText = '';
@@ -483,11 +528,13 @@ export class Agent {
483
528
  if (!def) {
484
529
  currentToolResults.push(toolResultError(call.toolCallId, call.toolName, `Unknown tool: ${call.toolName}`));
485
530
  emit({ type: 'tool_result', name: call.toolName, id: call.toolCallId, result: `Unknown tool`, isError: true });
531
+ trackLoop(call.toolName, call.input, 'unknown tool');
486
532
  continue;
487
533
  }
488
534
  const argsParsed = def.parameters.safeParse(call.input);
489
535
  if (!argsParsed.success) {
490
536
  const message = `Invalid arguments for ${call.toolName}: ${argsParsed.error.message}`;
537
+ trackLoop(call.toolName, call.input, message);
491
538
  currentToolResults.push(toolResultError(call.toolCallId, call.toolName, message));
492
539
  emit({ type: 'tool_result', name: call.toolName, id: call.toolCallId, result: message, isError: true });
493
540
  continue;
@@ -496,6 +543,7 @@ export class Agent {
496
543
  this.audit?.record({ event: 'tool_call', tool: call.toolName, args: approval.args ?? argsParsed.data, approved: approval.approved, auto: this.config.auto === true }, auditCtx);
497
544
  if (!approval.approved) {
498
545
  const denial = approval.note ? `Denied by user. ${approval.note}` : `Denied by user.`;
546
+ trackLoop(call.toolName, argsParsed.data, denial);
499
547
  currentToolResults.push(toolResult(call.toolCallId, call.toolName, denial));
500
548
  emit({ type: 'tool_result', name: call.toolName, id: call.toolCallId, result: denial, isError: false });
501
549
  continue;
@@ -507,6 +555,7 @@ export class Agent {
507
555
  const edited = def.parameters.safeParse(approval.args);
508
556
  if (!edited.success) {
509
557
  const message = `Invalid edited arguments for ${call.toolName}: ${edited.error.message}`;
558
+ trackLoop(call.toolName, approval.args, message);
510
559
  currentToolResults.push(toolResultError(call.toolCallId, call.toolName, message));
511
560
  emit({ type: 'tool_result', name: call.toolName, id: call.toolCallId, result: message, isError: true });
512
561
  continue;
@@ -564,12 +613,16 @@ export class Agent {
564
613
  this.audit?.record({ event: 'tool_result', tool: call.toolName, isError: false, durationMs: Date.now() - toolStartedAt }, auditCtx);
565
614
  if (FILE_WRITE_TOOLS.has(call.toolName))
566
615
  editedSinceVerify = true;
567
- const editedPath = toolArgs.path;
568
- if (FILE_WRITE_TOOLS.has(call.toolName) && typeof editedPath === 'string')
569
- editedFiles.add(editedPath);
570
- if (this.config.autoLint && FILE_WRITE_TOOLS.has(call.toolName) && typeof editedPath === 'string') {
571
- const report = await lintFile(editedPath, this.config.autoLint, { ...ctx, policy: undefined }).catch(() => null);
572
- if (report) {
616
+ // Every file the call worked on: a patch can change several (RB-13).
617
+ const touchedFiles = filesTouchedBy(call.toolName, toolArgs);
618
+ if (FILE_WRITE_TOOLS.has(call.toolName))
619
+ for (const p of touchedFiles)
620
+ editedFiles.add(p);
621
+ if (this.config.autoLint && FILE_WRITE_TOOLS.has(call.toolName)) {
622
+ for (const editedPath of touchedFiles) {
623
+ const report = await lintFile(editedPath, this.config.autoLint, { ...ctx, policy: undefined }).catch(() => null);
624
+ if (!report)
625
+ continue;
573
626
  emit({ type: 'lint', path: report.path, passed: report.passed, problems: report.problems.length });
574
627
  if (!report.passed) {
575
628
  const note = lintMessage(report);
@@ -586,11 +639,9 @@ export class Agent {
586
639
  : { result: finalResult, userNote: approval.note };
587
640
  }
588
641
  currentToolResults.push(toolResult(call.toolCallId, call.toolName, finalResult));
589
- if (STEERING_FILE_TOOLS.has(call.toolName)) {
590
- const touched = toolArgs.path;
591
- if (typeof touched === 'string')
592
- touchedPaths.push(touched);
593
- }
642
+ trackLoop(call.toolName, toolArgs, finalResult);
643
+ if (STEERING_FILE_TOOLS.has(call.toolName))
644
+ touchedPaths.push(...filesTouchedBy(call.toolName, toolArgs));
594
645
  emit({
595
646
  type: 'tool_result',
596
647
  name: call.toolName,
@@ -617,6 +668,7 @@ export class Agent {
617
668
  const message = errorMessageOf(err);
618
669
  currentToolResults.push(toolResultError(call.toolCallId, call.toolName, message));
619
670
  emit({ type: 'tool_result', name: call.toolName, id: call.toolCallId, result: message, isError: true });
671
+ trackLoop(call.toolName, toolArgs, `error:${message}`);
620
672
  if (this.hooks) {
621
673
  await this.hooks.dispatch({
622
674
  type: 'PostToolUse',
@@ -636,6 +688,11 @@ export class Agent {
636
688
  }
637
689
  for (const m of toolResultMessages)
638
690
  messages.push(m);
691
+ if (loopTripped) {
692
+ emit({ type: 'loop_detected', tool: loopTripped.tool, count: loopTripped.count });
693
+ reason = 'loop_detected';
694
+ break;
695
+ }
639
696
  // Mid-run fileMatch steering: one extra user message per round, each doc once per run.
640
697
  if (steeringDocs.length > 0 && touchedPaths.length > 0) {
641
698
  const injected = [];
@@ -760,6 +817,14 @@ export class Agent {
760
817
  const lastMessage = messages[messages.length - 1];
761
818
  if (continuedText !== '' && lastMessage?.role === 'user' && lastMessage.content === CONTINUE_PROMPT)
762
819
  messages.pop();
820
+ // Stopped mid-answer: keep the part the user already saw, marked as cut short, so "continue" can pick it up
821
+ // instead of starting over. Only when the model is the next speaker (after the user or a tool result).
822
+ if (reason === 'aborted' && partialStepText.trim()) {
823
+ const last = messages[messages.length - 1];
824
+ if (last && (last.role === 'user' || last.role === 'tool')) {
825
+ messages.push({ role: 'assistant', content: `${partialStepText.trim()}\n\n[Stopped by the user before finishing.]` });
826
+ }
827
+ }
763
828
  // The browser is per-run: never leave a Chrome process behind.
764
829
  await this.browser?.close().catch(() => undefined);
765
830
  emit({ type: 'done', reason });
@@ -863,21 +928,68 @@ export class Agent {
863
928
  return { ...t, execute: invalidating };
864
929
  });
865
930
  }
931
+ /**
932
+ * What the permission rules say about one tool call: `allow` (every target allowed), `deny` (any target denied,
933
+ * with the reason the model sees), `ask` (a target asks, a `.env` file is read, or a command leaves the workspace),
934
+ * or undefined when no rule applies and the normal approval flow decides.
935
+ */
936
+ decidePermission(toolName, args, cwd) {
937
+ const p = permissionFor(toolName, args, cwd);
938
+ if (!p || p.targets.length === 0)
939
+ return undefined;
940
+ const rules = this.permissionRules;
941
+ const explicit = rules.filter((r) => r.pattern !== '*' && r.pattern !== '**');
942
+ const actions = p.targets.map((t) => {
943
+ // A broad rule never covers a secrets file: only a rule that names it can allow it.
944
+ // Headless runs (no approve callback) have nobody to ask, so they keep reading as before.
945
+ if (p.permission === 'read' && isSensitiveFile(t))
946
+ return evaluatePermission(explicit, 'read', t) ?? (this.config.approve ? 'ask' : evaluatePermission(rules, 'read', t));
947
+ return evaluatePermission(rules, p.permission, t);
948
+ });
949
+ if (p.permission === 'bash') {
950
+ const command = args.command;
951
+ if (typeof command === 'string' && touchesOutsideCwd(command, cwd)) {
952
+ const external = evaluatePermission(rules, 'external_directory', command);
953
+ if (external === 'deny')
954
+ return { action: 'deny', reason: `Blocked by permission rule (external_directory ${command}).` };
955
+ if (external !== 'allow' && this.config.approve)
956
+ actions.push('ask');
957
+ }
958
+ }
959
+ const denied = actions.indexOf('deny');
960
+ if (denied >= 0)
961
+ return { action: 'deny', reason: `Blocked by permission rule (${p.permission} ${p.targets[denied]}).` };
962
+ if (actions.includes('ask'))
963
+ return { action: 'ask', reason: '' };
964
+ if (actions.every((a) => a === 'allow'))
965
+ return { action: 'allow', reason: '' };
966
+ return undefined;
967
+ }
866
968
  async requestApproval(def, id, args, abortSignal, ctx) {
969
+ // Bookkeeping tools (the todo list) never ask.
970
+ if (def.noApproval)
971
+ return { approved: true };
972
+ // Permission rules come first: deny blocks, allow runs, ask skips every shortcut below.
973
+ const rule = this.decidePermission(def.name, args, ctx?.cwd ?? this.config.cwd ?? process.cwd());
974
+ if (rule?.action === 'deny')
975
+ return { approved: false, note: rule.reason };
976
+ if (rule?.action === 'allow')
977
+ return { approved: true };
978
+ const forceAsk = rule?.action === 'ask';
867
979
  // Read-only tools the user chose not to be asked about (never a destructive one).
868
- if (!def.destructive && this.config.autoApproveTools?.includes(def.name)) {
980
+ if (!forceAsk && !def.destructive && this.config.autoApproveTools?.includes(def.name)) {
869
981
  return { approved: true };
870
982
  }
871
983
  // Memory writes the user chose not to be asked about. memory_forget is deleted data: always asked.
872
- if (def.name === 'memory_write' && this.config.memoryAutoApproveWrites) {
984
+ if (!forceAsk && def.name === 'memory_write' && this.config.memoryAutoApproveWrites) {
873
985
  return { approved: true };
874
986
  }
875
987
  // A plain command the user already said "always allow" for: exact match only (see command-allow.ts).
876
- if (def.name === 'run_command' && this.config.autoApproveCommands?.length && isListedCommand(args, this.config.autoApproveCommands)) {
988
+ if (!forceAsk && def.name === 'run_command' && this.config.autoApproveCommands?.length && isListedCommand(args, this.config.autoApproveCommands)) {
877
989
  return { approved: true };
878
990
  }
879
991
  const auto = this.config.auto ?? false;
880
- if (auto && !(def.destructive && !this.config.allowDestructive)) {
992
+ if (!forceAsk && auto && !(def.destructive && !this.config.allowDestructive)) {
881
993
  return { approved: true };
882
994
  }
883
995
  let preview;
@@ -1073,6 +1185,15 @@ async function buildInitialMessages(config, task, skills, steeringSystem = [], u
1073
1185
  // Unreadable instruction files are skipped, never fatal.
1074
1186
  }
1075
1187
  }
1188
+ let extraInstructionsBlock = '';
1189
+ if (config.extraInstructions?.length) {
1190
+ try {
1191
+ extraInstructionsBlock = await buildExtraInstructionsBlock(cwd, config.extraInstructions);
1192
+ }
1193
+ catch {
1194
+ // Skipped, never fatal.
1195
+ }
1196
+ }
1076
1197
  let mapBlock = '';
1077
1198
  if (config.repoMap) {
1078
1199
  try {
@@ -1085,7 +1206,7 @@ async function buildInitialMessages(config, task, skills, steeringSystem = [], u
1085
1206
  // Compose the final system prompt: base + (memory, skills) blocks in a
1086
1207
  // stable order so cache hits survive across runs that share state.
1087
1208
  const steeringBlock = steeringSystem.map(wrapSteering).join('\n\n');
1088
- const blocks = [steeringBlock, instructionsBlock, config.projectCommands ?? '', memoryBlock, skillsBlock, mapBlock].filter((b) => b.length > 0);
1209
+ const blocks = [steeringBlock, instructionsBlock, extraInstructionsBlock, config.mcpInstructions ?? '', config.projectCommands ?? '', memoryBlock, skillsBlock, mapBlock].filter((b) => b.length > 0);
1089
1210
  const systemContent = blocks.length > 0 ? `${basePrompt}\n\n${blocks.join('\n\n')}` : basePrompt;
1090
1211
  return [
1091
1212
  { role: 'system', content: systemContent },
@@ -1119,4 +1240,3 @@ function estimateNextPromptTokens(messages) {
1119
1240
  }
1120
1241
  return total;
1121
1242
  }
1122
- //# sourceMappingURL=agent.js.map
@@ -45,4 +45,3 @@ export declare function editorLimits(base: AgentConfig, architect: {
45
45
  };
46
46
  export declare function editorTask(task: string, plan: string): string;
47
47
  export declare function runArchitect(opts: ArchitectOptions): Promise<AgentRunResult>;
48
- //# sourceMappingURL=architect.d.ts.map
@@ -91,4 +91,3 @@ export async function runArchitect(opts) {
91
91
  costKnown: architect.costKnown && editor.costKnown,
92
92
  };
93
93
  }
94
- //# sourceMappingURL=architect.js.map
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Sub-agents that keep working after `sub_agent` has returned. The chat owns one registry per conversation: the
3
+ * model starts a run with `sub_agent { background: true }` and gets an id back at once; it collects the answer with
4
+ * `sub_agent_wait`, or the chat hands it every finished answer it has not seen with the next message. The person sees
5
+ * the runs in a strip above the message box and can stop one, stop all, or dismiss a finished one.
6
+ */
7
+ import type { SubAgentResult } from '../tools/sub-agent.js';
8
+ export type BackgroundState = 'running' | 'done' | 'failed' | 'stopped';
9
+ export interface BackgroundAgent {
10
+ id: string;
11
+ task: string;
12
+ /** The agent file it runs as, when it was started with one. */
13
+ agent?: string;
14
+ state: BackgroundState;
15
+ startedAt: number;
16
+ endedAt?: number;
17
+ result?: SubAgentResult;
18
+ error?: string;
19
+ }
20
+ /** More than this at once costs more than anyone meant to spend. */
21
+ export declare const MAX_RUNNING_BACKGROUND = 4;
22
+ export interface StartOptions {
23
+ task: string;
24
+ agent?: string | undefined;
25
+ /** Runs the work; must finish soon after `signal` aborts. */
26
+ run: (signal: AbortSignal) => Promise<SubAgentResult>;
27
+ }
28
+ export declare class BackgroundAgents {
29
+ private readonly entries;
30
+ private readonly listeners;
31
+ private counter;
32
+ start(options: StartOptions): BackgroundAgent;
33
+ list(): BackgroundAgent[];
34
+ get(id: string): BackgroundAgent | undefined;
35
+ stop(id: string): void;
36
+ stopAll(): void;
37
+ /** Stop everything and forget it all (a new chat starts with none). */
38
+ clear(): void;
39
+ /** Remove a finished entry from the list. A running one must be stopped first. */
40
+ dismiss(id: string): boolean;
41
+ /**
42
+ * Wait until the named runs (default: all that are running) have finished, or the timeout passes. Never throws:
43
+ * the answer is the current state of each run.
44
+ */
45
+ wait(ids?: readonly string[], options?: {
46
+ timeoutMs?: number;
47
+ signal?: AbortSignal;
48
+ }): Promise<BackgroundAgent[]>;
49
+ /** Finished runs the model has not been told about yet; each is returned once. */
50
+ takeUndelivered(): BackgroundAgent[];
51
+ /** Mark runs as already known to the model (a `sub_agent_wait` answered for them). */
52
+ markDelivered(ids: readonly string[]): void;
53
+ onChange(listener: () => void): () => void;
54
+ private changed;
55
+ private view;
56
+ }
57
+ /** The model-facing text for finished runs: what each was asked and what it answered. */
58
+ export declare function backgroundResultsBlock(finished: readonly BackgroundAgent[]): string;