@gajae-code/coding-agent 0.14.2 → 0.15.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 (345) hide show
  1. package/CHANGELOG.md +120 -1
  2. package/dist/types/async/job-manager.d.ts +4 -1
  3. package/dist/types/autoresearch/dashboard.d.ts +29 -4
  4. package/dist/types/autoresearch/data-context.d.ts +25 -0
  5. package/dist/types/autoresearch/git.d.ts +65 -7
  6. package/dist/types/autoresearch/harness.d.ts +58 -0
  7. package/dist/types/autoresearch/prompts.d.ts +51 -0
  8. package/dist/types/autoresearch/runs.d.ts +173 -0
  9. package/dist/types/autoresearch/types.d.ts +9 -139
  10. package/dist/types/capability/types.d.ts +20 -0
  11. package/dist/types/cli/accounts-cli.d.ts +1 -0
  12. package/dist/types/commands/{rlm.d.ts → autoresearch.d.ts} +2 -4
  13. package/dist/types/config/autorouting-contract.d.ts +146 -0
  14. package/dist/types/config/autorouting-generator.d.ts +40 -0
  15. package/dist/types/config/autorouting-tier-map.d.ts +16844 -0
  16. package/dist/types/config/autorouting.d.ts +35 -0
  17. package/dist/types/config/model-discovery-manager.d.ts +8 -1
  18. package/dist/types/config/model-registry.d.ts +30 -1
  19. package/dist/types/config/provider-selection-policy.d.ts +23 -0
  20. package/dist/types/config/settings-schema.d.ts +61 -3
  21. package/dist/types/config/settings.d.ts +3 -0
  22. package/dist/types/coordinator/contract.d.ts +1 -1
  23. package/dist/types/coordinator-mcp/durability.d.ts +29 -0
  24. package/dist/types/coordinator-mcp/event-webhook.d.ts +50 -0
  25. package/dist/types/coordinator-mcp/question-state.d.ts +1 -1
  26. package/dist/types/coordinator-mcp/server.d.ts +14 -0
  27. package/dist/types/crash/index-store.d.ts +3 -0
  28. package/dist/types/crash/record-loader.d.ts +2 -0
  29. package/dist/types/crash/upstream/relay.d.ts +5 -3
  30. package/dist/types/cursor.d.ts +12 -0
  31. package/dist/types/defaults/gjc-defaults.d.ts +35 -1
  32. package/dist/types/defaults/gjc-skills.generated.d.ts +1 -1
  33. package/dist/types/discovery/helpers.d.ts +1 -1
  34. package/dist/types/edit/index.d.ts +2 -1
  35. package/dist/types/eval/py/executor.d.ts +2 -0
  36. package/dist/types/extensibility/extensions/loader.d.ts +32 -0
  37. package/dist/types/extensibility/gjc-plugins/types.d.ts +1 -1
  38. package/dist/types/extensibility/skills.d.ts +2 -0
  39. package/dist/types/gjc-runtime/autoresearch-runtime.d.ts +194 -0
  40. package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
  41. package/dist/types/gjc-runtime/psmux-detect.d.ts +1 -1
  42. package/dist/types/gjc-runtime/python-transcript.d.ts +19 -0
  43. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +2 -8
  44. package/dist/types/gjc-runtime/session-layout.d.ts +6 -3
  45. package/dist/types/gjc-runtime/state-renderer.d.ts +0 -22
  46. package/dist/types/gjc-runtime/state-schema.d.ts +7 -7
  47. package/dist/types/gjc-runtime/tmux-common.d.ts +2 -2
  48. package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +38 -1
  49. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +2 -24
  50. package/dist/types/gjc-runtime/ultragoal-validation-policy.d.ts +73 -0
  51. package/dist/types/gjc-runtime/workflow-recovery-projection.d.ts +100 -0
  52. package/dist/types/hooks/skill-keywords.d.ts +1 -1
  53. package/dist/types/main.d.ts +0 -10
  54. package/dist/types/modes/acp/acp-agent.d.ts +13 -6
  55. package/dist/types/modes/components/model-selector.d.ts +14 -0
  56. package/dist/types/modes/components/skill-hud/render.d.ts +6 -1
  57. package/dist/types/modes/components/smart-routing-panel.d.ts +82 -0
  58. package/dist/types/modes/controllers/selector-controller.d.ts +14 -0
  59. package/dist/types/modes/interactive-mode.d.ts +3 -0
  60. package/dist/types/modes/types.d.ts +9 -0
  61. package/dist/types/rlm/artifacts.d.ts +4 -4
  62. package/dist/types/runtime/optional-runtime-services.d.ts +2 -1
  63. package/dist/types/runtime/workspace-tree-service.d.ts +5 -1
  64. package/dist/types/runtime-mcp/config.d.ts +6 -0
  65. package/dist/types/runtime-mcp/manager.d.ts +10 -0
  66. package/dist/types/sdk/acp/adapter.d.ts +0 -4
  67. package/dist/types/sdk/broker/broker.d.ts +1 -1
  68. package/dist/types/sdk/broker/lifecycle.d.ts +57 -2
  69. package/dist/types/sdk/broker/session-index.d.ts +15 -0
  70. package/dist/types/sdk/bus/chat-daemon-control.d.ts +6 -0
  71. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -0
  72. package/dist/types/sdk/bus/index.d.ts +8 -0
  73. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +2 -0
  74. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -2
  75. package/dist/types/sdk/client/client.d.ts +39 -4
  76. package/dist/types/sdk/host/host.d.ts +1 -0
  77. package/dist/types/sdk/host/internal-autorouting-state.d.ts +3 -0
  78. package/dist/types/sdk/host/model-pin.d.ts +29 -0
  79. package/dist/types/sdk/host/session-runtime.d.ts +2 -1
  80. package/dist/types/sdk/lifecycle-session.d.ts +13 -0
  81. package/dist/types/sdk/router/session-router.d.ts +27 -1
  82. package/dist/types/sdk/session.d.ts +11 -1
  83. package/dist/types/session/agent-session.d.ts +36 -6
  84. package/dist/types/session/artifacts.d.ts +16 -1
  85. package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
  86. package/dist/types/session/session-manager.d.ts +84 -2
  87. package/dist/types/session/session-staging-paths.d.ts +3 -0
  88. package/dist/types/skill-state/canonical-skills.d.ts +1 -1
  89. package/dist/types/skill-state/workflow-hud.d.ts +12 -21
  90. package/dist/types/skill-state/workflow-mutation-guard.d.ts +1 -0
  91. package/dist/types/slash-commands/helpers/autorouting-status.d.ts +8 -0
  92. package/dist/types/system-prompt.d.ts +23 -0
  93. package/dist/types/task/executor.d.ts +35 -4
  94. package/dist/types/task/index.d.ts +17 -3
  95. package/dist/types/task/receipt.d.ts +3 -1
  96. package/dist/types/task/types.d.ts +144 -0
  97. package/dist/types/tools/atomic-file-write.d.ts +72 -0
  98. package/dist/types/tools/descriptors.d.ts +1 -0
  99. package/dist/types/tools/index.d.ts +36 -1
  100. package/dist/types/tools/move-session.d.ts +40 -0
  101. package/dist/types/tools/python.d.ts +12 -0
  102. package/dist/types/tools/resource-gc.d.ts +0 -3
  103. package/dist/types/tools/search.d.ts +8 -1
  104. package/dist/types/tools/skill.d.ts +9 -4
  105. package/dist/types/tools/subagent.d.ts +33 -3
  106. package/dist/types/utils/xml-escape.d.ts +2 -0
  107. package/dist/types/workflow/workflow-intent-diff.d.ts +2 -2
  108. package/dist/types/workflow/workflow-intent-report-consumer.d.ts +1 -1
  109. package/package.json +11 -12
  110. package/scripts/build-sdk-package-smoke.ts +7 -5
  111. package/scripts/check-autorouting-tier-map.ts +183 -0
  112. package/scripts/generate-sdk-operation-inventory.ts +12 -0
  113. package/scripts/generate-tool-catalog.ts +40 -5
  114. package/src/async/job-manager.ts +5 -2
  115. package/src/autoresearch/dashboard.ts +134 -314
  116. package/src/autoresearch/data-context.ts +35 -0
  117. package/src/autoresearch/git.ts +186 -26
  118. package/src/autoresearch/{helpers.ts → harness.ts} +65 -40
  119. package/src/autoresearch/{prompt-setup.md → prompts/prompt-setup.md} +7 -7
  120. package/src/autoresearch/prompts/prompt.md +103 -0
  121. package/src/autoresearch/prompts.ts +126 -0
  122. package/src/autoresearch/runs.ts +708 -0
  123. package/src/autoresearch/types.ts +9 -150
  124. package/src/capability/index.ts +4 -4
  125. package/src/capability/types.ts +20 -0
  126. package/src/cli/accounts-cli.ts +21 -5
  127. package/src/cli/config-cli.ts +25 -1
  128. package/src/cli/fast-help.ts +1 -2
  129. package/src/cli/list-models.ts +5 -8
  130. package/src/cli/setup-cli.ts +8 -0
  131. package/src/cli.ts +2 -21
  132. package/src/commands/autoresearch.ts +33 -0
  133. package/src/commands/coordinator.ts +15 -0
  134. package/src/commands/launch.ts +2 -4
  135. package/src/commands/quick-lane.ts +1 -1
  136. package/src/commands/sdk.ts +24 -0
  137. package/src/commands/state.ts +1 -1
  138. package/src/config/autorouting-contract.ts +474 -0
  139. package/src/config/autorouting-generator.ts +238 -0
  140. package/src/config/autorouting-tier-map.ts +6108 -0
  141. package/src/config/autorouting.ts +120 -0
  142. package/src/config/model-discovery-manager.ts +42 -11
  143. package/src/config/model-registry.ts +348 -68
  144. package/src/config/provider-selection-policy.ts +60 -9
  145. package/src/config/settings-schema.ts +195 -6
  146. package/src/config/settings.ts +62 -1
  147. package/src/config.ts +2 -3
  148. package/src/coordinator/contract.ts +0 -1
  149. package/src/coordinator-mcp/codex-handoff.ts +68 -42
  150. package/src/coordinator-mcp/durability.ts +200 -0
  151. package/src/coordinator-mcp/event-webhook.ts +278 -0
  152. package/src/coordinator-mcp/question-state.ts +109 -46
  153. package/src/coordinator-mcp/server.ts +932 -504
  154. package/src/crash/index-store.ts +126 -22
  155. package/src/crash/record-loader.ts +7 -0
  156. package/src/crash/upstream/relay.ts +82 -34
  157. package/src/cursor.ts +84 -1
  158. package/src/debug/index.ts +26 -0
  159. package/src/defaults/gjc/skills/autoresearch/SKILL.md +116 -0
  160. package/src/defaults/gjc/skills/autoresearch/auto-critic.md +46 -0
  161. package/src/defaults/gjc/skills/autoresearch/auto-iterate.md +42 -0
  162. package/src/defaults/gjc/skills/deep-interview/SKILL.md +17 -37
  163. package/src/defaults/gjc/skills/ralplan/SKILL.md +21 -18
  164. package/src/defaults/gjc/skills/ultragoal/SKILL.md +6 -17
  165. package/src/defaults/gjc/skills/ultragoal/ai-slop-cleaner.md +2 -2
  166. package/src/defaults/gjc-defaults.ts +89 -2
  167. package/src/defaults/gjc-skills.generated.ts +24 -17
  168. package/src/discovery/builtin.ts +18 -5
  169. package/src/discovery/helpers.ts +6 -6
  170. package/src/edit/index.ts +5 -2
  171. package/src/eval/py/executor.ts +8 -0
  172. package/src/extensibility/extensions/loader.ts +135 -13
  173. package/src/extensibility/extensions/wrapper.ts +1 -2
  174. package/src/extensibility/gjc-plugins/schema.ts +1 -1
  175. package/src/extensibility/runtime-skill-discovery.ts +2 -2
  176. package/src/extensibility/skill-management.ts +2 -3
  177. package/src/extensibility/skills.ts +16 -8
  178. package/src/gjc-runtime/autoresearch-runtime.ts +1509 -0
  179. package/src/gjc-runtime/gc-render.ts +0 -1
  180. package/src/gjc-runtime/gc-runtime.ts +1 -11
  181. package/src/gjc-runtime/launch-tmux.ts +3 -3
  182. package/src/gjc-runtime/psmux-detect.ts +2 -2
  183. package/src/gjc-runtime/python-transcript.ts +58 -0
  184. package/src/gjc-runtime/ralplan-runtime.ts +6 -18
  185. package/src/gjc-runtime/session-layout.ts +18 -7
  186. package/src/gjc-runtime/session-state-sidecar.ts +58 -9
  187. package/src/gjc-runtime/state-renderer.ts +0 -38
  188. package/src/gjc-runtime/state-runtime.ts +43 -22
  189. package/src/gjc-runtime/state-schema.ts +1 -1
  190. package/src/gjc-runtime/tmux-common.ts +7 -7
  191. package/src/gjc-runtime/ultragoal-change-set.ts +232 -11
  192. package/src/gjc-runtime/ultragoal-runtime.ts +309 -114
  193. package/src/gjc-runtime/ultragoal-validation-policy.ts +247 -0
  194. package/src/gjc-runtime/workflow-command-ref.ts +15 -11
  195. package/src/gjc-runtime/workflow-manifest.generated.json +413 -532
  196. package/src/gjc-runtime/workflow-manifest.ts +43 -83
  197. package/src/gjc-runtime/workflow-recovery-projection.ts +616 -0
  198. package/src/hooks/skill-keywords.ts +3 -3
  199. package/src/hooks/skill-state.ts +2 -2
  200. package/src/internal-urls/docs-index.generated.ts +26 -24
  201. package/src/lsp/index.ts +25 -5
  202. package/src/main.ts +2 -27
  203. package/src/modes/acp/acp-agent.ts +200 -75
  204. package/src/modes/components/model-selector.ts +216 -13
  205. package/src/modes/components/oauth-selector.ts +5 -5
  206. package/src/modes/components/skill-hud/render.ts +173 -35
  207. package/src/modes/components/smart-routing-panel.ts +531 -0
  208. package/src/modes/components/tool-status-header.ts +6 -3
  209. package/src/modes/controllers/command-controller.ts +17 -7
  210. package/src/modes/controllers/input-controller.ts +44 -9
  211. package/src/modes/controllers/runtime-mcp-command-controller.ts +4 -0
  212. package/src/modes/controllers/selector-controller.ts +298 -65
  213. package/src/modes/interactive-mode.ts +8 -1
  214. package/src/modes/shared/agent-wire/workflow-gate-types.ts +1 -1
  215. package/src/modes/types.ts +9 -1
  216. package/src/prompts/agents/planner.md +1 -1
  217. package/src/prompts/system/system-prompt.md +1 -1
  218. package/src/prompts/system/volatile-project-context.md +2 -1
  219. package/src/prompts/tools/move-session.md +15 -0
  220. package/src/prompts/tools/python.md +12 -0
  221. package/src/prompts/tools/skill-discovery.md +1 -1
  222. package/src/prompts/tools/skill.md +2 -2
  223. package/src/prompts/tools/task-summary.md +1 -0
  224. package/src/prompts/tools/task.md +6 -0
  225. package/src/rlm/artifacts.ts +12 -10
  226. package/src/runtime/optional-runtime-services.ts +3 -2
  227. package/src/runtime/workspace-tree-service.ts +11 -3
  228. package/src/runtime-mcp/config.ts +8 -1
  229. package/src/runtime-mcp/manager.ts +33 -0
  230. package/src/sdk/acp/adapter.ts +48 -1
  231. package/src/sdk/broker/broker.ts +30 -2
  232. package/src/sdk/broker/discovery.ts +217 -2
  233. package/src/sdk/broker/lifecycle.ts +385 -59
  234. package/src/sdk/broker/session-index.ts +243 -48
  235. package/src/sdk/broker/transport.ts +1 -0
  236. package/src/sdk/bus/chat-daemon-control.ts +8 -2
  237. package/src/sdk/bus/chat-daemon-runtime.ts +5 -0
  238. package/src/sdk/bus/index.ts +208 -11
  239. package/src/sdk/bus/kind-aware-reconciliation.ts +16 -0
  240. package/src/sdk/bus/reconciliation-store.ts +27 -5
  241. package/src/sdk/bus/telegram-daemon-contract.ts +12 -2
  242. package/src/sdk/client/client.ts +204 -22
  243. package/src/sdk/host/host.ts +16 -0
  244. package/src/sdk/host/internal-autorouting-state.ts +13 -0
  245. package/src/sdk/host/model-pin.ts +101 -0
  246. package/src/sdk/host/reverse-leases.ts +2 -1
  247. package/src/sdk/host/session-runtime.test.ts +224 -1
  248. package/src/sdk/host/session-runtime.ts +125 -37
  249. package/src/sdk/lifecycle/service.ts +3 -1
  250. package/src/sdk/lifecycle-session.ts +42 -1
  251. package/src/sdk/protocol/operation-inventory.generated.json +66 -0
  252. package/src/sdk/router/session-router.ts +375 -36
  253. package/src/sdk/session.ts +547 -47
  254. package/src/session/account-inventory.ts +1 -1
  255. package/src/session/agent-session.ts +765 -189
  256. package/src/session/artifacts.ts +234 -4
  257. package/src/session/internal/managed-session-storage.ts +91 -4
  258. package/src/session/provider-safety-stop-hint.ts +3 -2
  259. package/src/session/session-manager.ts +775 -16
  260. package/src/session/session-staging-paths.ts +8 -0
  261. package/src/setup/hermes/templates/operator-instructions.v1.md +0 -1
  262. package/src/setup/host-plugin-setup.ts +2 -2
  263. package/src/skill-state/active-state.ts +2 -2
  264. package/src/skill-state/canonical-skills.ts +1 -1
  265. package/src/skill-state/initial-phase.ts +1 -1
  266. package/src/skill-state/workflow-hud.ts +41 -41
  267. package/src/skill-state/workflow-mutation-guard.ts +26 -7
  268. package/src/slash-commands/builtin-registry.ts +77 -0
  269. package/src/slash-commands/helpers/autorouting-status.ts +55 -0
  270. package/src/system-prompt.ts +102 -5
  271. package/src/task/discovery.ts +2 -3
  272. package/src/task/executor.ts +617 -43
  273. package/src/task/index.ts +262 -15
  274. package/src/task/receipt.ts +30 -0
  275. package/src/task/render.ts +11 -1
  276. package/src/task/types.ts +316 -0
  277. package/src/tools/atomic-file-write.ts +594 -0
  278. package/src/tools/bisect.ts +3 -2
  279. package/src/tools/descriptors.test.ts +3 -0
  280. package/src/tools/descriptors.ts +24 -0
  281. package/src/tools/image-gen.ts +5 -1
  282. package/src/tools/index.ts +62 -5
  283. package/src/tools/move-session.ts +107 -0
  284. package/src/tools/python.ts +205 -0
  285. package/src/tools/read.ts +88 -15
  286. package/src/tools/renderers.ts +2 -0
  287. package/src/tools/resource-gc.ts +8 -177
  288. package/src/tools/search.ts +30 -6
  289. package/src/tools/skill-discovery.ts +1 -0
  290. package/src/tools/skill.ts +37 -7
  291. package/src/tools/subagent-render.ts +119 -13
  292. package/src/tools/subagent.ts +91 -74
  293. package/src/tools/tool-catalog.generated.ts +64 -2
  294. package/src/tools/write.ts +16 -12
  295. package/src/utils/xml-escape.ts +14 -0
  296. package/src/web/search/providers/codex.ts +2 -2
  297. package/src/workflow/workflow-intent-diff.ts +13 -12
  298. package/src/workflow/workflow-intent-report-consumer.ts +6 -6
  299. package/dist/types/autoresearch/helpers.d.ts +0 -24
  300. package/dist/types/autoresearch/index.d.ts +0 -2
  301. package/dist/types/autoresearch/state.d.ts +0 -17
  302. package/dist/types/autoresearch/storage.d.ts +0 -142
  303. package/dist/types/autoresearch/tools/init-experiment.d.ts +0 -31
  304. package/dist/types/autoresearch/tools/log-experiment.d.ts +0 -23
  305. package/dist/types/autoresearch/tools/run-experiment.d.ts +0 -8
  306. package/dist/types/autoresearch/tools/update-notes.d.ts +0 -12
  307. package/dist/types/commands/team.d.ts +0 -24
  308. package/dist/types/gjc-runtime/team-gc.d.ts +0 -7
  309. package/dist/types/gjc-runtime/team-launch.d.ts +0 -61
  310. package/dist/types/gjc-runtime/team-notify.d.ts +0 -45
  311. package/dist/types/gjc-runtime/team-runtime.d.ts +0 -336
  312. package/dist/types/gjc-runtime/team-store.d.ts +0 -168
  313. package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +0 -43
  314. package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +0 -92
  315. package/dist/types/gjc-runtime/team-workers.d.ts +0 -83
  316. package/dist/types/rlm/index.d.ts +0 -47
  317. package/dist/types/rlm/preset.d.ts +0 -23
  318. package/dist/types/rlm/python-tool.d.ts +0 -16
  319. package/src/autoresearch/command-resume.md +0 -14
  320. package/src/autoresearch/index.ts +0 -536
  321. package/src/autoresearch/prompt.md +0 -103
  322. package/src/autoresearch/resume-message.md +0 -10
  323. package/src/autoresearch/state.ts +0 -273
  324. package/src/autoresearch/storage.ts +0 -699
  325. package/src/autoresearch/tools/init-experiment.ts +0 -272
  326. package/src/autoresearch/tools/log-experiment.ts +0 -524
  327. package/src/autoresearch/tools/run-experiment.ts +0 -475
  328. package/src/autoresearch/tools/update-notes.ts +0 -109
  329. package/src/commands/rlm.ts +0 -19
  330. package/src/commands/team.ts +0 -238
  331. package/src/defaults/gjc/skills/deep-interview/auto-research-greenfield.md +0 -42
  332. package/src/defaults/gjc/skills/team/SKILL.md +0 -467
  333. package/src/gjc-runtime/team-gc.ts +0 -49
  334. package/src/gjc-runtime/team-launch.ts +0 -404
  335. package/src/gjc-runtime/team-notify.ts +0 -326
  336. package/src/gjc-runtime/team-runtime.ts +0 -5923
  337. package/src/gjc-runtime/team-store.ts +0 -878
  338. package/src/gjc-runtime/team-worker-heartbeat.ts +0 -149
  339. package/src/gjc-runtime/team-worker-memory-guard.ts +0 -363
  340. package/src/gjc-runtime/team-workers.ts +0 -1123
  341. package/src/prompts/system/rlm-report-command.md +0 -1
  342. package/src/prompts/system/rlm-research.md +0 -23
  343. package/src/rlm/index.ts +0 -365
  344. package/src/rlm/preset.ts +0 -76
  345. package/src/rlm/python-tool.ts +0 -68
@@ -1,536 +0,0 @@
1
- import * as fs from "node:fs";
2
- import * as path from "node:path";
3
- import type { AutocompleteItem } from "@gajae-code/tui";
4
- import { logger, prompt } from "@gajae-code/utils";
5
- import type { ExtensionContext, ExtensionFactory } from "../extensibility/extensions";
6
- import * as git from "../utils/git";
7
- import commandResumeTemplate from "./command-resume.md" with { type: "text" };
8
- import { createDashboardController } from "./dashboard";
9
- import { ensureAutoresearchBranch } from "./git";
10
- import { formatNum } from "./helpers";
11
- import promptTemplate from "./prompt.md" with { type: "text" };
12
- import setupPromptTemplate from "./prompt-setup.md" with { type: "text" };
13
- import resumeMessageTemplate from "./resume-message.md" with { type: "text" };
14
- import {
15
- buildExperimentState,
16
- createExperimentState,
17
- createRuntimeStore,
18
- currentResults,
19
- findBaselineMetric,
20
- findBaselineRunNumber,
21
- findBestKeptMetric,
22
- reconstructControlState,
23
- } from "./state";
24
- import { openAutoresearchStorage, openAutoresearchStorageIfExists, type RunRow, type SessionRow } from "./storage";
25
- import { createInitExperimentTool } from "./tools/init-experiment";
26
- import { createLogExperimentTool } from "./tools/log-experiment";
27
- import { createRunExperimentTool } from "./tools/run-experiment";
28
- import { createUpdateNotesTool } from "./tools/update-notes";
29
- import type { AutoresearchRuntime, ExperimentResult, PendingRunSummary } from "./types";
30
-
31
- const EXPERIMENT_TOOL_NAMES = ["init_experiment", "run_experiment", "log_experiment", "update_notes"];
32
-
33
- export const createAutoresearchExtension: ExtensionFactory = api => {
34
- const runtimeStore = createRuntimeStore();
35
- const dashboard = createDashboardController();
36
-
37
- const getSessionKey = (ctx: ExtensionContext): string => ctx.sessionManager.getSessionId();
38
- const getRuntime = (ctx: ExtensionContext): AutoresearchRuntime => runtimeStore.ensure(getSessionKey(ctx));
39
-
40
- const loadActiveSession = async (
41
- ctx: ExtensionContext,
42
- ): Promise<{ session: SessionRow | null; currentBranch: string | null }> => {
43
- const currentBranch = await tryReadBranch(ctx.cwd);
44
- const storage = await openAutoresearchStorageIfExists(ctx.cwd);
45
- if (!storage) return { session: null, currentBranch };
46
- const session = storage.getActiveSessionForBranch(currentBranch);
47
- return { session, currentBranch };
48
- };
49
-
50
- const rehydrate = async (ctx: ExtensionContext): Promise<void> => {
51
- const runtime = getRuntime(ctx);
52
- const control = reconstructControlState(ctx.sessionManager.getBranch());
53
- runtime.goal = control.goal;
54
- runtime.autoResumeArmed = false;
55
- runtime.lastAutoResumePendingRunNumber = null;
56
-
57
- // Skip storage entirely if autoresearch was never activated in this conversation.
58
- // This is the common case: every project gets a session_start event but most
59
- // never touch autoresearch, so we must not create a SQLite file just to look.
60
- const everActivated = control.lastMode !== null;
61
- const { session, currentBranch } = everActivated
62
- ? await loadActiveSession(ctx)
63
- : { session: null, currentBranch: null };
64
-
65
- // Mode is effective only when the recorded session matches the current git
66
- // branch. When the user switches off the autoresearch branch the widget hides
67
- // and the experiment tools detach, but the session entries are preserved so
68
- // switching back resumes seamlessly.
69
- const onActiveBranch = session === null || session.branch === null || session.branch === currentBranch;
70
- runtime.autoresearchMode = control.autoresearchMode && onActiveBranch;
71
-
72
- if (session && onActiveBranch) {
73
- const storage = await openAutoresearchStorageIfExists(ctx.cwd);
74
- if (storage) {
75
- const loggedRuns = storage.listLoggedRuns(session.id);
76
- runtime.state = buildExperimentState(session, loggedRuns);
77
- runtime.goal = runtime.goal ?? session.goal;
78
- runtime.lastRunSummary = pendingRunSummaryFromRow(storage.getPendingRun(session.id));
79
- } else {
80
- runtime.state = createExperimentState();
81
- runtime.lastRunSummary = null;
82
- }
83
- } else {
84
- runtime.state = createExperimentState();
85
- runtime.lastRunSummary = null;
86
- }
87
- runtime.lastRunDuration = runtime.lastRunSummary?.durationSeconds ?? null;
88
- runtime.lastRunAsi = runtime.lastRunSummary?.parsedAsi ?? null;
89
- runtime.lastRunArtifactDir = runtime.lastRunSummary?.runDirectory ?? null;
90
- runtime.lastRunNumber = runtime.lastRunSummary?.runNumber ?? null;
91
- runtime.runningExperiment = null;
92
- dashboard.updateWidget(ctx, runtime);
93
-
94
- const activeTools = api.getActiveTools();
95
- const experimentTools = new Set(EXPERIMENT_TOOL_NAMES);
96
- const nextActiveTools = runtime.autoresearchMode
97
- ? [...new Set([...activeTools, ...EXPERIMENT_TOOL_NAMES])]
98
- : activeTools.filter(name => !experimentTools.has(name));
99
- const toolsChanged =
100
- nextActiveTools.length !== activeTools.length ||
101
- nextActiveTools.some((name, index) => name !== activeTools[index]);
102
- if (toolsChanged) {
103
- await api.setActiveTools(nextActiveTools);
104
- }
105
- };
106
-
107
- const setMode = (
108
- ctx: ExtensionContext,
109
- enabled: boolean,
110
- goal: string | null,
111
- mode: "on" | "off" | "clear",
112
- ): void => {
113
- const runtime = getRuntime(ctx);
114
- runtime.autoresearchMode = enabled;
115
- runtime.autoResumeArmed = false;
116
- runtime.goal = goal;
117
- runtime.lastAutoResumePendingRunNumber = null;
118
- api.appendEntry("autoresearch-control", goal ? { mode, goal } : { mode });
119
- };
120
-
121
- api.registerTool(createInitExperimentTool({ dashboard, getRuntime, pi: api }));
122
- api.registerTool(createRunExperimentTool({ dashboard, getRuntime, pi: api }));
123
- api.registerTool(createLogExperimentTool({ dashboard, getRuntime, pi: api }));
124
- api.registerTool(createUpdateNotesTool({ dashboard, getRuntime, pi: api }));
125
-
126
- api.registerCommand("autoresearch", {
127
- description: "Toggle builtin autoresearch mode, or pass off / clear, or a goal message.",
128
- getArgumentCompletions(argumentPrefix: string): AutocompleteItem[] | null {
129
- if (argumentPrefix.includes(" ")) return null;
130
- const normalized = argumentPrefix.trim().toLowerCase();
131
- if (normalized.length === 0) return null;
132
- const completions: AutocompleteItem[] = [
133
- { label: "off", value: "off", description: "Leave autoresearch mode" },
134
- {
135
- label: "clear",
136
- value: "clear",
137
- description: "Reset worktree to baseline and close the active session",
138
- },
139
- ];
140
- const filtered = completions.filter(item => item.label.startsWith(normalized));
141
- return filtered.length > 0 ? filtered : null;
142
- },
143
- async handler(args, ctx): Promise<void> {
144
- const trimmed = args.trim();
145
- const runtime = getRuntime(ctx);
146
-
147
- if (trimmed === "" && runtime.autoresearchMode) {
148
- setMode(ctx, false, runtime.goal, "off");
149
- dashboard.updateWidget(ctx, runtime);
150
- const experimentTools = new Set(EXPERIMENT_TOOL_NAMES);
151
- await api.setActiveTools(api.getActiveTools().filter(name => !experimentTools.has(name)));
152
- ctx.ui.notify("Autoresearch mode disabled", "info");
153
- return;
154
- }
155
-
156
- if (trimmed === "off") {
157
- setMode(ctx, false, runtime.goal, "off");
158
- dashboard.updateWidget(ctx, runtime);
159
- const experimentTools = new Set(EXPERIMENT_TOOL_NAMES);
160
- await api.setActiveTools(api.getActiveTools().filter(name => !experimentTools.has(name)));
161
- ctx.ui.notify("Autoresearch mode disabled", "info");
162
- return;
163
- }
164
-
165
- if (trimmed === "clear" || trimmed.startsWith("clear ")) {
166
- const flagPart = trimmed === "clear" ? "" : trimmed.slice("clear ".length).trim();
167
- const keepTree = flagPart.includes("--keep-tree");
168
- const resetTreeForce = flagPart.includes("--reset-tree");
169
- await handleClear(ctx, runtime, { keepTree, resetTreeForce });
170
- return;
171
- }
172
-
173
- const goalArg = trimmed.length > 0 ? trimmed : null;
174
- const branchResult = await ensureAutoresearchBranch(api, ctx.cwd, goalArg ?? runtime.goal);
175
- if (!branchResult.ok) {
176
- ctx.ui.notify(branchResult.error, "error");
177
- return;
178
- }
179
- if (branchResult.warning) {
180
- ctx.ui.notify(branchResult.warning, "warning");
181
- }
182
-
183
- // Look up an existing session for the branch we just landed on. A session
184
- // recorded under a different autoresearch/* branch is intentionally ignored
185
- // — `/autoresearch` on a fresh branch starts a fresh session. Only open the
186
- // DB if it already exists; the empty-state path must not create one.
187
- const existingStorage = await openAutoresearchStorageIfExists(ctx.cwd);
188
- const existingSession = existingStorage?.getActiveSessionForBranch(branchResult.branchName) ?? null;
189
- const resumeContext = trimmed;
190
- const branchStatusLine = branchResult.branchName
191
- ? branchResult.created
192
- ? `Created and checked out dedicated git branch \`${branchResult.branchName}\` before resuming.`
193
- : `Using dedicated git branch \`${branchResult.branchName}\`.`
194
- : "Continuing on the current branch — no autoresearch branch was created.";
195
-
196
- if (existingSession && existingStorage) {
197
- if (goalArg) existingStorage.updateSession(existingSession.id, { goal: goalArg });
198
- if (branchResult.branchName) {
199
- existingStorage.updateSession(existingSession.id, { branch: branchResult.branchName });
200
- }
201
- const refreshed = existingStorage.getSessionById(existingSession.id) ?? existingSession;
202
- runtime.state = buildExperimentState(refreshed, existingStorage.listLoggedRuns(refreshed.id));
203
- runtime.goal = refreshed.goal ?? goalArg;
204
- setMode(ctx, true, runtime.goal, "on");
205
- dashboard.updateWidget(ctx, runtime);
206
- await api.setActiveTools([...new Set([...api.getActiveTools(), ...EXPERIMENT_TOOL_NAMES])]);
207
- api.sendUserMessage(
208
- prompt.render(commandResumeTemplate, {
209
- branch_status_line: branchStatusLine,
210
- has_resume_context: resumeContext.length > 0,
211
- resume_context: resumeContext,
212
- }),
213
- );
214
- return;
215
- }
216
-
217
- setMode(ctx, true, goalArg, "on");
218
- dashboard.updateWidget(ctx, runtime);
219
- await api.setActiveTools([...new Set([...api.getActiveTools(), ...EXPERIMENT_TOOL_NAMES])]);
220
- if (goalArg !== null) {
221
- api.sendUserMessage(goalArg);
222
- } else {
223
- ctx.ui.notify("Autoresearch enabled—describe what to optimize in your next message.", "info");
224
- }
225
- },
226
- });
227
-
228
- api.registerShortcut("ctrl+x", {
229
- description: "Toggle autoresearch dashboard",
230
- handler(ctx): void {
231
- const runtime = getRuntime(ctx);
232
- if (runtime.state.results.length === 0 && !runtime.runningExperiment) {
233
- ctx.ui.notify("No autoresearch results yet", "info");
234
- return;
235
- }
236
- runtime.dashboardExpanded = !runtime.dashboardExpanded;
237
- dashboard.updateWidget(ctx, runtime);
238
- },
239
- });
240
-
241
- api.registerShortcut("ctrl+shift+x", {
242
- description: "Show autoresearch dashboard overlay",
243
- handler(ctx): Promise<void> {
244
- return dashboard.showOverlay(ctx, getRuntime(ctx));
245
- },
246
- });
247
-
248
- api.on("session_start", (_event, ctx) => rehydrate(ctx));
249
- api.on("session_switch", (_event, ctx) => rehydrate(ctx));
250
- api.on("session_branch", (_event, ctx) => rehydrate(ctx));
251
- api.on("session_tree", (_event, ctx) => rehydrate(ctx));
252
- api.on("session_shutdown", (_event, ctx) => {
253
- dashboard.clear(ctx);
254
- runtimeStore.clear(getSessionKey(ctx));
255
- });
256
-
257
- api.on("agent_end", async (_event, ctx) => {
258
- const runtime = getRuntime(ctx);
259
- runtime.runningExperiment = null;
260
- dashboard.updateWidget(ctx, runtime);
261
- dashboard.requestRender();
262
- if (!runtime.autoresearchMode) return;
263
- if (ctx.hasPendingMessages()) {
264
- runtime.autoResumeArmed = false;
265
- return;
266
- }
267
- const { session } = await loadActiveSession(ctx);
268
- const storage = session ? await openAutoresearchStorageIfExists(ctx.cwd) : null;
269
- const pendingRow = session && storage ? storage.getPendingRun(session.id) : null;
270
- const pendingRun = pendingRunSummaryFromRow(pendingRow);
271
- runtime.lastRunSummary = pendingRun;
272
- runtime.lastRunDuration = pendingRun?.durationSeconds ?? runtime.lastRunDuration;
273
- runtime.lastRunAsi = pendingRun?.parsedAsi ?? runtime.lastRunAsi;
274
- const shouldResumePendingRun =
275
- pendingRun !== null && runtime.lastAutoResumePendingRunNumber !== pendingRun.runNumber;
276
- if (!shouldResumePendingRun && !runtime.autoResumeArmed) {
277
- return;
278
- }
279
- runtime.autoResumeArmed = false;
280
- runtime.lastAutoResumePendingRunNumber = pendingRun?.runNumber ?? null;
281
- api.sendMessage(
282
- {
283
- customType: "autoresearch-resume",
284
- content: prompt.render(resumeMessageTemplate, {
285
- has_pending_run: Boolean(pendingRun),
286
- }),
287
- display: false,
288
- attribution: "agent",
289
- },
290
- { deliverAs: "nextTurn", triggerTurn: true },
291
- );
292
- });
293
-
294
- api.on("before_agent_start", async (event, ctx) => {
295
- const runtime = getRuntime(ctx);
296
- if (!runtime.autoresearchMode) return;
297
- // Re-check git branch on every agent start. If the user manually switched
298
- // off the autoresearch/* branch between turns, we silently drop autoresearch
299
- // from this turn — the widget hides, the experiment tools detach, and we do
300
- // not inject the autoresearch system prompt.
301
- const { session, currentBranch } = await loadActiveSession(ctx);
302
- const onActiveBranch = session === null || session.branch === null || session.branch === currentBranch;
303
- if (!onActiveBranch) {
304
- runtime.autoresearchMode = false;
305
- runtime.state = createExperimentState();
306
- runtime.lastRunSummary = null;
307
- runtime.runningExperiment = null;
308
- dashboard.updateWidget(ctx, runtime);
309
- const experimentTools = new Set(EXPERIMENT_TOOL_NAMES);
310
- await api.setActiveTools(api.getActiveTools().filter(name => !experimentTools.has(name)));
311
- return;
312
- }
313
- const storage = await openAutoresearchStorageIfExists(ctx.cwd);
314
- if (session && storage) {
315
- runtime.state = buildExperimentState(session, storage.listLoggedRuns(session.id));
316
- }
317
- const pendingRow = session && storage ? storage.getPendingRun(session.id) : null;
318
- const pendingRun = pendingRunSummaryFromRow(pendingRow);
319
- runtime.lastRunSummary = pendingRun;
320
- runtime.lastRunDuration = pendingRun?.durationSeconds ?? runtime.lastRunDuration;
321
- runtime.lastRunAsi = pendingRun?.parsedAsi ?? runtime.lastRunAsi;
322
- const state = runtime.state;
323
- const currentSegmentResults = currentResults(state.results, state.currentSegment);
324
- const baselineMetric = findBaselineMetric(state.results, state.currentSegment);
325
- const baselineRunNumber = findBaselineRunNumber(state.results, state.currentSegment);
326
- const bestMetric = findBestKeptMetric(state.results, state.currentSegment, state.bestDirection);
327
- const bestResult = bestKeptResult(state.results, state.currentSegment, state.bestDirection);
328
- const goal = runtime.goal ?? state.goal ?? state.name ?? "";
329
- const recentResults = currentSegmentResults.slice(-3).map(result => {
330
- const asiSummary = summarizeExperimentAsi(result);
331
- return {
332
- asi_summary: asiSummary,
333
- description: result.description,
334
- has_asi_summary: Boolean(asiSummary),
335
- metric_display: formatNum(result.metric, state.metricUnit),
336
- run_number: result.runNumber ?? state.results.indexOf(result) + 1,
337
- status: result.status,
338
- has_deviations: result.scopeDeviations.length > 0,
339
- deviations: result.scopeDeviations.join(", "),
340
- justified: Boolean(result.justification),
341
- flagged: result.flagged,
342
- flagged_reason: result.flaggedReason ?? "",
343
- };
344
- });
345
- const unjustifiedRuns = currentSegmentResults
346
- .filter(r => r.status === "keep" && !r.flagged && r.scopeDeviations.length > 0 && !r.justification)
347
- .slice(-3)
348
- .map(r => ({
349
- run_number: r.runNumber,
350
- paths: r.scopeDeviations.join(", "),
351
- }));
352
- if (!session) {
353
- const currentBranch = await tryReadBranch(ctx.cwd);
354
- const onAutoresearchBranch = currentBranch?.startsWith("autoresearch/") ?? false;
355
- const baselineWarning = onAutoresearchBranch
356
- ? null
357
- : "Heads up: you are not on a dedicated `autoresearch/*` branch. `log_experiment discard` will only revert run-modified files, not reset to baseline — so harness files written before `init_experiment` may not survive a discard. Clean the worktree and re-run `/autoresearch` if you want full revert safety.";
358
- return {
359
- systemPrompt: [
360
- prompt.render(setupPromptTemplate, {
361
- base_system_prompt: event.systemPrompt.join("\n\n"),
362
- has_goal: goal.trim().length > 0,
363
- goal,
364
- working_dir: ctx.cwd,
365
- has_branch: Boolean(currentBranch),
366
- branch: currentBranch ?? "",
367
- has_baseline_warning: baselineWarning !== null,
368
- baseline_warning: baselineWarning ?? "",
369
- }),
370
- ],
371
- };
372
- }
373
- return {
374
- systemPrompt: [
375
- prompt.render(promptTemplate, {
376
- base_system_prompt: event.systemPrompt.join("\n\n"),
377
- has_goal: goal.trim().length > 0,
378
- goal,
379
- working_dir: ctx.cwd,
380
- default_metric_name: state.metricName,
381
- metric_name: state.metricName,
382
- has_branch: Boolean(state.branch),
383
- branch: state.branch,
384
- has_baseline_commit: Boolean(state.baselineCommit),
385
- baseline_commit: state.baselineCommit ? state.baselineCommit.slice(0, 12) : "",
386
- has_notes: state.notes.trim().length > 0,
387
- notes: state.notes,
388
- current_segment: state.currentSegment + 1,
389
- current_segment_run_count: currentSegmentResults.length,
390
- has_baseline_metric: baselineMetric !== null,
391
- baseline_metric_display: formatNum(baselineMetric, state.metricUnit),
392
- baseline_run_number: baselineRunNumber,
393
- has_best_result: bestResult !== null && bestMetric !== null,
394
- best_metric_display: bestMetric !== null ? formatNum(bestMetric, state.metricUnit) : "-",
395
- best_run_number: bestResult ? (bestResult.runNumber ?? state.results.indexOf(bestResult) + 1) : null,
396
- has_recent_results: recentResults.length > 0,
397
- recent_results: recentResults,
398
- has_unjustified_runs: unjustifiedRuns.length > 0,
399
- unjustified_runs: unjustifiedRuns,
400
- has_pending_run: Boolean(pendingRun),
401
- pending_run_number: pendingRun?.runNumber,
402
- pending_run_command: pendingRun?.command,
403
- pending_run_passed: pendingRun?.passed ?? false,
404
- has_pending_run_metric: pendingRun?.parsedPrimary !== null && pendingRun?.parsedPrimary !== undefined,
405
- pending_run_metric_display:
406
- pendingRun?.parsedPrimary !== null && pendingRun?.parsedPrimary !== undefined
407
- ? formatNum(pendingRun.parsedPrimary, state.metricUnit)
408
- : null,
409
- }),
410
- ],
411
- };
412
- });
413
-
414
- async function handleClear(
415
- ctx: ExtensionContext,
416
- runtime: AutoresearchRuntime,
417
- opts: { keepTree: boolean; resetTreeForce: boolean },
418
- ): Promise<void> {
419
- const storage = await openAutoresearchStorage(ctx.cwd);
420
- const session = storage.getActiveSession();
421
- const branchName = await tryReadBranch(ctx.cwd);
422
- const onAutoresearchBranch = branchName?.startsWith("autoresearch/") ?? false;
423
- const shouldResetTree = !opts.keepTree && (onAutoresearchBranch || opts.resetTreeForce);
424
- if (shouldResetTree && session?.baselineCommit) {
425
- try {
426
- await git.reset(ctx.cwd, { hard: true, target: session.baselineCommit });
427
- await git.clean(ctx.cwd);
428
- ctx.ui.notify(`Reset worktree to baseline ${session.baselineCommit.slice(0, 12)}.`, "info");
429
- } catch (err) {
430
- ctx.ui.notify(
431
- `Failed to reset worktree to baseline: ${err instanceof Error ? err.message : String(err)}`,
432
- "error",
433
- );
434
- }
435
- } else if (shouldResetTree) {
436
- ctx.ui.notify("No baseline commit recorded — skipped worktree reset.", "warning");
437
- }
438
-
439
- removeLegacyArtifacts(ctx.cwd);
440
-
441
- if (session) {
442
- storage.closeSession(session.id);
443
- }
444
- runtime.state = createExperimentState();
445
- runtime.goal = null;
446
- runtime.lastRunDuration = null;
447
- runtime.lastRunAsi = null;
448
- runtime.lastRunArtifactDir = null;
449
- runtime.lastRunNumber = null;
450
- runtime.lastRunSummary = null;
451
- setMode(ctx, false, null, "clear");
452
- dashboard.updateWidget(ctx, runtime);
453
- const experimentTools = new Set(EXPERIMENT_TOOL_NAMES);
454
- await api.setActiveTools(api.getActiveTools().filter(name => !experimentTools.has(name)));
455
- ctx.ui.notify("Autoresearch session cleared.", "info");
456
- }
457
- };
458
-
459
- const LEGACY_ARTIFACTS = [
460
- "autoresearch.md",
461
- "autoresearch.sh",
462
- "autoresearch.checks.sh",
463
- "autoresearch.program.md",
464
- "autoresearch.ideas.md",
465
- "autoresearch.jsonl",
466
- "autoresearch.config.json",
467
- ".autoresearch",
468
- ];
469
-
470
- function removeLegacyArtifacts(workDir: string): void {
471
- for (const name of LEGACY_ARTIFACTS) {
472
- const target = path.join(workDir, name);
473
- try {
474
- fs.rmSync(target, { recursive: true, force: true });
475
- } catch (err) {
476
- logger.warn("Failed to remove legacy autoresearch artifact", {
477
- path: target,
478
- error: err instanceof Error ? err.message : String(err),
479
- });
480
- }
481
- }
482
- }
483
-
484
- function pendingRunSummaryFromRow(row: RunRow | null): PendingRunSummary | null {
485
- if (!row) return null;
486
- if (row.status !== null) return null;
487
- if (row.completedAt === null) return null;
488
- const passed = row.exitCode === 0 && !row.timedOut;
489
- return {
490
- command: row.command,
491
- durationSeconds: row.durationMs !== null ? row.durationMs / 1000 : null,
492
- parsedAsi: row.parsedAsi,
493
- parsedMetrics: row.parsedMetrics,
494
- parsedPrimary: row.parsedPrimary,
495
- passed,
496
- preRunDirtyPaths: row.preRunDirtyPaths,
497
- runDirectory: path.dirname(row.logPath),
498
- runNumber: row.id,
499
- exitCode: row.exitCode,
500
- timedOut: row.timedOut,
501
- };
502
- }
503
-
504
- function summarizeExperimentAsi(result: ExperimentResult): string | null {
505
- const hypothesis = typeof result.asi?.hypothesis === "string" ? result.asi.hypothesis.trim() : "";
506
- const rollback = typeof result.asi?.rollback_reason === "string" ? result.asi.rollback_reason.trim() : "";
507
- const next = typeof result.asi?.next_action_hint === "string" ? result.asi.next_action_hint.trim() : "";
508
- const summary = [hypothesis, rollback, next].filter(part => part.length > 0).join(" | ");
509
- return summary.length > 0 ? summary.slice(0, 220) : null;
510
- }
511
-
512
- function bestKeptResult(
513
- results: ExperimentResult[],
514
- segment: number,
515
- direction: "lower" | "higher",
516
- ): ExperimentResult | null {
517
- let best: ExperimentResult | null = null;
518
- for (const result of results) {
519
- if (result.segment !== segment || result.status !== "keep" || result.flagged) continue;
520
- if (!best) {
521
- best = result;
522
- continue;
523
- }
524
- const better = direction === "lower" ? result.metric < best.metric : result.metric > best.metric;
525
- if (better) best = result;
526
- }
527
- return best;
528
- }
529
-
530
- async function tryReadBranch(cwd: string): Promise<string | null> {
531
- try {
532
- return (await git.branch.current(cwd)) ?? null;
533
- } catch {
534
- return null;
535
- }
536
- }
@@ -1,103 +0,0 @@
1
- {{base_system_prompt}}
2
-
3
- ## Autoresearch Mode
4
-
5
- Autoresearch mode is active.
6
-
7
- {{#if has_goal}}
8
- Primary goal:
9
- {{goal}}
10
- {{else}}
11
- There is no goal recorded for this session yet. Infer what to optimize from the latest user message and the conversation; capture the goal in your notes (`update_notes`) once it is clear.
12
- {{/if}}
13
-
14
- Session state and run artifacts are managed for you. The benchmark entrypoint is `bash autoresearch.sh` (committed during Phase 1). Do not edit `autoresearch.sh` mid-segment unless you intentionally bump segment via `init_experiment new_segment: true`. Do not create `autoresearch.md` or `.autoresearch/` in this repo.
15
-
16
- Working directory: `{{working_dir}}`
17
- {{#if has_branch}}Active branch: `{{branch}}`{{/if}}
18
- {{#if has_baseline_commit}}Baseline commit: `{{baseline_commit}}`{{/if}}
19
-
20
- You are running an autonomous experiment loop. Keep iterating until the user interrupts you or the configured maximum iteration count is reached.
21
-
22
- ### Available tools
23
- - `init_experiment` — open or reconfigure the session. Pass `new_segment: true` to start a fresh baseline within the current session.
24
- - `run_experiment` — run the benchmark (`bash autoresearch.sh`). Output is captured automatically and `METRIC name=value` / `ASI key=value` lines printed by the harness are parsed back to you. The command is fixed; if you need a different workload, edit `autoresearch.sh` and bump segment via `init_experiment new_segment: true`.
25
- - `log_experiment` — record the result. On `keep`, changes are committed only on a dedicated `autoresearch/*` branch; otherwise the tool warns and leaves files in the worktree. On `discard`/`crash`/`checks_failed`, the worktree is reverted. Pass `flag_runs` to mark earlier runs as suspect; flagged runs are excluded from baseline and best-metric math.
26
- - `update_notes` — replace the durable session playbook (`body`) or append to the ideas backlog (`append_idea`). The notes are injected into your system prompt every iteration.
27
-
28
- ### Operating protocol
29
- 1. Understand the target before touching code: read source, identify the bottleneck, verify prerequisites and benchmark inputs.
30
- 2. Update goal, scope, or constraints via another `init_experiment` call (no segment bump) or `update_notes`. Bump segment when you intentionally change `autoresearch.sh`.
31
- 3. Establish a baseline first.
32
- 4. Iterate: change code, run `run_experiment`, log honestly with `log_experiment`. One coherent experiment per iteration.
33
- 5. Keep the primary metric as the decision maker:
34
- - `keep` when it improves;
35
- - `discard` when it regresses or stays flat;
36
- - `crash` when the run fails;
37
- - `checks_failed` when validation fails (you decide what validation means; run it through the regular `bash` tool).
38
- 6. Use ASI freely — it is opaque, just stash useful learnings (`hypothesis`, `rollback_reason`, `next_action_hint`, anything else).
39
- 7. When confidence is low, re-run promising changes before keeping them. `log_experiment` reports a confidence score (multiples of the observed noise floor) on each kept run.
40
-
41
- ### Scope, off-limits, and accountability
42
- - Edits are not blocked. You can change anything.
43
- - `log_experiment` records the modified paths. Files outside `scope_paths` or inside `off_limits` are recorded as `scope_deviations` on the run.
44
- - If you keep a run with deviations, pass `justification` explaining why. Without it, the run logs but is flagged in the next iteration's prompt as unjustified.
45
- - If a previous run looks reward-hacked or otherwise wrong, pass `flag_runs: [{ run_id, reason }]` on the next `log_experiment` to exclude it from baseline and best-metric calculations.
46
-
47
- {{#if has_notes}}
48
- ### Your notes (use `update_notes` to edit)
49
-
50
- {{notes}}
51
-
52
- {{/if}}
53
- {{#if has_recent_results}}
54
- ### Current segment snapshot
55
- - segment: `{{current_segment}}`
56
- - runs in current segment: `{{current_segment_run_count}}`
57
- {{#if has_baseline_metric}}
58
- - baseline `{{metric_name}}`: `{{baseline_metric_display}}`
59
- {{/if}}
60
- {{#if has_best_result}}
61
- - best kept `{{metric_name}}`: `{{best_metric_display}}`{{#if best_run_number}} from run `#{{best_run_number}}`{{/if}}
62
- {{/if}}
63
-
64
- Recent runs:
65
- {{#each recent_results}}
66
- - run `#{{run_number}}`: `{{status}}` `{{metric_display}}` — {{description}}
67
- {{#if has_asi_summary}}
68
- ASI: {{asi_summary}}
69
- {{/if}}
70
- {{#if has_deviations}}
71
- Modified outside scope: {{deviations}}{{#unless justified}} (no justification){{/unless}}
72
- {{/if}}
73
- {{#if flagged}}
74
- FLAGGED: {{flagged_reason}}
75
- {{/if}}
76
- {{/each}}
77
- {{/if}}
78
- {{#if has_unjustified_runs}}
79
-
80
- ### Unjustified deviations
81
- {{#each unjustified_runs}}
82
- - run `#{{run_number}}` modified `{{paths}}` outside scope without justification. Either accept it, justify it on the next log, or `flag_runs` it.
83
- {{/each}}
84
- {{/if}}
85
- {{#if has_pending_run}}
86
-
87
- ### Pending run
88
- An unlogged run is waiting:
89
- - run: `#{{pending_run_number}}`
90
- - command: `{{pending_run_command}}`
91
- {{#if has_pending_run_metric}}
92
- - parsed `{{metric_name}}`: `{{pending_run_metric_display}}`
93
- {{/if}}
94
- - result: {{#if pending_run_passed}}passed{{else}}failed{{/if}}
95
-
96
- Finish the `log_experiment` step before starting another benchmark.
97
- {{/if}}
98
-
99
- ### Guardrails
100
- - Do not game the benchmark.
101
- - Do not overfit to synthetic inputs if the real workload is broader.
102
- - Preserve correctness.
103
- - If the user sends another message while a run is in progress, finish the current run and logging cycle first, then address the new input in the next iteration.
@@ -1,10 +0,0 @@
1
- Continue the autoresearch loop now.
2
-
3
- - Re-read your notes and the recent-runs context above before deciding the next direction.
4
- - Inspect recent git history for context.
5
- {{#if has_pending_run}}
6
- - A previous benchmark run completed but was never logged. Finish `log_experiment` before starting a new run.
7
- {{/if}}
8
- - Continue from the most promising unfinished direction.
9
- - Keep iterating until interrupted or until the configured iteration cap is reached.
10
- - Preserve correctness and do not game the benchmark.