@tea-agent/loop-agent 0.1.0-fe-test.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 (1050) hide show
  1. package/AGENTS.md +114 -0
  2. package/CHANGELOG.md +2283 -0
  3. package/README.md +177 -0
  4. package/bin/agent-worker.js +22 -0
  5. package/bin/loop-agent.js +57 -0
  6. package/dist/adapters/aimax.js +91 -0
  7. package/dist/adapters/context.js +32 -0
  8. package/dist/adapters/index.js +29 -0
  9. package/dist/adapters/loop-agent.js +192 -0
  10. package/dist/adapters/types.js +1 -0
  11. package/dist/application/context-usage/skill-resolution-stats.js +263 -0
  12. package/dist/application/dag/args.js +486 -0
  13. package/dist/application/dag/generate-task-dag.js +408 -0
  14. package/dist/application/dag/report-dag.js +14 -0
  15. package/dist/application/dag/run-dag.js +109 -0
  16. package/dist/application/dag/validate-dag.js +166 -0
  17. package/dist/application/evaluation/alias.js +184 -0
  18. package/dist/application/evaluation/budget.js +192 -0
  19. package/dist/application/evaluation/campaign-hash.js +47 -0
  20. package/dist/application/evaluation/campaign-matrix.js +372 -0
  21. package/dist/application/evaluation/campaign-scorecard.js +135 -0
  22. package/dist/application/evaluation/campaign.js +370 -0
  23. package/dist/application/evaluation/candidate-hash.js +75 -0
  24. package/dist/application/evaluation/candidate.js +69 -0
  25. package/dist/application/evaluation/corpus-hash.js +38 -0
  26. package/dist/application/evaluation/corpus.js +56 -0
  27. package/dist/application/evaluation/experiment.js +294 -0
  28. package/dist/application/evaluation/ignition.js +198 -0
  29. package/dist/application/evaluation/integrity-audit.js +162 -0
  30. package/dist/application/evaluation/outer-loop.js +132 -0
  31. package/dist/application/evaluation/pi-cell-executor.js +39 -0
  32. package/dist/application/evaluation/private-verifier.js +46 -0
  33. package/dist/application/evaluation/promotion-policy.js +151 -0
  34. package/dist/application/evaluation/proposer.js +98 -0
  35. package/dist/application/evaluation/replay.js +289 -0
  36. package/dist/application/evaluation/types.js +652 -0
  37. package/dist/application/loop/run-action.js +19 -0
  38. package/dist/application/task-lifecycle/advance.js +1204 -0
  39. package/dist/application/task-lifecycle/gates.js +130 -0
  40. package/dist/application/task-lifecycle/index.js +7 -0
  41. package/dist/application/task-lifecycle/observe.js +424 -0
  42. package/dist/application/task-lifecycle/plan-transitions.js +251 -0
  43. package/dist/application/task-lifecycle/recommendations.js +180 -0
  44. package/dist/application/task-lifecycle/record.js +73 -0
  45. package/dist/application/task-lifecycle/types.js +1 -0
  46. package/dist/build-stamp.json +6 -0
  47. package/dist/cli/catalog.js +24 -0
  48. package/dist/cli/command-definitions.js +659 -0
  49. package/dist/cli/help.js +56 -0
  50. package/dist/cli/index.js +5 -0
  51. package/dist/cli/program.js +647 -0
  52. package/dist/cli/router.js +13 -0
  53. package/dist/cli/update/init-surface-notifier.js +167 -0
  54. package/dist/cli/update/notifier.js +117 -0
  55. package/dist/cli/update/npm-client.js +151 -0
  56. package/dist/cli/update/policy.js +92 -0
  57. package/dist/cli/update/runtime-activity.js +29 -0
  58. package/dist/cli/update/state.js +68 -0
  59. package/dist/cli-governance/active-residue-check.js +38 -0
  60. package/dist/cli.js +57 -0
  61. package/dist/commands/client-recovery.js +1373 -0
  62. package/dist/commands/closeout.js +13 -0
  63. package/dist/commands/coverage-audit.js +14 -0
  64. package/dist/commands/coverage-report.js +50 -0
  65. package/dist/commands/cursor-prompt.js +182 -0
  66. package/dist/commands/dag-approve.js +142 -0
  67. package/dist/commands/dag-final-verification.js +76 -0
  68. package/dist/commands/dag-init-hybrid.js +57 -0
  69. package/dist/commands/dag-reconcile-run.js +5 -0
  70. package/dist/commands/dag-reconcile-tasks.js +51 -0
  71. package/dist/commands/dag-reject.js +91 -0
  72. package/dist/commands/dag-report.js +76 -0
  73. package/dist/commands/dag-request-interrupt.js +20 -0
  74. package/dist/commands/dag-rerun-task.js +19 -0
  75. package/dist/commands/dag-rerun.js +111 -0
  76. package/dist/commands/dag-resume.js +35 -0
  77. package/dist/commands/dag-run-task.js +12 -0
  78. package/dist/commands/dag-validate.js +20 -0
  79. package/dist/commands/dag-workflow-compile.js +91 -0
  80. package/dist/commands/dag-workflow-plan.js +130 -0
  81. package/dist/commands/dag-workflow-validate.js +66 -0
  82. package/dist/commands/delegate.js +130 -0
  83. package/dist/commands/docs-archive.js +5 -0
  84. package/dist/commands/docs-audit.js +6 -0
  85. package/dist/commands/doctor.js +283 -0
  86. package/dist/commands/eval.js +1398 -0
  87. package/dist/commands/examples.js +90 -0
  88. package/dist/commands/goal.js +92 -0
  89. package/dist/commands/handoff-check.js +5 -0
  90. package/dist/commands/harvest.js +44 -0
  91. package/dist/commands/import-prd.js +81 -0
  92. package/dist/commands/init-upgrade.js +3085 -0
  93. package/dist/commands/init.js +3630 -0
  94. package/dist/commands/inspect.js +11 -0
  95. package/dist/commands/instructions.js +223 -0
  96. package/dist/commands/knowledge.js +162 -0
  97. package/dist/commands/loop-benchmark.js +72 -0
  98. package/dist/commands/loop.js +251 -0
  99. package/dist/commands/new-task.js +5 -0
  100. package/dist/commands/operator.js +44 -0
  101. package/dist/commands/pi-prompt.js +174 -0
  102. package/dist/commands/pi-reuse-benchmark.js +153 -0
  103. package/dist/commands/plan-list.js +5 -0
  104. package/dist/commands/plan.js +50 -0
  105. package/dist/commands/promote-run.js +29 -0
  106. package/dist/commands/reference-index.js +16 -0
  107. package/dist/commands/run-dag-progress.js +123 -0
  108. package/dist/commands/run-dag.js +22 -0
  109. package/dist/commands/spine.js +38 -0
  110. package/dist/commands/stats.js +113 -0
  111. package/dist/commands/status.js +57 -0
  112. package/dist/commands/study-init.js +192 -0
  113. package/dist/commands/task-advance.js +366 -0
  114. package/dist/commands/task-contract.js +269 -0
  115. package/dist/commands/task-source-prepare.js +479 -0
  116. package/dist/commands/task-status.js +133 -0
  117. package/dist/commands/workflow.js +259 -0
  118. package/dist/commands/worktree-create.js +31 -0
  119. package/dist/commands/worktree-list.js +5 -0
  120. package/dist/commands/worktree-remove.js +26 -0
  121. package/dist/executors/config-core.js +5 -0
  122. package/dist/executors/config.js +2 -0
  123. package/dist/executors/dag-pi-executor.js +1277 -0
  124. package/dist/executors/dag-static-executor.js +42 -0
  125. package/dist/executors/dag.js +3 -0
  126. package/dist/executors/index.js +6 -0
  127. package/dist/executors/model-routing.js +71 -0
  128. package/dist/executors/pi-defaults.js +9 -0
  129. package/dist/executors/pi-event-serializer.js +65 -0
  130. package/dist/executors/pi-executor.js +981 -0
  131. package/dist/executors/pi-playwright-cli-tool.js +1006 -0
  132. package/dist/executors/pi-prompt-transport.js +198 -0
  133. package/dist/executors/pi-reuse-benchmark.js +316 -0
  134. package/dist/executors/pi-runtime-reuse.js +29 -0
  135. package/dist/executors/pi-sdk-executor.js +722 -0
  136. package/dist/executors/pi-sdk.js +1 -0
  137. package/dist/executors/pi-writer-tool-policy.js +266 -0
  138. package/dist/executors/pi.js +3 -0
  139. package/dist/executors/playwright-cli-launcher.js +63 -0
  140. package/dist/executors/process-tree.js +33 -0
  141. package/dist/executors/shell-executor.js +3055 -0
  142. package/dist/executors/shell-presets.js +99 -0
  143. package/dist/executors/shell-verification.js +262 -0
  144. package/dist/executors/shell-write-guard.js +543 -0
  145. package/dist/executors/shell.js +3 -0
  146. package/dist/executors/static.js +1 -0
  147. package/dist/governance/checks.js +437 -0
  148. package/dist/governance/document-index-closure.js +164 -0
  149. package/dist/governance/exec-plans.js +549 -0
  150. package/dist/governance/harness.js +9 -0
  151. package/dist/governance/index.js +3 -0
  152. package/dist/governance/manifest-types.js +254 -0
  153. package/dist/governance/manifest.js +2 -0
  154. package/dist/governance/path-guard.js +69 -0
  155. package/dist/governance/path-guards.js +2 -0
  156. package/dist/governance/profiles.js +3 -0
  157. package/dist/governance/requirement-coverage.js +425 -0
  158. package/dist/governance/skill-safety.js +135 -0
  159. package/dist/governance/spine-audit.js +155 -0
  160. package/dist/infrastructure/evaluation/alias-store.js +199 -0
  161. package/dist/infrastructure/evaluation/campaign-store.js +154 -0
  162. package/dist/infrastructure/evaluation/candidate-store.js +439 -0
  163. package/dist/infrastructure/evaluation/corpus-store.js +181 -0
  164. package/dist/infrastructure/evaluation/experiment-store.js +124 -0
  165. package/dist/infrastructure/evaluation/ignition-store.js +82 -0
  166. package/dist/infrastructure/evaluation/private-verifier-store.js +145 -0
  167. package/dist/infrastructure/evaluation/proposer-store.js +78 -0
  168. package/dist/infrastructure/evaluation/store.js +40 -0
  169. package/dist/infrastructure/harness/active-residue-policy.js +73 -0
  170. package/dist/infrastructure/harness/artifact-store.js +72 -0
  171. package/dist/infrastructure/harness/atomic-write.js +50 -0
  172. package/dist/infrastructure/harness/completed-facts-guard.js +40 -0
  173. package/dist/infrastructure/harness/loop-action-store.js +20 -0
  174. package/dist/infrastructure/harness/loop-store.js +41 -0
  175. package/dist/infrastructure/harness/one-shot-run-store.js +94 -0
  176. package/dist/infrastructure/harness/task-store.js +108 -0
  177. package/dist/records/closeout.js +2 -0
  178. package/dist/records/harvest.js +215 -0
  179. package/dist/records/index.js +3 -0
  180. package/dist/records/one-shot-runs.js +386 -0
  181. package/dist/records/promotion.js +200 -0
  182. package/dist/shared/artifacts-core.js +107 -0
  183. package/dist/shared/artifacts.js +2 -0
  184. package/dist/shared/context-files.js +32 -0
  185. package/dist/shared/context.js +2 -0
  186. package/dist/shared/copy-dir.js +17 -0
  187. package/dist/shared/git-progress.js +172 -0
  188. package/dist/shared/index.js +5 -0
  189. package/dist/shared/logger.js +17 -0
  190. package/dist/shared/one-shot-prompt-args.js +98 -0
  191. package/dist/shared/openspec-spec.js +125 -0
  192. package/dist/shared/operator/capabilities.js +2659 -0
  193. package/dist/shared/operator/command-lifecycle.js +94 -0
  194. package/dist/shared/operator/envelope.js +59 -0
  195. package/dist/shared/operator/index.js +5 -0
  196. package/dist/shared/operator/registry.js +38 -0
  197. package/dist/shared/operator/types.js +5 -0
  198. package/dist/shared/output-truncation.js +37 -0
  199. package/dist/shared/package-metadata.js +530 -0
  200. package/dist/shared/path-refs.js +31 -0
  201. package/dist/shared/pi-retry-settings.js +23 -0
  202. package/dist/shared/playwright-cli-command-policy.js +41 -0
  203. package/dist/shared/preview.js +39 -0
  204. package/dist/shared/prompts.js +26 -0
  205. package/dist/shared/reference-context.js +264 -0
  206. package/dist/shared/resilient-git.js +133 -0
  207. package/dist/shared/runtime-activity.js +6 -0
  208. package/dist/shared/timeout-policy.js +24 -0
  209. package/dist/shared/timeout.js +1 -0
  210. package/dist/shared/types.js +5 -0
  211. package/dist/sidecars/cursor-prompt/executor.js +428 -0
  212. package/dist/sidecars/cursor-prompt/index.js +3 -0
  213. package/dist/sidecars/cursor-prompt/stream.js +121 -0
  214. package/dist/task/config-types.js +235 -0
  215. package/dist/task/config.js +2 -0
  216. package/dist/task/contract/adopt.js +166 -0
  217. package/dist/task/contract/apply.js +326 -0
  218. package/dist/task/contract/canonicalize.js +60 -0
  219. package/dist/task/contract/constants.js +30 -0
  220. package/dist/task/contract/diff.js +177 -0
  221. package/dist/task/contract/hash.js +42 -0
  222. package/dist/task/contract/import-revision.js +96 -0
  223. package/dist/task/contract/index.js +17 -0
  224. package/dist/task/contract/journal.js +155 -0
  225. package/dist/task/contract/lock.js +153 -0
  226. package/dist/task/contract/observe.js +296 -0
  227. package/dist/task/contract/paths.js +19 -0
  228. package/dist/task/contract/project.js +185 -0
  229. package/dist/task/contract/recover.js +312 -0
  230. package/dist/task/contract/request-ledger.js +37 -0
  231. package/dist/task/contract/schema.js +153 -0
  232. package/dist/task/contract/transaction.js +160 -0
  233. package/dist/task/contract/types.js +1 -0
  234. package/dist/task/contract/validate-draft.js +106 -0
  235. package/dist/task/dag-source-paths.js +50 -0
  236. package/dist/task/delegate.js +208 -0
  237. package/dist/task/frontend-preflight.js +131 -0
  238. package/dist/task/frontend-project-capability.js +570 -0
  239. package/dist/task/goal-audit.js +51 -0
  240. package/dist/task/goal-policy.js +8 -0
  241. package/dist/task/goal.js +3 -0
  242. package/dist/task/ids.js +1 -0
  243. package/dist/task/index.js +12 -0
  244. package/dist/task/lifecycle.js +1 -0
  245. package/dist/task/operator/capabilities.js +6 -0
  246. package/dist/task/operator/envelope.js +2 -0
  247. package/dist/task/operator/index.js +5 -0
  248. package/dist/task/operator/registry.js +2 -0
  249. package/dist/task/operator/types.js +1 -0
  250. package/dist/task/paths.js +1 -0
  251. package/dist/task/read-model.js +140 -0
  252. package/dist/task/runtime.js +708 -0
  253. package/dist/task/source-prepare/artifact-meta.js +137 -0
  254. package/dist/task/source-prepare/build-draft.js +232 -0
  255. package/dist/task/source-prepare/completeness.js +248 -0
  256. package/dist/task/source-prepare/index.js +10 -0
  257. package/dist/task/source-prepare/parse-intent.js +496 -0
  258. package/dist/task/source-prepare/path-policy.js +197 -0
  259. package/dist/task/source-prepare/placeholder-paths.js +77 -0
  260. package/dist/task/source-prepare/prepare.js +920 -0
  261. package/dist/task/source-prepare/reference-integrity.js +290 -0
  262. package/dist/task/source-prepare/semantic-intake.js +717 -0
  263. package/dist/task/source-prepare/types.js +7 -0
  264. package/dist/task/source-references.js +228 -0
  265. package/dist/task/source-state.js +1 -0
  266. package/dist/task/state.js +41 -0
  267. package/dist/task/subagent-guidance.js +1 -0
  268. package/dist/task/task-demand-routing.js +443 -0
  269. package/dist/task/workflow-state-types.js +92 -0
  270. package/dist/task/worktree-cleanup.js +140 -0
  271. package/dist/task/worktree.js +388 -0
  272. package/dist/verification/maven/cache.js +142 -0
  273. package/dist/verification/maven/index.js +120 -0
  274. package/dist/verification/maven/plan-commands.js +421 -0
  275. package/dist/verification/maven/pom-static.js +136 -0
  276. package/dist/verification/maven/scope-resolve.js +153 -0
  277. package/dist/verification/maven/stale.js +130 -0
  278. package/dist/verification/maven/types.js +23 -0
  279. package/dist/verification/maven/workspace-graph.js +322 -0
  280. package/dist/worker/cli.js +957 -0
  281. package/dist/worker/closeout/apply.js +73 -0
  282. package/dist/worker/closeout/preview.js +30 -0
  283. package/dist/worker/console/app-data.js +316 -0
  284. package/dist/worker/console/chat/artifact-card.js +30 -0
  285. package/dist/worker/console/chat/assistant-content.js +121 -0
  286. package/dist/worker/console/chat/chat-event-store.js +981 -0
  287. package/dist/worker/console/chat/chat-ui-policy.js +25 -0
  288. package/dist/worker/console/chat/compaction-errors.js +64 -0
  289. package/dist/worker/console/chat/composer-draft-store.js +45 -0
  290. package/dist/worker/console/chat/context-panel.js +54 -0
  291. package/dist/worker/console/chat/contract-apply-receipt-store.js +174 -0
  292. package/dist/worker/console/chat/explore-tools.js +299 -0
  293. package/dist/worker/console/chat/human-gate-card.js +45 -0
  294. package/dist/worker/console/chat/interview-adapter.js +149 -0
  295. package/dist/worker/console/chat/mcp-inventory.js +221 -0
  296. package/dist/worker/console/chat/model-resolver.js +215 -0
  297. package/dist/worker/console/chat/operation-card.js +92 -0
  298. package/dist/worker/console/chat/pi-console-config.js +376 -0
  299. package/dist/worker/console/chat/pi-runtime.js +2446 -0
  300. package/dist/worker/console/chat/repo-browser.js +140 -0
  301. package/dist/worker/console/chat/repo-walk.js +125 -0
  302. package/dist/worker/console/chat/resource-loader.js +59 -0
  303. package/dist/worker/console/chat/resource-preferences-store.js +152 -0
  304. package/dist/worker/console/chat/routes.js +3137 -0
  305. package/dist/worker/console/chat/runtime-context.js +102 -0
  306. package/dist/worker/console/chat/runtime-selection.js +96 -0
  307. package/dist/worker/console/chat/semantic-activity.js +489 -0
  308. package/dist/worker/console/chat/session-store.js +484 -0
  309. package/dist/worker/console/chat/shortcuts.js +217 -0
  310. package/dist/worker/console/chat/tool-adapter.js +131 -0
  311. package/dist/worker/console/chat/tool-preview.js +247 -0
  312. package/dist/worker/console/chat/tools.js +212 -0
  313. package/dist/worker/console/chat/turn-execution-registry.js +82 -0
  314. package/dist/worker/console/chat/turn-process.js +346 -0
  315. package/dist/worker/console/chat/usage.js +165 -0
  316. package/dist/worker/console/chat/workspace-landing.js +103 -0
  317. package/dist/worker/console/dag-confirmation.js +347 -0
  318. package/dist/worker/console/dag-execution-receipt.js +393 -0
  319. package/dist/worker/console/doctor.js +230 -0
  320. package/dist/worker/console/draft-store.js +158 -0
  321. package/dist/worker/console/harness-pi-model-matrix.js +137 -0
  322. package/dist/worker/console/human-gate-token.js +130 -0
  323. package/dist/worker/console/index.js +17 -0
  324. package/dist/worker/console/inspect-split.js +82 -0
  325. package/dist/worker/console/interview/assessment.js +67 -0
  326. package/dist/worker/console/interview/grill-me.js +277 -0
  327. package/dist/worker/console/interview/session.js +100 -0
  328. package/dist/worker/console/interview/tools.js +109 -0
  329. package/dist/worker/console/loopback.js +16 -0
  330. package/dist/worker/console/mutation-gate-receipt-store.js +184 -0
  331. package/dist/worker/console/night-aux-ticker.js +146 -0
  332. package/dist/worker/console/observe-health-match.js +179 -0
  333. package/dist/worker/console/observe-link.js +42 -0
  334. package/dist/worker/console/open-browser.js +134 -0
  335. package/dist/worker/console/operation-run-facts.js +190 -0
  336. package/dist/worker/console/operation-runner.js +353 -0
  337. package/dist/worker/console/operation-sse.js +184 -0
  338. package/dist/worker/console/operation-store.js +169 -0
  339. package/dist/worker/console/operation-wait.js +355 -0
  340. package/dist/worker/console/operator-actions.js +3768 -0
  341. package/dist/worker/console/operator-selection.js +105 -0
  342. package/dist/worker/console/operator-surface-health.js +24 -0
  343. package/dist/worker/console/operator-user-error.js +45 -0
  344. package/dist/worker/console/pi-readiness.js +288 -0
  345. package/dist/worker/console/prd-identity.js +102 -0
  346. package/dist/worker/console/prd-intake-bridge.js +441 -0
  347. package/dist/worker/console/prd-reference-discovery.js +124 -0
  348. package/dist/worker/console/recovery-cta.js +320 -0
  349. package/dist/worker/console/recovery-error-copy.js +198 -0
  350. package/dist/worker/console/recovery-selection.js +107 -0
  351. package/dist/worker/console/repo-fingerprint.js +35 -0
  352. package/dist/worker/console/resolve-dag-run-for-task.js +115 -0
  353. package/dist/worker/console/resource-loader.js +95 -0
  354. package/dist/worker/console/routes.js +475 -0
  355. package/dist/worker/console/security.js +170 -0
  356. package/dist/worker/console/server.js +357 -0
  357. package/dist/worker/console/sibling-controller.js +33 -0
  358. package/dist/worker/console/static/assets/abnfDiagram-N423BO3Z-BmOEx0gA.js +1 -0
  359. package/dist/worker/console/static/assets/arc-BGiVVe8b.js +1 -0
  360. package/dist/worker/console/static/assets/architectureDiagram-T3A2C74G-nDdu4rgJ.js +36 -0
  361. package/dist/worker/console/static/assets/blockDiagram-VBNYF7ZC-Bb5u0BWf.js +132 -0
  362. package/dist/worker/console/static/assets/c4Diagram-5PPSVZJV-BlhC0j94.js +10 -0
  363. package/dist/worker/console/static/assets/channel-Tl-FkUqr.js +1 -0
  364. package/dist/worker/console/static/assets/chunk-2GRJ4B5K-Ai8_qQXI.js +1 -0
  365. package/dist/worker/console/static/assets/chunk-2Q5K7J3B-B9gyCjqX.js +1 -0
  366. package/dist/worker/console/static/assets/chunk-5RXB4S5H-Bzbj3zGH.js +231 -0
  367. package/dist/worker/console/static/assets/chunk-5VM5RSS4-BT415PvT.js +15 -0
  368. package/dist/worker/console/static/assets/chunk-6Q2QTUOP-D_A5_5QL.js +88 -0
  369. package/dist/worker/console/static/assets/chunk-GF5L2VYU-srJkaP3f.js +206 -0
  370. package/dist/worker/console/static/assets/chunk-JWPE2WC7-UYGvEP4l.js +1 -0
  371. package/dist/worker/console/static/assets/chunk-KBJHAD2P-B8luBrrz.js +1 -0
  372. package/dist/worker/console/static/assets/chunk-RYQCIY6F-DN7wXZSq.js +1 -0
  373. package/dist/worker/console/static/assets/chunk-XXDRQBXY-DXKyMuKS.js +1 -0
  374. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BaehtRk4.js +1 -0
  375. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BaehtRk4.js +1 -0
  376. package/dist/worker/console/static/assets/cose-bilkent-JH36ORCC-dqvoynXj.js +1 -0
  377. package/dist/worker/console/static/assets/cynefin-VYW2F7L2--PcyL34A.js +166 -0
  378. package/dist/worker/console/static/assets/cynefinDiagram-MW4NZA55-DvWs_hTY.js +62 -0
  379. package/dist/worker/console/static/assets/cytoscape.esm-yzknjiTM.js +321 -0
  380. package/dist/worker/console/static/assets/dagre-VZM6K2ZE-DxeIxbyO.js +4 -0
  381. package/dist/worker/console/static/assets/defaultLocale-DX6XiGOO.js +1 -0
  382. package/dist/worker/console/static/assets/diagram-7IWD3JNH-DPCG61Of.js +30 -0
  383. package/dist/worker/console/static/assets/diagram-B4RE2ZJO-CmuU50-U.js +3 -0
  384. package/dist/worker/console/static/assets/diagram-LBJQPF4R-B61XLD_v.js +24 -0
  385. package/dist/worker/console/static/assets/diagram-Q27KOJAE-BB7HTRRY.js +24 -0
  386. package/dist/worker/console/static/assets/diagram-UB23O5K3-DvkboAIp.js +41 -0
  387. package/dist/worker/console/static/assets/ebnfDiagram-BXEA7PRR-BdJ_y1fL.js +1 -0
  388. package/dist/worker/console/static/assets/erDiagram-JOGREHBK-9bUBZTRi.js +85 -0
  389. package/dist/worker/console/static/assets/flowDiagram-UKHOOZJN-Dw4L4RBa.js +156 -0
  390. package/dist/worker/console/static/assets/ganttDiagram-PKOTCBZU-Jr82N_QP.js +292 -0
  391. package/dist/worker/console/static/assets/gitGraphDiagram-DS77QQ5N-DAz9wFLr.js +106 -0
  392. package/dist/worker/console/static/assets/graph-DOmOIIwC.js +1 -0
  393. package/dist/worker/console/static/assets/index-B7Y-0g3J.css +1 -0
  394. package/dist/worker/console/static/assets/index-DkCrqaYg.js +325 -0
  395. package/dist/worker/console/static/assets/infoDiagram-6WML65LV-CBB5Np7y.js +2 -0
  396. package/dist/worker/console/static/assets/init-Gi6I4Gst.js +1 -0
  397. package/dist/worker/console/static/assets/ishikawaDiagram-WSZJBQD7-D8IOp94y.js +70 -0
  398. package/dist/worker/console/static/assets/journeyDiagram-NVQOT4AX-Dgd3AHGG.js +139 -0
  399. package/dist/worker/console/static/assets/kanban-definition-27J2QSJJ-BmYOxLE9.js +89 -0
  400. package/dist/worker/console/static/assets/layout-D-LzfAck.js +1 -0
  401. package/dist/worker/console/static/assets/linear-DfYTEF6J.js +1 -0
  402. package/dist/worker/console/static/assets/map-DxJ2ADlA.js +1 -0
  403. package/dist/worker/console/static/assets/mermaid.core-BjuFPRqa.js +308 -0
  404. package/dist/worker/console/static/assets/mindmap-definition-FAOFIHXS-CLyUViGd.js +96 -0
  405. package/dist/worker/console/static/assets/ordinal-Cboi1Yqb.js +1 -0
  406. package/dist/worker/console/static/assets/pegDiagram-VL7TDLO6-BvX2Di4-.js +1 -0
  407. package/dist/worker/console/static/assets/pieDiagram-7S7Q4E2Y-BFj0_OLv.js +39 -0
  408. package/dist/worker/console/static/assets/quadrantDiagram-CIZ2JOQS-BIUrD_hx.js +7 -0
  409. package/dist/worker/console/static/assets/railroadDiagram-AXF67PYL-CHBB48fj.js +1 -0
  410. package/dist/worker/console/static/assets/requirementDiagram-LRYGKXZP-sJrYw2Sf.js +84 -0
  411. package/dist/worker/console/static/assets/sankeyDiagram-W5VNT64P-BzHH6fPR.js +40 -0
  412. package/dist/worker/console/static/assets/sequenceDiagram-SI44F4Z6-7QCnelCt.js +162 -0
  413. package/dist/worker/console/static/assets/sizeCapture-X5ZJPWSS-sDYSxn72.js +1 -0
  414. package/dist/worker/console/static/assets/stateDiagram-OKZ733FA-XpiUdwzm.js +1 -0
  415. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-eEhq2A8Y.js +1 -0
  416. package/dist/worker/console/static/assets/swimlanes-SLNWSIFB-DvqgNPzD.js +2 -0
  417. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-la8AC7fo.js +8 -0
  418. package/dist/worker/console/static/assets/timeline-definition-Z64GVDOM-2TyOYNx0.js +120 -0
  419. package/dist/worker/console/static/assets/vennDiagram-T6HMQDX7-B-nM6wM2.js +34 -0
  420. package/dist/worker/console/static/assets/wardleyDiagram-T6FBY63Y-B86wPdbr.js +78 -0
  421. package/dist/worker/console/static/assets/xychartDiagram-ELKLHX3M-Dr1C4AQz.js +7 -0
  422. package/dist/worker/console/static/favicon.svg +37 -0
  423. package/dist/worker/console/static/fonts/katex/KaTeX_AMS-Regular.woff2 +0 -0
  424. package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Bold.woff2 +0 -0
  425. package/dist/worker/console/static/fonts/katex/KaTeX_Caligraphic-Regular.woff2 +0 -0
  426. package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Bold.woff2 +0 -0
  427. package/dist/worker/console/static/fonts/katex/KaTeX_Fraktur-Regular.woff2 +0 -0
  428. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Bold.woff2 +0 -0
  429. package/dist/worker/console/static/fonts/katex/KaTeX_Main-BoldItalic.woff2 +0 -0
  430. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Italic.woff2 +0 -0
  431. package/dist/worker/console/static/fonts/katex/KaTeX_Main-Regular.woff2 +0 -0
  432. package/dist/worker/console/static/fonts/katex/KaTeX_Math-BoldItalic.woff2 +0 -0
  433. package/dist/worker/console/static/fonts/katex/KaTeX_Math-Italic.woff2 +0 -0
  434. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Bold.woff2 +0 -0
  435. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Italic.woff2 +0 -0
  436. package/dist/worker/console/static/fonts/katex/KaTeX_SansSerif-Regular.woff2 +0 -0
  437. package/dist/worker/console/static/fonts/katex/KaTeX_Script-Regular.woff2 +0 -0
  438. package/dist/worker/console/static/fonts/katex/KaTeX_Size1-Regular.woff2 +0 -0
  439. package/dist/worker/console/static/fonts/katex/KaTeX_Size2-Regular.woff2 +0 -0
  440. package/dist/worker/console/static/fonts/katex/KaTeX_Size3-Regular.woff2 +0 -0
  441. package/dist/worker/console/static/fonts/katex/KaTeX_Size4-Regular.woff2 +0 -0
  442. package/dist/worker/console/static/fonts/katex/KaTeX_Typewriter-Regular.woff2 +0 -0
  443. package/dist/worker/console/static/index.html +15 -0
  444. package/dist/worker/console/static-src/app/console-types.js +184 -0
  445. package/dist/worker/console/static-src/app/useConsoleShell.js +101 -0
  446. package/dist/worker/console/static-src/app/useOperatorActions.js +324 -0
  447. package/dist/worker/console/static-src/app/usePrdImport.js +172 -0
  448. package/dist/worker/console/static-src/app/useRecoveryActions.js +289 -0
  449. package/dist/worker/console/static-src/app/useRecoveryConsole.js +425 -0
  450. package/dist/worker/console/static-src/app/useTaskWizard.js +296 -0
  451. package/dist/worker/console/static-src/chat-markdown-security.js +38 -0
  452. package/dist/worker/console/static-src/chat-view-types.js +2 -0
  453. package/dist/worker/console/static-src/night/night-types.js +24 -0
  454. package/dist/worker/console/static-src/night/useNightBoard.js +94 -0
  455. package/dist/worker/console/static-src/night/useNightWizard.js +171 -0
  456. package/dist/worker/console/static-src/night-prepare-result.js +118 -0
  457. package/dist/worker/console/static-src/operator-chat/activity-journey.js +125 -0
  458. package/dist/worker/console/static-src/operator-chat/activity-rail-presentation.js +73 -0
  459. package/dist/worker/console/static-src/operator-chat/activity-references.js +20 -0
  460. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +420 -0
  461. package/dist/worker/console/static-src/operator-chat/format.js +71 -0
  462. package/dist/worker/console/static-src/operator-chat/landing-density.js +23 -0
  463. package/dist/worker/console/static-src/operator-chat/mutation-gate.js +45 -0
  464. package/dist/worker/console/static-src/operator-chat/refs.js +86 -0
  465. package/dist/worker/console/static-src/operator-chat/resource-auto-invocation.js +91 -0
  466. package/dist/worker/console/static-src/operator-chat/resource-diagnostics.js +204 -0
  467. package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +257 -0
  468. package/dist/worker/console/static-src/operator-chat/session-title-watcher.js +128 -0
  469. package/dist/worker/console/static-src/operator-chat/sidebar-split.js +90 -0
  470. package/dist/worker/console/static-src/operator-chat/slash-palette-layout.js +24 -0
  471. package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +141 -0
  472. package/dist/worker/console/static-src/operator-chat/spatial-overlay.js +38 -0
  473. package/dist/worker/console/static-src/operator-chat/tools-catalog.js +77 -0
  474. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +690 -0
  475. package/dist/worker/console/static-src/operator-chat/turn-submission.js +158 -0
  476. package/dist/worker/console/static-src/operator-chat/types.js +1 -0
  477. package/dist/worker/console/static-src/operator-chat/useActivityRailTransition.js +59 -0
  478. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +495 -0
  479. package/dist/worker/console/static-src/operator-chat/useChatStream.js +780 -0
  480. package/dist/worker/console/static-src/operator-chat/useChatThread.js +280 -0
  481. package/dist/worker/console/static-src/operator-chat/useComposer.js +257 -0
  482. package/dist/worker/console/static-src/operator-chat/useInterview.js +108 -0
  483. package/dist/worker/console/static-src/operator-chat/useOverlayFocus.js +84 -0
  484. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +148 -0
  485. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +358 -0
  486. package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +196 -0
  487. package/dist/worker/console/static-src/operator-chat/useWorkspaceLayout.js +58 -0
  488. package/dist/worker/console/static-src/operator-chat/workspace-layout-mode.js +35 -0
  489. package/dist/worker/console/static-src/prd-file-import.js +218 -0
  490. package/dist/worker/console/vite.config.js +27 -0
  491. package/dist/worker/console/workflow-kinds.js +46 -0
  492. package/dist/worker/delivery/final-verification.js +302 -0
  493. package/dist/worker/delivery/git-transaction.js +497 -0
  494. package/dist/worker/delivery/package.js +537 -0
  495. package/dist/worker/delivery/verification-bundle.js +544 -0
  496. package/dist/worker/feature/acceptance-policy.js +227 -0
  497. package/dist/worker/feature/advance.js +301 -0
  498. package/dist/worker/feature/decision-loader.js +99 -0
  499. package/dist/worker/feature/discover.js +14 -0
  500. package/dist/worker/feature/doctor.js +223 -0
  501. package/dist/worker/feature/fullstack-validate.js +337 -0
  502. package/dist/worker/feature/next-action.js +140 -0
  503. package/dist/worker/feature/profile-schema.js +47 -0
  504. package/dist/worker/feature/ready-plan-projection.js +82 -0
  505. package/dist/worker/feature/reducer.js +137 -0
  506. package/dist/worker/feature/review.js +678 -0
  507. package/dist/worker/feature/run.js +390 -0
  508. package/dist/worker/feature/scaffold.js +812 -0
  509. package/dist/worker/feature/types.js +1 -0
  510. package/dist/worker/follow-up/approve.js +273 -0
  511. package/dist/worker/follow-up/factory.js +234 -0
  512. package/dist/worker/follow-up/paths.js +25 -0
  513. package/dist/worker/follow-up/policy.js +26 -0
  514. package/dist/worker/follow-up/schema.js +93 -0
  515. package/dist/worker/follow-up/store.js +96 -0
  516. package/dist/worker/loop-agent/command-result.js +1 -0
  517. package/dist/worker/loop-agent/controller-protocol.js +143 -0
  518. package/dist/worker/loop-agent/loop-agent-client.js +489 -0
  519. package/dist/worker/loop-agent/parse-json.js +14 -0
  520. package/dist/worker/materialize/harness-task-lifecycle-probe.js +126 -0
  521. package/dist/worker/materialize/harness-task-lineage.js +220 -0
  522. package/dist/worker/materialize/harness-task-materializer.js +648 -0
  523. package/dist/worker/metrics/projector.js +139 -0
  524. package/dist/worker/observability/dag-execution-trajectory.js +591 -0
  525. package/dist/worker/observability/event-history.js +216 -0
  526. package/dist/worker/observability/event-store.js +83 -0
  527. package/dist/worker/observability/events.js +79 -0
  528. package/dist/worker/observability/interrupt-eligibility.js +264 -0
  529. package/dist/worker/observability/progress-composite.js +34 -0
  530. package/dist/worker/observability/read-model.js +2499 -0
  531. package/dist/worker/observability/snapshot-store.js +43 -0
  532. package/dist/worker/observability/types.js +1 -0
  533. package/dist/worker/observe/dag-node-execution-output.js +180 -0
  534. package/dist/worker/observe/dag-run-artifacts.js +90 -0
  535. package/dist/worker/observe/health.js +58 -0
  536. package/dist/worker/observe/night-jobs.js +104 -0
  537. package/dist/worker/observe/node-input.js +441 -0
  538. package/dist/worker/observe/paths.js +174 -0
  539. package/dist/worker/observe/routes.js +1077 -0
  540. package/dist/worker/observe/server.js +117 -0
  541. package/dist/worker/observe/spec-evidence.js +398 -0
  542. package/dist/worker/observe/static/api.js +117 -0
  543. package/dist/worker/observe/static/app.js +169 -0
  544. package/dist/worker/observe/static/constants.js +182 -0
  545. package/dist/worker/observe/static/copy.js +67 -0
  546. package/dist/worker/observe/static/custom-select.js +567 -0
  547. package/dist/worker/observe/static/dag-edge-routing.js +368 -0
  548. package/dist/worker/observe/static/dag-helpers.js +161 -0
  549. package/dist/worker/observe/static/dag-history-labels.js +95 -0
  550. package/dist/worker/observe/static/dag-layout.d.ts +36 -0
  551. package/dist/worker/observe/static/dag-layout.js +163 -0
  552. package/dist/worker/observe/static/dag-model.js +145 -0
  553. package/dist/worker/observe/static/dom.js +220 -0
  554. package/dist/worker/observe/static/favicon.svg +37 -0
  555. package/dist/worker/observe/static/format-pool.d.ts +71 -0
  556. package/dist/worker/observe/static/format-pool.js +153 -0
  557. package/dist/worker/observe/static/format.js +347 -0
  558. package/dist/worker/observe/static/index.html +409 -0
  559. package/dist/worker/observe/static/kpi.js +78 -0
  560. package/dist/worker/observe/static/markdown-render.js +124 -0
  561. package/dist/worker/observe/static/operator-chrome.css +517 -0
  562. package/dist/worker/observe/static/operator-chrome.d.ts +83 -0
  563. package/dist/worker/observe/static/operator-chrome.js +623 -0
  564. package/dist/worker/observe/static/relations.js +133 -0
  565. package/dist/worker/observe/static/router.js +156 -0
  566. package/dist/worker/observe/static/run-processing.js +148 -0
  567. package/dist/worker/observe/static/shell-chrome.js +65 -0
  568. package/dist/worker/observe/static/state.js +496 -0
  569. package/dist/worker/observe/static/styles.css +3567 -0
  570. package/dist/worker/observe/static/views/batch.js +227 -0
  571. package/dist/worker/observe/static/views/dag-graph.js +508 -0
  572. package/dist/worker/observe/static/views/dag-inspector.js +1722 -0
  573. package/dist/worker/observe/static/views/dag-trajectory.js +313 -0
  574. package/dist/worker/observe/static/views/dag.js +483 -0
  575. package/dist/worker/observe/static/views/dags.js +877 -0
  576. package/dist/worker/observe/static/views/dashboard.js +747 -0
  577. package/dist/worker/observe/static/views/failures.js +143 -0
  578. package/dist/worker/observe/static/views/feature.js +492 -0
  579. package/dist/worker/observe/static/views/night.js +201 -0
  580. package/dist/worker/observe/static/views/pool.js +708 -0
  581. package/dist/worker/observe/static/views/run.js +453 -0
  582. package/dist/worker/observe/static/views/session-timeline.js +771 -0
  583. package/dist/worker/observe/static/views/shell.js +7 -0
  584. package/dist/worker/observe/static/views/task.js +315 -0
  585. package/dist/worker/observe/static/views/timeline.js +163 -0
  586. package/dist/worker/outcomes/adapters.js +153 -0
  587. package/dist/worker/outcomes/declared-artifacts.js +103 -0
  588. package/dist/worker/outcomes/evidence-tokens.js +29 -0
  589. package/dist/worker/outcomes/gate.js +40 -0
  590. package/dist/worker/outcomes/projector.js +227 -0
  591. package/dist/worker/outcomes/registry.js +1 -0
  592. package/dist/worker/outcomes/store.js +131 -0
  593. package/dist/worker/outcomes/types.js +79 -0
  594. package/dist/worker/pool/attempt-identity.js +41 -0
  595. package/dist/worker/pool/attempt-lease.js +184 -0
  596. package/dist/worker/pool/attempt-transition.js +210 -0
  597. package/dist/worker/pool/begin-attempt-with-lease.js +26 -0
  598. package/dist/worker/pool/begin-attempt.js +35 -0
  599. package/dist/worker/pool/doctor.js +165 -0
  600. package/dist/worker/pool/failure-routing.js +182 -0
  601. package/dist/worker/pool/migrate-state.js +303 -0
  602. package/dist/worker/pool/reconcile.js +285 -0
  603. package/dist/worker/pool/recovery-decision.js +163 -0
  604. package/dist/worker/pool/run-owner-store.js +126 -0
  605. package/dist/worker/pool/run-store.js +360 -0
  606. package/dist/worker/pool/runtime-reconcile-inventory.js +127 -0
  607. package/dist/worker/pool/state-projection.js +57 -0
  608. package/dist/worker/pool/types.js +17 -0
  609. package/dist/worker/pool/validation.js +144 -0
  610. package/dist/worker/preflight.js +157 -0
  611. package/dist/worker/profile-mapping.js +76 -0
  612. package/dist/worker/progress-reporter.js +63 -0
  613. package/dist/worker/report/morning-report.js +155 -0
  614. package/dist/worker/repos/repo-resolver.js +23 -0
  615. package/dist/worker/run-task/execute-prepared-task.js +178 -0
  616. package/dist/worker/run-task/run-task.js +912 -0
  617. package/dist/worker/runner/run-ready.js +561 -0
  618. package/dist/worker/runner/single-task-attempt.js +176 -0
  619. package/dist/worker/scheduler/admission.js +547 -0
  620. package/dist/worker/scheduler/auto-followup.js +99 -0
  621. package/dist/worker/scheduler/cli.js +644 -0
  622. package/dist/worker/scheduler/clock-install/darwin-launchd.js +238 -0
  623. package/dist/worker/scheduler/clock-install/linux-systemd-user.js +224 -0
  624. package/dist/worker/scheduler/clock-install/types.js +1 -0
  625. package/dist/worker/scheduler/clock-install/win32-schtasks.js +227 -0
  626. package/dist/worker/scheduler/clock-install.js +284 -0
  627. package/dist/worker/scheduler/clock.js +420 -0
  628. package/dist/worker/scheduler/dispatcher.js +503 -0
  629. package/dist/worker/scheduler/doctor.js +431 -0
  630. package/dist/worker/scheduler/evidence.js +170 -0
  631. package/dist/worker/scheduler/git-base.js +90 -0
  632. package/dist/worker/scheduler/index.js +25 -0
  633. package/dist/worker/scheduler/lease.js +114 -0
  634. package/dist/worker/scheduler/lifecycle.js +348 -0
  635. package/dist/worker/scheduler/lock.js +80 -0
  636. package/dist/worker/scheduler/morning-window.js +191 -0
  637. package/dist/worker/scheduler/night-git-finalizer.js +114 -0
  638. package/dist/worker/scheduler/night-harvest.js +412 -0
  639. package/dist/worker/scheduler/paths.js +92 -0
  640. package/dist/worker/scheduler/prepared-attempt-recovery.js +471 -0
  641. package/dist/worker/scheduler/recovery.js +277 -0
  642. package/dist/worker/scheduler/reservation.js +146 -0
  643. package/dist/worker/scheduler/retry.js +199 -0
  644. package/dist/worker/scheduler/scheduler-loop.js +272 -0
  645. package/dist/worker/scheduler/store.js +275 -0
  646. package/dist/worker/scheduler/traceability.js +54 -0
  647. package/dist/worker/scheduler/trigger.js +258 -0
  648. package/dist/worker/scheduler/types.js +369 -0
  649. package/dist/worker/scheduler/workspace-adapter.js +128 -0
  650. package/dist/worker/task-graph/acceptance-schema.js +40 -0
  651. package/dist/worker/task-graph/ready-planner.js +267 -0
  652. package/dist/worker/task-graph/ready-queue.js +23 -0
  653. package/dist/worker/task-graph/task-graph-schema.js +59 -0
  654. package/dist/worker/task-graph/types.js +1 -0
  655. package/dist/worker/task-graph/validate.js +293 -0
  656. package/dist/worker/task-spec/complexity-mapping.js +8 -0
  657. package/dist/worker/task-spec/schema.js +125 -0
  658. package/dist/worker/task-spec/types.js +1 -0
  659. package/dist/worker/task-spec/validate.js +391 -0
  660. package/dist/worker/task-spec/workflow-routing.js +149 -0
  661. package/dist/workflows/dag/authoring.js +8 -0
  662. package/dist/workflows/dag/authority-surface.js +138 -0
  663. package/dist/workflows/dag/backend-test-analysis-contract.js +507 -0
  664. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +1985 -0
  665. package/dist/workflows/dag/backend-test-case-manifest.js +638 -0
  666. package/dist/workflows/dag/backend-test-classification-contract.js +38 -0
  667. package/dist/workflows/dag/backend-test-contract-envelope.js +205 -0
  668. package/dist/workflows/dag/backend-test-coverage-contract.js +202 -0
  669. package/dist/workflows/dag/backend-test-execution-contract.js +715 -0
  670. package/dist/workflows/dag/backend-test-gap-fill.js +205 -0
  671. package/dist/workflows/dag/backend-test-intake-context.js +178 -0
  672. package/dist/workflows/dag/backend-test-layout.js +133 -0
  673. package/dist/workflows/dag/backend-test-markdown-workflow.js +1984 -0
  674. package/dist/workflows/dag/backend-test-module-stem.js +26 -0
  675. package/dist/workflows/dag/backend-test-pytest-collection.js +859 -0
  676. package/dist/workflows/dag/backend-test-result-contract.js +1030 -0
  677. package/dist/workflows/dag/backend-test-scenario-param.js +1670 -0
  678. package/dist/workflows/dag/backend-test-scenario-partitions.js +249 -0
  679. package/dist/workflows/dag/backend-test-semantic-review-contract.js +36 -0
  680. package/dist/workflows/dag/backend-test-stability-contract.js +57 -0
  681. package/dist/workflows/dag/backend-test-writer-completeness.js +1058 -0
  682. package/dist/workflows/dag/budget-enforcement.js +67 -0
  683. package/dist/workflows/dag/canvas-observer.js +474 -0
  684. package/dist/workflows/dag/context-policy.js +137 -0
  685. package/dist/workflows/dag/contract-output-registry.js +14 -0
  686. package/dist/workflows/dag/contract-validator-registrations.js +10 -0
  687. package/dist/workflows/dag/controller-identity.js +104 -0
  688. package/dist/workflows/dag/convergence/controller.js +596 -0
  689. package/dist/workflows/dag/decision-envelope.js +557 -0
  690. package/dist/workflows/dag/decision-evidence.js +153 -0
  691. package/dist/workflows/dag/decision-gates.js +1 -0
  692. package/dist/workflows/dag/dynamic-runtime/condition.js +48 -0
  693. package/dist/workflows/dag/dynamic-runtime/loop-until.js +161 -0
  694. package/dist/workflows/dag/dynamic-runtime/map.js +435 -0
  695. package/dist/workflows/dag/dynamic-runtime/reduction.js +72 -0
  696. package/dist/workflows/dag/dynamic-runtime/shared.js +203 -0
  697. package/dist/workflows/dag/event-observer.js +132 -0
  698. package/dist/workflows/dag/executor-registry.js +23 -0
  699. package/dist/workflows/dag/facts.js +4 -0
  700. package/dist/workflows/dag/failure-category.js +118 -0
  701. package/dist/workflows/dag/failure-routing.js +105 -0
  702. package/dist/workflows/dag/final-verification.js +180 -0
  703. package/dist/workflows/dag/frontend-implementation-contract.js +1911 -0
  704. package/dist/workflows/dag/frontend-lint-baseline.js +474 -0
  705. package/dist/workflows/dag/frontend-plan-render.js +90 -0
  706. package/dist/workflows/dag/frontend-prewrite-gate.js +1011 -0
  707. package/dist/workflows/dag/frontend-project-capability.js +1 -0
  708. package/dist/workflows/dag/frontend-recovery-plan.js +73 -0
  709. package/dist/workflows/dag/frontend-recovery-root-manifest.js +123 -0
  710. package/dist/workflows/dag/frontend-recovery-run.js +539 -0
  711. package/dist/workflows/dag/frontend-repair.js +541 -0
  712. package/dist/workflows/dag/frontend-review-context.js +116 -0
  713. package/dist/workflows/dag/frontend-risk.js +161 -0
  714. package/dist/workflows/dag/frontend-test-case-checklist.js +343 -0
  715. package/dist/workflows/dag/frontend-test-case-manifest.js +104 -0
  716. package/dist/workflows/dag/frontend-test-case-quality.js +105 -0
  717. package/dist/workflows/dag/frontend-test-html-report.js +174 -0
  718. package/dist/workflows/dag/frontend-test-l5-report.js +177 -0
  719. package/dist/workflows/dag/frontend-test-result-contract.js +487 -0
  720. package/dist/workflows/dag/frontend-verification-trace.js +275 -0
  721. package/dist/workflows/dag/frontend-worktree-diff.js +201 -0
  722. package/dist/workflows/dag/frontend-writer-recovery.js +106 -0
  723. package/dist/workflows/dag/frontend-writer-rollback.js +821 -0
  724. package/dist/workflows/dag/governance-constants.js +5 -0
  725. package/dist/workflows/dag/governance-profile.js +413 -0
  726. package/dist/workflows/dag/index.js +6 -0
  727. package/dist/workflows/dag/init-hybrid.js +7345 -0
  728. package/dist/workflows/dag/interrupt-request.js +559 -0
  729. package/dist/workflows/dag/knowledge-curator.js +165 -0
  730. package/dist/workflows/dag/l5-report-metrics.js +33 -0
  731. package/dist/workflows/dag/lifecycle.js +855 -0
  732. package/dist/workflows/dag/liveness-policy.js +251 -0
  733. package/dist/workflows/dag/node-execution.js +1081 -0
  734. package/dist/workflows/dag/observer-compose.js +52 -0
  735. package/dist/workflows/dag/output-protocol.js +356 -0
  736. package/dist/workflows/dag/project-governance-context.js +514 -0
  737. package/dist/workflows/dag/prompt-source.js +88 -0
  738. package/dist/workflows/dag/prompt.js +348 -0
  739. package/dist/workflows/dag/reconcile-run.js +145 -0
  740. package/dist/workflows/dag/reconcile-tasks.js +404 -0
  741. package/dist/workflows/dag/recovery-recommendation.js +329 -0
  742. package/dist/workflows/dag/repair-artifact.js +363 -0
  743. package/dist/workflows/dag/report.js +1229 -0
  744. package/dist/workflows/dag/rerun-plan.js +614 -0
  745. package/dist/workflows/dag/rerun-run.js +556 -0
  746. package/dist/workflows/dag/rerun-task.js +370 -0
  747. package/dist/workflows/dag/retry-policy.js +263 -0
  748. package/dist/workflows/dag/run-store.js +41 -0
  749. package/dist/workflows/dag/runner.js +1069 -0
  750. package/dist/workflows/dag/runtime-contract.js +87 -0
  751. package/dist/workflows/dag/runtime.js +5 -0
  752. package/dist/workflows/dag/scheduler.js +497 -0
  753. package/dist/workflows/dag/sdd-embedded.js +128 -0
  754. package/dist/workflows/dag/skill-instructions.js +478 -0
  755. package/dist/workflows/dag/skill-snapshot.js +553 -0
  756. package/dist/workflows/dag/skills.js +41 -0
  757. package/dist/workflows/dag/spec.js +3 -0
  758. package/dist/workflows/dag/task-contract-binding.js +138 -0
  759. package/dist/workflows/dag/task-demand-routing.js +1 -0
  760. package/dist/workflows/dag/topo.js +30 -0
  761. package/dist/workflows/dag/types.js +1145 -0
  762. package/dist/workflows/dag/upstream-artifacts.js +98 -0
  763. package/dist/workflows/dag/validate.js +998 -0
  764. package/dist/workflows/dag/workspace-checkpoint.js +186 -0
  765. package/dist/workflows/dynamic/artifacts.js +65 -0
  766. package/dist/workflows/dynamic/compile.js +371 -0
  767. package/dist/workflows/dynamic/compileTypes.js +1 -0
  768. package/dist/workflows/dynamic/errors.js +5 -0
  769. package/dist/workflows/dynamic/index.js +7 -0
  770. package/dist/workflows/dynamic/profiles.js +156 -0
  771. package/dist/workflows/dynamic/spec.js +115 -0
  772. package/dist/workflows/dynamic/validate.js +275 -0
  773. package/dist/workflows/loop/actions/dag-action.js +129 -0
  774. package/dist/workflows/loop/actions/pi-review.js +267 -0
  775. package/dist/workflows/loop/actions/shared.js +157 -0
  776. package/dist/workflows/loop/actions/shell-verify.js +82 -0
  777. package/dist/workflows/loop/actions/types.js +1 -0
  778. package/dist/workflows/loop/actions/workflow-action.js +255 -0
  779. package/dist/workflows/loop/actions.js +160 -0
  780. package/dist/workflows/loop/benchmark.js +510 -0
  781. package/dist/workflows/loop/closeout.js +135 -0
  782. package/dist/workflows/loop/context.js +47 -0
  783. package/dist/workflows/loop/events.js +26 -0
  784. package/dist/workflows/loop/hash.js +32 -0
  785. package/dist/workflows/loop/index.js +8 -0
  786. package/dist/workflows/loop/paths.js +17 -0
  787. package/dist/workflows/loop/policy/auto-policy.js +112 -0
  788. package/dist/workflows/loop/policy/path-patterns.js +13 -0
  789. package/dist/workflows/loop/rounds.js +81 -0
  790. package/dist/workflows/loop/signals.js +52 -0
  791. package/dist/workflows/loop/state.js +116 -0
  792. package/dist/workflows/loop/templates.js +54 -0
  793. package/dist/workflows/loop/types.js +28 -0
  794. package/docs/README.md +82 -0
  795. package/docs/architecture/README.md +35 -0
  796. package/docs/architecture/dag-execution.md +165 -0
  797. package/docs/architecture/evolution.md +108 -0
  798. package/docs/architecture/facts-and-state.md +74 -0
  799. package/docs/architecture/runtime-boundaries.md +226 -0
  800. package/docs/architecture/system-overview.md +100 -0
  801. package/docs/architecture/worker-and-feature.md +122 -0
  802. package/docs/governance/README.md +18 -0
  803. package/docs/governance/harness-methodology-debugging.md +177 -0
  804. package/docs/governance/harness-methodology-tdd.md +130 -0
  805. package/docs/governance/harness-methodology-verification.md +27 -0
  806. package/docs/init-surface.manifest.json +358 -0
  807. package/docs/operations/README.md +15 -0
  808. package/docs/operations/local-development-environment.md +77 -0
  809. package/docs/skills/README.md +7 -0
  810. package/docs/skills/vetted-skill-registry.md +49 -0
  811. package/docs/templates/README.md +67 -0
  812. package/docs/templates/adr.md +60 -0
  813. package/docs/templates/agent-dag-authority-surface-audit.prompt.md +94 -0
  814. package/docs/templates/agent-dag-decision-envelope.schema.json +213 -0
  815. package/docs/templates/agent-dag-decision-gate-dogfood-report.md +117 -0
  816. package/docs/templates/agent-dag-decision-gate.prompt.md +246 -0
  817. package/docs/templates/agent-dag-process-supervisor.prompt.md +98 -0
  818. package/docs/templates/agent-dag-report.schema.json +473 -0
  819. package/docs/templates/agent-dag-review-verdict.prompt.md +68 -0
  820. package/docs/templates/agent-dag.base.json +190 -0
  821. package/docs/templates/agent-dag.final-verification.json +185 -0
  822. package/docs/templates/agent-dag.schema.json +590 -0
  823. package/docs/templates/agent-dag.supervised-implementation.json +640 -0
  824. package/docs/templates/agent-worker-production-readiness-checklist.md +47 -0
  825. package/docs/templates/backend-test-analysis.schema.json +37 -0
  826. package/docs/templates/backend-test-case-manifest.schema.json +223 -0
  827. package/docs/templates/backend-test-dag.classify.prompt.md +75 -0
  828. package/docs/templates/backend-test-dag.generate-pytest.prompt.md +41 -0
  829. package/docs/templates/backend-test-dag.json +671 -0
  830. package/docs/templates/backend-test-dag.retrospect.prompt.md +165 -0
  831. package/docs/templates/backend-test-dag.review-cases.prompt.md +36 -0
  832. package/docs/templates/backend-test-execution.schema.json +138 -0
  833. package/docs/templates/backend-test-result.schema.json +99 -0
  834. package/docs/templates/branch-merge-report.md +115 -0
  835. package/docs/templates/evaluation/agents-map-slim-v1.candidate.json +9 -0
  836. package/docs/templates/evaluation/agents-map-slim-v1.md +87 -0
  837. package/docs/templates/evaluation/agents-map-verbose-v0.candidate.json +9 -0
  838. package/docs/templates/evaluation/agents-map-verbose-v0.md +153 -0
  839. package/docs/templates/evaluation/campaign-budget-v1.json +12 -0
  840. package/docs/templates/evaluation/campaign-dogfood-v0.json +24 -0
  841. package/docs/templates/evaluation/campaign-evidence-v1.json +44 -0
  842. package/docs/templates/evaluation/context-policy-baseline-v1.json +17 -0
  843. package/docs/templates/evaluation/context-policy-role-specialized-v1.json +28 -0
  844. package/docs/templates/evaluation/corpus-dogfood-v0.manifest.json +118 -0
  845. package/docs/templates/evaluation/matrix-dag-dry-run-v1.json +21 -0
  846. package/docs/templates/evaluation/matrix-fixture-v1.json +10 -0
  847. package/docs/templates/evaluation/private-verifier-dogfood-v0.json +16 -0
  848. package/docs/templates/exec-plan.md +66 -0
  849. package/docs/templates/feature-spec.md +53 -0
  850. package/docs/templates/frontend-design-contract.md +68 -0
  851. package/docs/templates/frontend-eval/fixtures/failures/01-type-build-error.md +17 -0
  852. package/docs/templates/frontend-eval/fixtures/failures/02-unit-component-test-fail.md +16 -0
  853. package/docs/templates/frontend-eval/fixtures/failures/03-fixture-schema-drift.md +16 -0
  854. package/docs/templates/frontend-eval/fixtures/failures/04-missing-loading-empty-error-state.md +16 -0
  855. package/docs/templates/frontend-eval/fixtures/failures/05-forbidden-write-writeset-expansion.md +16 -0
  856. package/docs/templates/frontend-eval/fixtures/failures/06-unapproved-dependency-add.md +16 -0
  857. package/docs/templates/frontend-eval/fixtures/failures/07-mock-production-on.md +21 -0
  858. package/docs/templates/frontend-eval/fixtures/functional/01-simple-component-style.md +29 -0
  859. package/docs/templates/frontend-eval/fixtures/functional/02-form-validation.md +28 -0
  860. package/docs/templates/frontend-eval/fixtures/functional/03-list-detail-page.md +28 -0
  861. package/docs/templates/frontend-eval/fixtures/functional/04-api-mock.md +29 -0
  862. package/docs/templates/frontend-eval/fixtures/functional/05-permission-auth-gated-ui.md +27 -0
  863. package/docs/templates/frontend-eval/fixtures/functional/06-ssr-server-client-boundary.md +28 -0
  864. package/docs/templates/frontend-eval/fixtures/functional/07-shared-public-component-api.md +28 -0
  865. package/docs/templates/frontend-eval/fixtures/functional/08-pure-local-no-remote.md +27 -0
  866. package/docs/templates/frontend-eval/metrics.md +138 -0
  867. package/docs/templates/frontend-eval/smoke-targets.md +53 -0
  868. package/docs/templates/frontend-implementation-contract.schema.json +35 -0
  869. package/docs/templates/frontend-task-constraints.md +62 -0
  870. package/docs/templates/frontend-task-requirement.md +104 -0
  871. package/docs/templates/frontend-test-case-checklist.md +44 -0
  872. package/docs/templates/frontend-test-case.example.md +143 -0
  873. package/docs/templates/frontend-test-dag.generate-cases.prompt.md +63 -0
  874. package/docs/templates/frontend-test-dag.json +409 -0
  875. package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +21 -0
  876. package/docs/templates/frontend-test-dag.retrospect.prompt.md +5 -0
  877. package/docs/templates/frontend-test-dag.review-cases.prompt.md +5 -0
  878. package/docs/templates/frontend-test-dag.review-execution.prompt.md +3 -0
  879. package/docs/templates/frontend-test-standard-scenarios.v1.json +159 -0
  880. package/docs/templates/harness.schema.json +351 -0
  881. package/docs/templates/hybrid-dag.json +188 -0
  882. package/docs/templates/init-evolution-review.md +35 -0
  883. package/docs/templates/init-managed-agents.md +157 -0
  884. package/docs/templates/interactive-ui-round2-experiment.md +66 -0
  885. package/docs/templates/knowledge-graph-bootstrap-dag.json +118 -0
  886. package/docs/templates/knowledge-sync-dag.json +178 -0
  887. package/docs/templates/knowledge-sync-draft.schema.json +71 -0
  888. package/docs/templates/product-line/AGENTS.md +9 -0
  889. package/docs/templates/product-line/README.md +42 -0
  890. package/docs/templates/product-line/acceptance.yaml +23 -0
  891. package/docs/templates/product-line/closeout.yaml +9 -0
  892. package/docs/templates/product-line/design.md +13 -0
  893. package/docs/templates/product-line/feature-scaffold-batch.example.yaml +31 -0
  894. package/docs/templates/product-line/feature.yaml +11 -0
  895. package/docs/templates/product-line/links.md +10 -0
  896. package/docs/templates/product-line/requirement.md +17 -0
  897. package/docs/templates/product-line/scaffold-samples/README.md +36 -0
  898. package/docs/templates/product-line/scaffold-samples/backend-only/acceptance.yaml +16 -0
  899. package/docs/templates/product-line/scaffold-samples/backend-only/design.md +14 -0
  900. package/docs/templates/product-line/scaffold-samples/backend-only/feature.yaml +14 -0
  901. package/docs/templates/product-line/scaffold-samples/backend-only/requirement.md +6 -0
  902. package/docs/templates/product-line/scaffold-samples/backend-only/tasks/BE-IMPL-001.yaml +83 -0
  903. package/docs/templates/product-line/scaffold-samples/backend-only/tasks/task-graph.yaml +14 -0
  904. package/docs/templates/product-line/scaffold-samples/fe-with-api/acceptance.yaml +18 -0
  905. package/docs/templates/product-line/scaffold-samples/fe-with-api/design.md +18 -0
  906. package/docs/templates/product-line/scaffold-samples/fe-with-api/feature.yaml +14 -0
  907. package/docs/templates/product-line/scaffold-samples/fe-with-api/requirement.md +6 -0
  908. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/BE-IMPL-001.yaml +84 -0
  909. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/CONTRACT-001.yaml +84 -0
  910. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/FE-IMPL-001.yaml +86 -0
  911. package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/task-graph.yaml +40 -0
  912. package/docs/templates/product-line/scaffold-samples/frontend-only/acceptance.yaml +16 -0
  913. package/docs/templates/product-line/scaffold-samples/frontend-only/design.md +14 -0
  914. package/docs/templates/product-line/scaffold-samples/frontend-only/feature.yaml +14 -0
  915. package/docs/templates/product-line/scaffold-samples/frontend-only/requirement.md +6 -0
  916. package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/FE-IMPL-001.yaml +85 -0
  917. package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/task-graph.yaml +14 -0
  918. package/docs/templates/product-line/task-graph.yaml +23 -0
  919. package/docs/templates/product-line/task.yaml +68 -0
  920. package/docs/templates/product-line/test-plan.md +7 -0
  921. package/docs/templates/production-readiness-checklist.md +57 -0
  922. package/docs/templates/progress-log.md +27 -0
  923. package/docs/templates/project-start-checklist.md +9 -0
  924. package/docs/templates/qa-report.md +48 -0
  925. package/docs/templates/sprint-contract.md +29 -0
  926. package/docs/templates/worker-dogfood-evidence.md +80 -0
  927. package/docs/templates/worker-dogfood-setup.md +68 -0
  928. package/examples/decision-gate-agent-dag.json +177 -0
  929. package/examples/example-dag.json +46 -0
  930. package/examples/hybrid-loop-agent-dag.json +189 -0
  931. package/examples/l5-report-coms-process-definition.html +322 -0
  932. package/examples/l5-report-demo.html +79 -0
  933. package/harness.json +90 -0
  934. package/package.json +98 -0
  935. package/scripts/kb-bootstrap-init-skeleton.sh +241 -0
  936. package/scripts/kb-graph-incremental-prepare.mjs +386 -0
  937. package/scripts/kb-graph-materialize.mjs +105 -0
  938. package/scripts/kb-graph-promote.mjs +164 -0
  939. package/scripts/kb-query.mjs +554 -0
  940. package/skills/agent-worker/SKILL.md +48 -0
  941. package/skills/agent-worker/references/agent-worker-operator.md +159 -0
  942. package/skills/ai-engineering-context/SKILL.md +48 -0
  943. package/skills/analyze-product-dependencies/SKILL.md +108 -0
  944. package/skills/analyze-product-dependencies/references/api-documentation-schema.md +35 -0
  945. package/skills/analyze-product-dependencies/references/dependency-analysis-schema.md +38 -0
  946. package/skills/analyze-product-dependencies/references/example.md +76 -0
  947. package/skills/analyze-product-dependencies/references/forward-test-cases.md +110 -0
  948. package/skills/analyze-product-dependencies/references/input-contract.md +34 -0
  949. package/skills/analyze-product-dependencies/references/kb-integration.md +64 -0
  950. package/skills/analyze-product-dependencies/references/scouting-rules.md +76 -0
  951. package/skills/analyze-product-dependencies/scripts/test-validators.mjs +460 -0
  952. package/skills/analyze-product-dependencies/scripts/validate-api-documentation.mjs +194 -0
  953. package/skills/analyze-product-dependencies/scripts/validate-dependency-analysis.mjs +200 -0
  954. package/skills/analyze-product-dependencies/scripts/validate-product-requirement-input.mjs +90 -0
  955. package/skills/analyze-product-dependencies/scripts/validation-helpers.mjs +138 -0
  956. package/skills/analyze-product-requirements/SKILL.md +145 -0
  957. package/skills/analyze-product-requirements/references/acceptance-criteria.md +87 -0
  958. package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +70 -0
  959. package/skills/analyze-product-requirements/references/example.md +104 -0
  960. package/skills/analyze-product-requirements/references/forward-test-cases.md +144 -0
  961. package/skills/analyze-product-requirements/references/kb-integration.md +56 -0
  962. package/skills/analyze-product-requirements/references/product-analysis-schema.md +41 -0
  963. package/skills/analyze-product-requirements/references/product-requirement-schema.md +42 -0
  964. package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +66 -0
  965. package/skills/analyze-product-requirements/scripts/compute-source-identity.mjs +35 -0
  966. package/skills/analyze-product-requirements/scripts/test-validators.mjs +501 -0
  967. package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +100 -0
  968. package/skills/analyze-product-requirements/scripts/validate-product-requirement.mjs +109 -0
  969. package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +109 -0
  970. package/skills/analyze-product-requirements/scripts/validation-helpers.mjs +175 -0
  971. package/skills/browser-tools/SKILL.md +196 -0
  972. package/skills/browser-tools/browser-content.js +103 -0
  973. package/skills/browser-tools/browser-cookies.js +35 -0
  974. package/skills/browser-tools/browser-eval.js +53 -0
  975. package/skills/browser-tools/browser-hn-scraper.js +108 -0
  976. package/skills/browser-tools/browser-nav.js +44 -0
  977. package/skills/browser-tools/browser-pick.js +162 -0
  978. package/skills/browser-tools/browser-screenshot.js +34 -0
  979. package/skills/browser-tools/browser-start.js +86 -0
  980. package/skills/browser-tools/package-lock.json +2556 -0
  981. package/skills/browser-tools/package.json +19 -0
  982. package/skills/code-review-core/SKILL.md +20 -0
  983. package/skills/codebase-scout/SKILL.md +19 -0
  984. package/skills/frontend-bounded-implement/SKILL.md +53 -0
  985. package/skills/frontend-design-review/SKILL.md +79 -0
  986. package/skills/frontend-design-review/references/review-checklist.md +43 -0
  987. package/skills/frontend-implementation/SKILL.md +52 -0
  988. package/skills/frontend-implementation/references/code-standards.md +33 -0
  989. package/skills/frontend-implementation/references/design-spec.md +56 -0
  990. package/skills/frontend-implementation/references/node-contracts.md +31 -0
  991. package/skills/frontend-review/SKILL.md +55 -0
  992. package/skills/frontend-review/references/review-findings.md +50 -0
  993. package/skills/frontend-verification/SKILL.md +61 -0
  994. package/skills/frontend-verification/references/verification-checklist.md +48 -0
  995. package/skills/grill-me/SKILL.md +10 -0
  996. package/skills/grill-with-docs/SKILL.md +80 -0
  997. package/skills/grill-with-docs/adr-format.md +58 -0
  998. package/skills/grill-with-docs/context-format.md +52 -0
  999. package/skills/init-capability-evolution/SKILL.md +70 -0
  1000. package/skills/local-jacoco-coverage/SKILL.md +281 -0
  1001. package/skills/local-jacoco-coverage/references/requirement-to-source-mapping.md +85 -0
  1002. package/skills/local-jacoco-coverage/references/runtime-alignment.md +106 -0
  1003. package/skills/local-jacoco-coverage/scripts/run-coverage-analysis.sh +148 -0
  1004. package/skills/local-jacoco-coverage/scripts/start-jacoco-agent.sh +110 -0
  1005. package/skills/loop-agent/SKILL.md +68 -0
  1006. package/skills/loop-agent/references/README.md +67 -0
  1007. package/skills/loop-agent/references/command-reference.md +645 -0
  1008. package/skills/loop-agent/references/docs-converge.md +126 -0
  1009. package/skills/loop-agent/references/harness-policy.md +289 -0
  1010. package/skills/loop-agent/references/hybrid-dag.md +245 -0
  1011. package/skills/loop-agent/references/learned/README.md +21 -0
  1012. package/skills/loop-agent/references/long-running-loop.md +57 -0
  1013. package/skills/loop-agent/references/model-routing.md +45 -0
  1014. package/skills/loop-agent/references/multi-worktree.md +54 -0
  1015. package/skills/loop-agent/references/one-shot-runs.md +84 -0
  1016. package/skills/loop-agent/references/orchestrator-and-interventions.md +175 -0
  1017. package/skills/loop-agent/references/pi-prompt.md +23 -0
  1018. package/skills/loop-agent/references/pi-subagent-assisted-mode.md +84 -0
  1019. package/skills/loop-agent/references/post-implementation-and-patterns.md +54 -0
  1020. package/skills/loop-agent/references/source-and-plan-practice.md +169 -0
  1021. package/skills/loop-agent/references/task-workflow.md +104 -0
  1022. package/skills/loop-agent/references/verification-and-failure-handling.md +148 -0
  1023. package/skills/playwright-cli/SKILL.md +93 -0
  1024. package/skills/playwright-cli/references/element-attributes.md +23 -0
  1025. package/skills/playwright-cli/references/playwright-tests.md +39 -0
  1026. package/skills/playwright-cli/references/request-mocking.md +87 -0
  1027. package/skills/playwright-cli/references/running-code.md +241 -0
  1028. package/skills/playwright-cli/references/session-management.md +225 -0
  1029. package/skills/playwright-cli/references/storage-state.md +275 -0
  1030. package/skills/playwright-cli/references/test-generation.md +433 -0
  1031. package/skills/playwright-cli/references/tracing.md +5 -0
  1032. package/skills/playwright-cli/references/video-recording.md +5 -0
  1033. package/skills/playwright-cli-case-generator/SKILL.md +108 -0
  1034. package/skills/requesting-code-review/SKILL.md +101 -0
  1035. package/skills/requesting-code-review/code-reviewer.md +168 -0
  1036. package/skills/systematic-debugging/CREATION-LOG.md +119 -0
  1037. package/skills/systematic-debugging/SKILL.md +312 -0
  1038. package/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
  1039. package/skills/systematic-debugging/condition-based-waiting.md +115 -0
  1040. package/skills/systematic-debugging/defense-in-depth.md +122 -0
  1041. package/skills/systematic-debugging/find-polluter.sh +63 -0
  1042. package/skills/systematic-debugging/root-cause-tracing.md +169 -0
  1043. package/skills/systematic-debugging/test-academic.md +14 -0
  1044. package/skills/systematic-debugging/test-pressure-1.md +58 -0
  1045. package/skills/systematic-debugging/test-pressure-2.md +68 -0
  1046. package/skills/systematic-debugging/test-pressure-3.md +69 -0
  1047. package/skills/test-driven-development/SKILL.md +27 -0
  1048. package/skills/using-git-worktrees/SKILL.md +215 -0
  1049. package/skills/verification-before-completion/SKILL.md +154 -0
  1050. package/skills/webapp-testing/SKILL.md +19 -0
@@ -0,0 +1,1373 @@
1
+ import { mkdir, readFile, readdir, rename, rm, writeFile, } from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ export const CLIENT_RECOVERY_MODES = [
5
+ "auto",
6
+ "project",
7
+ "user",
8
+ "off",
9
+ ];
10
+ export const OPENCODE_TRANSIENT_RETRY_PLUGIN_PATH = ".opencode/plugins/loop-agent-transient-retry.js";
11
+ export const OPENCODE_TRANSIENT_RETRY_LOG_PATH = ".opencode/plugins/loop-agent-transient-retry.log";
12
+ export const OPENCODE_CONTEXT_OVERFLOW_COMPACT_PLUGIN_PATH = ".opencode/plugins/loop-agent-context-overflow-compact.js";
13
+ export const PI_CONTEXT_OVERFLOW_EXTENSION_PATH = ".pi/extensions/loop-agent-context-overflow.js";
14
+ /** Pi project settings are part of the managed init surface; never default to home. */
15
+ export const PI_PROJECT_SETTINGS_PATH = ".pi/settings.json";
16
+ export const PERMANENT_ERROR_INTERACTION = "plugin-ignore-permanent-error";
17
+ export const BACKOFF_MS = [2000, 4000, 8000, 16000, 30000];
18
+ export const MAX_SESSION_RETRIES = 5;
19
+ /** Hard cap for OpenCode overflow compact+resume recoveries (≤ 2). */
20
+ export const MAX_OVERFLOW_RECOVERIES = 1;
21
+ import { PI_RECOMMENDED_COMPACTION, PI_RECOMMENDED_RETRY, } from "../shared/pi-retry-settings.js";
22
+ export { PI_RECOMMENDED_COMPACTION, PI_RECOMMENDED_RETRY };
23
+ /**
24
+ * Shared overflow phrase sources used by isContextOverflow and generated plugins.
25
+ * Keep English + Chinese intranet gateway messages in one place to avoid drift.
26
+ */
27
+ export const CONTEXT_OVERFLOW_PHRASES = [
28
+ "请求上下文过大",
29
+ "context_length_exceeded",
30
+ "context overflow",
31
+ "context length overflow",
32
+ "too many tokens",
33
+ "maximum context",
34
+ "prompt is too long",
35
+ "request_too_large",
36
+ "context window",
37
+ ];
38
+ function escapeRegExpLiteral(value) {
39
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
40
+ }
41
+ const CONTEXT_OVERFLOW_PATTERN = new RegExp(CONTEXT_OVERFLOW_PHRASES.map(escapeRegExpLiteral).join("|"), "i");
42
+ function buildGeneratedContextOverflowPatternSource() {
43
+ return `const CONTEXT_OVERFLOW_PHRASES = ${JSON.stringify([
44
+ ...CONTEXT_OVERFLOW_PHRASES,
45
+ ])};
46
+ const OVERFLOW_PATTERN = new RegExp(
47
+ CONTEXT_OVERFLOW_PHRASES.map((phrase) =>
48
+ phrase.replace(/[.*+?^\${}()|[\\]\\\\]/g, "\\\\$&"),
49
+ ).join("|"),
50
+ "i",
51
+ );`;
52
+ }
53
+ const PERMANENT_MESSAGE_PATTERNS = [
54
+ {
55
+ reason: "auth",
56
+ pattern: /\b(401|unauthorized|invalid api key|authentication)\b/i,
57
+ },
58
+ {
59
+ reason: "permission",
60
+ pattern: /\b(403|forbidden|permission denied|not allowed)\b/i,
61
+ },
62
+ {
63
+ reason: "quota",
64
+ pattern: /\b(quota|rate.?limit|billing|insufficient.?credit)\b/i,
65
+ },
66
+ {
67
+ reason: "context-overflow",
68
+ pattern: CONTEXT_OVERFLOW_PATTERN,
69
+ },
70
+ {
71
+ reason: "cancelled",
72
+ pattern: /\b(cancelled|canceled|aborted by user|user cancel)\b/i,
73
+ },
74
+ {
75
+ reason: "business-validation",
76
+ pattern: /\b(business validation|invalid task|schema validation)\b/i,
77
+ },
78
+ ];
79
+ const TRANSIENT_MESSAGE_PATTERNS = [
80
+ /\bcode[:\s]*502\b/i,
81
+ /\b502\b/,
82
+ /\bLLMRequestError\b/i,
83
+ /\bnetwork fluctuation\b/i,
84
+ /\btimeout\b/i,
85
+ /\btransient provider failure\b/i,
86
+ /\bnon-standard (payload|response)\b/i,
87
+ /\bupstream returned\b/i,
88
+ /\bmodel processing timeout\b/i,
89
+ ];
90
+ export function isClientRecoveryMode(value) {
91
+ return (typeof value === "string" &&
92
+ CLIENT_RECOVERY_MODES.includes(value));
93
+ }
94
+ export function parseClientRecoveryMode(value) {
95
+ if (value === undefined || value === null || value === "")
96
+ return "auto";
97
+ if (isClientRecoveryMode(value))
98
+ return value;
99
+ throw new Error(`init --client-recovery must be one of ${CLIENT_RECOVERY_MODES.join("|")}`);
100
+ }
101
+ function asText(value) {
102
+ if (typeof value === "string")
103
+ return value;
104
+ if (value == null)
105
+ return "";
106
+ try {
107
+ return JSON.stringify(value);
108
+ }
109
+ catch {
110
+ return String(value);
111
+ }
112
+ }
113
+ function collectErrorText(error) {
114
+ if (typeof error === "string")
115
+ return error;
116
+ if (!error || typeof error !== "object")
117
+ return asText(error);
118
+ const record = error;
119
+ const parts = [
120
+ asText(record.name),
121
+ asText(record.message),
122
+ asText(record.status),
123
+ asText(record.code),
124
+ asText(record.data),
125
+ ];
126
+ return parts.filter(Boolean).join(" ");
127
+ }
128
+ function hasUnknownErrorShape(error) {
129
+ const text = collectErrorText(error);
130
+ if (/\bUnknownError\b/i.test(text))
131
+ return true;
132
+ if (error && typeof error === "object") {
133
+ const record = error;
134
+ if (typeof record.name === "string" && /UnknownError/i.test(record.name))
135
+ return true;
136
+ }
137
+ return false;
138
+ }
139
+ /**
140
+ * TypeValidation bypass shape: bare TypeValidationError (zod invalid_union
141
+ * surfaced directly by the provider/SDK instead of wrapped as UnknownError).
142
+ * Bypass only fires when combined with a transient signal (see classifyTransientUnknownError).
143
+ */
144
+ function hasTypeValidationShape(error) {
145
+ const text = collectErrorText(error);
146
+ if (/\bTypeValidationError\b/i.test(text))
147
+ return true;
148
+ if (/Type validation failed/i.test(text))
149
+ return true;
150
+ if (error && typeof error === "object") {
151
+ const record = error;
152
+ if (typeof record.name === "string" &&
153
+ /TypeValidationError/i.test(record.name)) {
154
+ return true;
155
+ }
156
+ }
157
+ return false;
158
+ }
159
+ function isStandardApiError(error) {
160
+ if (!error || typeof error !== "object")
161
+ return false;
162
+ const record = error;
163
+ if (typeof record.name === "string" && /^APIError$/i.test(record.name))
164
+ return true;
165
+ if (typeof record.name === "string" &&
166
+ /^(AuthError|PermissionError)$/i.test(record.name)) {
167
+ return true;
168
+ }
169
+ return false;
170
+ }
171
+ function permanentReason(error) {
172
+ if (isStandardApiError(error)) {
173
+ const record = error;
174
+ if (typeof record.name === "string" && /AuthError/i.test(record.name))
175
+ return "auth";
176
+ if (typeof record.name === "string" &&
177
+ /PermissionError/i.test(record.name)) {
178
+ return "permission";
179
+ }
180
+ return "api-error";
181
+ }
182
+ const text = collectErrorText(error);
183
+ for (const entry of PERMANENT_MESSAGE_PATTERNS) {
184
+ if (entry.pattern.test(text))
185
+ return entry.reason;
186
+ }
187
+ return undefined;
188
+ }
189
+ /**
190
+ * Shared context-overflow recognition for OpenCode overflow-compact plugin,
191
+ * Pi project extension, and pure tests. Does not treat 401/403, quota, cancel,
192
+ * business validation, or standard 502/LLMRequestError as overflow.
193
+ */
194
+ export function isContextOverflow(error) {
195
+ return CONTEXT_OVERFLOW_PATTERN.test(collectErrorText(error));
196
+ }
197
+ function looksTransient(error) {
198
+ const text = collectErrorText(error);
199
+ if (TRANSIENT_MESSAGE_PATTERNS.some((pattern) => pattern.test(text)))
200
+ return true;
201
+ if (error && typeof error === "object") {
202
+ const record = error;
203
+ if (record.code === 502 || record.status === 502)
204
+ return true;
205
+ if (record.data && typeof record.data === "object") {
206
+ const data = record.data;
207
+ if (data.code === 502 || data.status === 502)
208
+ return true;
209
+ }
210
+ }
211
+ return false;
212
+ }
213
+ /**
214
+ * Decide whether an OpenCode error should be resumed by the project plugin.
215
+ * Only compensates transient UnknownError paths that built-in APIError retry misses.
216
+ *
217
+ * TypeValidation bypass: a bare TypeValidationError (provider/SDK surfaces
218
+ * zod invalid_union directly, without the UnknownError wrapper) is treated as
219
+ * a retryable transient-unknown-error ONLY when it also carries a transient
220
+ * signal (502 / LLMRequestError / timeout / etc.). A pure schema mismatch
221
+ * without a transient signal is still rejected (resumable: false).
222
+ */
223
+ export function classifyTransientUnknownError(error) {
224
+ const permanent = permanentReason(error);
225
+ if (permanent) {
226
+ return {
227
+ resumable: false,
228
+ reason: permanent,
229
+ interaction: PERMANENT_ERROR_INTERACTION,
230
+ };
231
+ }
232
+ const isUnknownShape = hasUnknownErrorShape(error);
233
+ const isTypeValidationShape = hasTypeValidationShape(error);
234
+ if (!isUnknownShape && !isTypeValidationShape) {
235
+ return {
236
+ resumable: false,
237
+ reason: "not-unknown-error",
238
+ interaction: PERMANENT_ERROR_INTERACTION,
239
+ };
240
+ }
241
+ if (!looksTransient(error)) {
242
+ return {
243
+ resumable: false,
244
+ reason: "unknown-non-transient",
245
+ interaction: PERMANENT_ERROR_INTERACTION,
246
+ };
247
+ }
248
+ return { resumable: true, reason: "transient-unknown-error" };
249
+ }
250
+ export function nextBackoffMs(attempt) {
251
+ if (!Number.isInteger(attempt) ||
252
+ attempt < 0 ||
253
+ attempt >= BACKOFF_MS.length) {
254
+ return undefined;
255
+ }
256
+ return BACKOFF_MS[attempt];
257
+ }
258
+ export function canResumeSession(input) {
259
+ if (input.sessionStatus === "retry") {
260
+ return { allowed: false, reason: "builtin-retry-active" };
261
+ }
262
+ if (!input.sessionStatus) {
263
+ return { allowed: false, reason: "session-status-unknown" };
264
+ }
265
+ if (input.locked) {
266
+ return { allowed: false, reason: "session-locked" };
267
+ }
268
+ if (!input.idle ||
269
+ input.sessionStatus === "busy" ||
270
+ input.sessionStatus === "running") {
271
+ return { allowed: false, reason: "session-busy" };
272
+ }
273
+ if (input.attempt >= MAX_SESSION_RETRIES) {
274
+ return { allowed: false, reason: "max-retries" };
275
+ }
276
+ return { allowed: true, reason: "ready" };
277
+ }
278
+ export function buildResumePrompt(input) {
279
+ return [
280
+ `[loop-agent transient recovery] session=${input.sessionId} attempt=${input.attempt}`,
281
+ `Previous model turn failed with a transient UnknownError: ${input.errorSummary}`,
282
+ "Before continuing any work, first inspect already completed tool calls and existing file modifications in this session.",
283
+ "Do not re-run side-effecting tools or rewrite files that already reflect successful prior work.",
284
+ "Resume only the remaining unfinished work after that check.",
285
+ "续接前请先检查本 session 已有工具调用与文件改动,避免重复执行有副作用的操作。",
286
+ ].join("\n");
287
+ }
288
+ export function createSessionRecoveryTracker() {
289
+ const states = new Map();
290
+ function getOrCreate(sessionId) {
291
+ let state = states.get(sessionId);
292
+ if (!state) {
293
+ state = { attempt: 0, locked: false };
294
+ states.set(sessionId, state);
295
+ }
296
+ return state;
297
+ }
298
+ return {
299
+ getOrCreate,
300
+ isLocked(sessionId) {
301
+ return getOrCreate(sessionId).locked;
302
+ },
303
+ tryAcquire(sessionId) {
304
+ const state = getOrCreate(sessionId);
305
+ if (state.locked)
306
+ return false;
307
+ state.locked = true;
308
+ return true;
309
+ },
310
+ release(sessionId) {
311
+ const state = getOrCreate(sessionId);
312
+ state.locked = false;
313
+ },
314
+ markSuccess(sessionId) {
315
+ const state = getOrCreate(sessionId);
316
+ state.attempt = 0;
317
+ state.locked = false;
318
+ },
319
+ incrementAttempt(sessionId) {
320
+ const state = getOrCreate(sessionId);
321
+ state.attempt += 1;
322
+ return state.attempt;
323
+ },
324
+ };
325
+ }
326
+ function isRecord(value) {
327
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
328
+ }
329
+ function readRetryEnabled(existing) {
330
+ if (!existing || !isRecord(existing.retry))
331
+ return undefined;
332
+ if (typeof existing.retry.enabled !== "boolean")
333
+ return undefined;
334
+ return existing.retry.enabled;
335
+ }
336
+ /**
337
+ * Field-level plan for ~/.pi/agent/settings.json retry recommendations.
338
+ * Never clobbers existing values; never overrides enabled:false.
339
+ */
340
+ export function planPiRetryMerge(existing) {
341
+ const settingsPath = "~/.pi/agent/settings.json";
342
+ if (existing === undefined) {
343
+ return {
344
+ action: "write",
345
+ reason: "missing-file",
346
+ path: settingsPath,
347
+ next: {
348
+ retry: {
349
+ ...PI_RECOMMENDED_RETRY,
350
+ provider: { ...PI_RECOMMENDED_RETRY.provider },
351
+ },
352
+ },
353
+ };
354
+ }
355
+ if (!isRecord(existing)) {
356
+ return {
357
+ action: "report",
358
+ reason: "invalid-json",
359
+ path: settingsPath,
360
+ message: "Pi settings root must be a JSON object",
361
+ };
362
+ }
363
+ const enabled = readRetryEnabled(existing);
364
+ if (enabled === false) {
365
+ return {
366
+ action: "report",
367
+ reason: "enabled-false",
368
+ path: settingsPath,
369
+ next: existing,
370
+ message: "retry.enabled=false is preserved; human decision required to enable recovery",
371
+ };
372
+ }
373
+ const retry = isRecord(existing.retry) ? { ...existing.retry } : {};
374
+ const provider = isRecord(retry.provider) ? { ...retry.provider } : {};
375
+ let changed = !isRecord(existing.retry) ||
376
+ !isRecord(existing.retry.provider);
377
+ if (retry.enabled === undefined) {
378
+ retry.enabled = PI_RECOMMENDED_RETRY.enabled;
379
+ changed = true;
380
+ }
381
+ if (retry.maxRetries === undefined) {
382
+ retry.maxRetries = PI_RECOMMENDED_RETRY.maxRetries;
383
+ changed = true;
384
+ }
385
+ if (retry.baseDelayMs === undefined) {
386
+ retry.baseDelayMs = PI_RECOMMENDED_RETRY.baseDelayMs;
387
+ changed = true;
388
+ }
389
+ if (provider.maxRetries === undefined) {
390
+ provider.maxRetries = PI_RECOMMENDED_RETRY.provider.maxRetries;
391
+ changed = true;
392
+ }
393
+ if (provider.maxRetryDelayMs === undefined) {
394
+ provider.maxRetryDelayMs = PI_RECOMMENDED_RETRY.provider.maxRetryDelayMs;
395
+ changed = true;
396
+ }
397
+ retry.provider = provider;
398
+ const next = { ...existing, retry };
399
+ if (!changed) {
400
+ return {
401
+ action: "noop",
402
+ reason: "matches",
403
+ path: settingsPath,
404
+ next,
405
+ };
406
+ }
407
+ return {
408
+ action: "write",
409
+ reason: "missing-fields",
410
+ path: settingsPath,
411
+ next,
412
+ };
413
+ }
414
+ export function piSettingsPath(homeDir) {
415
+ return path.join(homeDir, ".pi", "agent", "settings.json");
416
+ }
417
+ async function writeJsonAtomic(filePath, value) {
418
+ await mkdir(path.dirname(filePath), { recursive: true });
419
+ const tempPath = path.join(path.dirname(filePath), `.${path.basename(filePath)}.${process.pid}.${Date.now()}.tmp`);
420
+ try {
421
+ await writeFile(tempPath, `${JSON.stringify(value, null, 2)}\n`, "utf-8");
422
+ await rename(tempPath, filePath);
423
+ }
424
+ catch (error) {
425
+ await rm(tempPath, { force: true }).catch(() => undefined);
426
+ throw error;
427
+ }
428
+ }
429
+ function isMissingFileError(error) {
430
+ return (error instanceof Error &&
431
+ "code" in error &&
432
+ error.code === "ENOENT");
433
+ }
434
+ export async function applyPiRetryMerge(input) {
435
+ const settingsPath = piSettingsPath(input.homeDir);
436
+ let raw;
437
+ try {
438
+ raw = await readFile(settingsPath, "utf-8");
439
+ }
440
+ catch (error) {
441
+ if (!isMissingFileError(error))
442
+ throw error;
443
+ raw = undefined;
444
+ }
445
+ if (raw === undefined) {
446
+ const plan = planPiRetryMerge(undefined);
447
+ if (plan.action === "write" && plan.next) {
448
+ await writeJsonAtomic(settingsPath, plan.next);
449
+ return { ...plan, path: settingsPath, wrote: true };
450
+ }
451
+ return { ...plan, path: settingsPath, wrote: false };
452
+ }
453
+ let parsed;
454
+ try {
455
+ parsed = JSON.parse(raw);
456
+ }
457
+ catch {
458
+ return {
459
+ action: "report",
460
+ reason: "invalid-json",
461
+ path: settingsPath,
462
+ wrote: false,
463
+ message: "Pi settings.json is not valid JSON; refusing to write",
464
+ };
465
+ }
466
+ if (!isRecord(parsed)) {
467
+ return {
468
+ action: "report",
469
+ reason: "invalid-json",
470
+ path: settingsPath,
471
+ wrote: false,
472
+ message: "Pi settings.json root must be a JSON object; refusing to write",
473
+ };
474
+ }
475
+ const plan = planPiRetryMerge(parsed);
476
+ if (plan.action === "write" && plan.next) {
477
+ await writeJsonAtomic(settingsPath, plan.next);
478
+ // Best-effort cleanup of any stray temp files from interrupted prior runs.
479
+ try {
480
+ const dir = path.dirname(settingsPath);
481
+ const entries = await readdir(dir);
482
+ await Promise.all(entries
483
+ .filter((name) => name.startsWith(`.${path.basename(settingsPath)}.`) &&
484
+ name.endsWith(".tmp"))
485
+ .map((name) => rm(path.join(dir, name), { force: true })));
486
+ }
487
+ catch {
488
+ // ignore cleanup failures
489
+ }
490
+ return { ...plan, path: settingsPath, wrote: true };
491
+ }
492
+ return { ...plan, path: settingsPath, wrote: false };
493
+ }
494
+ /**
495
+ * Stable generated source for the OpenCode project plugin.
496
+ * The plugin compensates only transient UnknownError after built-in retry is idle.
497
+ */
498
+ export function buildOpenCodeTransientRetryPluginSource() {
499
+ // Keep this template deterministic: no timestamps, no random ids.
500
+ return `/**
501
+ * loop-agent OpenCode transient recovery plugin
502
+ * Path: ${OPENCODE_TRANSIENT_RETRY_PLUGIN_PATH}
503
+ *
504
+ * Compensates transient UnknownError cases that OpenCode built-in APIError
505
+ * retry does not cover. Never runs concurrently with session.status === "retry".
506
+ * Permanent failures use interaction "${PERMANENT_ERROR_INTERACTION}".
507
+ * User aborts (MessageAbortedError / cancel words) are silently cleared.
508
+ * Best-effort file log: ${OPENCODE_TRANSIENT_RETRY_LOG_PATH}.
509
+ */
510
+ import path from "node:path";
511
+ import { fileURLToPath } from "node:url";
512
+ import { appendFile, mkdir } from "node:fs/promises";
513
+
514
+ const PLUGIN_PATH = ${JSON.stringify(OPENCODE_TRANSIENT_RETRY_PLUGIN_PATH)};
515
+ const LOG_FILE_NAME = ${JSON.stringify(path.basename(OPENCODE_TRANSIENT_RETRY_LOG_PATH))};
516
+ const LOG_PATH = (() => {
517
+ try {
518
+ const dir =
519
+ import.meta.dirname ?? path.dirname(fileURLToPath(import.meta.url));
520
+ return path.join(dir, LOG_FILE_NAME);
521
+ } catch {
522
+ return ${JSON.stringify(OPENCODE_TRANSIENT_RETRY_LOG_PATH)};
523
+ }
524
+ })();
525
+ const PERMANENT_INTERACTION = ${JSON.stringify(PERMANENT_ERROR_INTERACTION)};
526
+ const BACKOFF_MS = ${JSON.stringify([...BACKOFF_MS])};
527
+ const MAX_RETRIES = ${MAX_SESSION_RETRIES};
528
+ ${buildGeneratedContextOverflowPatternSource()}
529
+ void logToFile("load ok");
530
+
531
+ const sessionState = new Map();
532
+ const sessionStatus = new Map();
533
+ const pendingErrors = new Map();
534
+ const recoveryWorkers = new Map();
535
+
536
+ function getState(sessionId) {
537
+ let state = sessionState.get(sessionId);
538
+ if (!state) {
539
+ state = { attempt: 0, locked: false, rerunRequested: false };
540
+ sessionState.set(sessionId, state);
541
+ }
542
+ return state;
543
+ }
544
+
545
+ function textOf(error) {
546
+ if (!error) return "";
547
+ if (typeof error === "string") return error;
548
+ try {
549
+ return JSON.stringify(error);
550
+ } catch {
551
+ return String(error);
552
+ }
553
+ }
554
+
555
+ async function logToFile(line) {
556
+ try {
557
+ await mkdir(path.dirname(LOG_PATH), { recursive: true });
558
+ await appendFile(
559
+ LOG_PATH,
560
+ new Date().toISOString() + " " + line + "\\n",
561
+ "utf-8",
562
+ );
563
+ } catch {
564
+ // Best-effort observability log; never throw (ENOENT/EISDIR tolerated).
565
+ }
566
+ }
567
+
568
+ function isUserAbort(error) {
569
+ if (error && typeof error === "object" && typeof error.name === "string") {
570
+ if (/^MessageAbortedError$/i.test(error.name)) return true;
571
+ }
572
+ return /aborted by user|user cancel|cancelled|canceled/i.test(textOf(error));
573
+ }
574
+
575
+ function isPermanent(error) {
576
+ const text = textOf(error);
577
+ if (error && typeof error === "object" && typeof error.name === "string") {
578
+ if (/^APIError$/i.test(error.name)) return true;
579
+ if (/^(AuthError|PermissionError)$/i.test(error.name)) return true;
580
+ }
581
+ return (
582
+ OVERFLOW_PATTERN.test(text) ||
583
+ /\\b(401|403|unauthorized|forbidden|quota|rate.?limit|cancelled|canceled|business validation|invalid task|schema validation)\\b/i.test(text)
584
+ );
585
+ }
586
+
587
+ function isTransientUnknown(error) {
588
+ if (isPermanent(error)) return false;
589
+ const text = textOf(error);
590
+ const hasUnknown = /UnknownError/i.test(text) || (error && /UnknownError/i.test(String(error.name || "")));
591
+ const hasTypeValidation =
592
+ /\\bTypeValidationError\\b/i.test(text) ||
593
+ /Type validation failed/i.test(text) ||
594
+ (error && /TypeValidationError/i.test(String(error.name || "")));
595
+ if (!hasUnknown && !hasTypeValidation) return false;
596
+ return (
597
+ /\\b(code[:\\s]*502|502|LLMRequestError|network fluctuation|timeout|transient provider failure|non-standard)\\b/i.test(
598
+ text,
599
+ ) ||
600
+ (error && (error.code === 502 || error.status === 502))
601
+ );
602
+ }
603
+
604
+ function buildResumePrompt(sessionId, error, attempt) {
605
+ return [
606
+ "[loop-agent transient recovery] session=" + sessionId + " attempt=" + attempt,
607
+ "Previous model turn failed with a transient UnknownError: " + textOf(error),
608
+ "Before continuing any work, first inspect already completed tool calls and existing file modifications in this session.",
609
+ "Do not re-run side-effecting tools or rewrite files that already reflect successful prior work.",
610
+ "Resume only the remaining unfinished work after that check.",
611
+ "续接前请先检查本 session 已有工具调用与文件改动,避免重复执行有副作用的操作。",
612
+ ].join("\\n");
613
+ }
614
+
615
+ async function wait(ms) {
616
+ return new Promise((resolve) => setTimeout(resolve, ms));
617
+ }
618
+
619
+ function statusType(status) {
620
+ const type = status && typeof status.type === "string" ? status.type : undefined;
621
+ return type === "idle" || type === "retry" || type === "busy" ? type : undefined;
622
+ }
623
+
624
+ async function readSessionStatus(client, sessionId) {
625
+ const cached = sessionStatus.get(sessionId);
626
+ if (cached === "retry" || cached === "busy") {
627
+ return { ok: true, type: cached };
628
+ }
629
+ try {
630
+ const response = await client.session.status({ throwOnError: true });
631
+ if (!response || typeof response !== "object" || response.error != null) {
632
+ return { ok: false };
633
+ }
634
+ const current = statusType(response?.data?.[sessionId]);
635
+ if (!current) return { ok: false };
636
+ sessionStatus.set(sessionId, current);
637
+ return { ok: true, type: current };
638
+ } catch {
639
+ return { ok: false };
640
+ }
641
+ }
642
+
643
+ function promptWasAccepted(response) {
644
+ return Boolean(
645
+ response &&
646
+ typeof response === "object" &&
647
+ response.error == null &&
648
+ Object.prototype.hasOwnProperty.call(response, "data") &&
649
+ response.data !== null &&
650
+ typeof response.data === "object",
651
+ );
652
+ }
653
+
654
+ export default async function loopAgentTransientRetryPlugin({ client, $ }) {
655
+ void $;
656
+ void PLUGIN_PATH;
657
+ void logToFile("setup ok");
658
+
659
+ async function drainPendingRecovery(sessionId) {
660
+ const state = getState(sessionId);
661
+ const pending = pendingErrors.get(sessionId);
662
+ if (!pending) return;
663
+ if (state.attempt >= MAX_RETRIES) {
664
+ pendingErrors.delete(sessionId);
665
+ return;
666
+ }
667
+
668
+ // A status event may be stale by the time this worker runs. Confirm idle via
669
+ // the SDK before and after backoff; every other outcome keeps the error pending.
670
+ const beforeDelay = await readSessionStatus(client, sessionId);
671
+ if (pendingErrors.get(sessionId) !== pending) return;
672
+ if (!beforeDelay.ok || beforeDelay.type !== "idle") return;
673
+
674
+ const delay = BACKOFF_MS[state.attempt];
675
+ if (typeof delay !== "number") {
676
+ pendingErrors.delete(sessionId);
677
+ return;
678
+ }
679
+ await wait(delay);
680
+ if (pendingErrors.get(sessionId) !== pending) return;
681
+
682
+ const beforePrompt = await readSessionStatus(client, sessionId);
683
+ if (pendingErrors.get(sessionId) !== pending) return;
684
+ if (!beforePrompt.ok || beforePrompt.type !== "idle") return;
685
+
686
+ const nextAttempt = state.attempt + 1;
687
+ const prompt = buildResumePrompt(sessionId, pending.error, nextAttempt);
688
+ let response;
689
+ try {
690
+ response = await client.session.promptAsync({
691
+ path: { id: sessionId },
692
+ body: { parts: [{ type: "text", text: prompt }] },
693
+ throwOnError: true,
694
+ });
695
+ } catch {
696
+ void logToFile(
697
+ "prompt attempt=" + nextAttempt + " accepted=false session=" + sessionId,
698
+ );
699
+ return;
700
+ }
701
+ const accepted = promptWasAccepted(response);
702
+ void logToFile(
703
+ "prompt attempt=" + nextAttempt + " accepted=" + accepted + " session=" + sessionId,
704
+ );
705
+ if (!accepted) return;
706
+
707
+ state.attempt = nextAttempt;
708
+ if (pendingErrors.get(sessionId) === pending) {
709
+ pendingErrors.delete(sessionId);
710
+ }
711
+ }
712
+
713
+ function startRecoveryWorker(sessionId) {
714
+ const state = getState(sessionId);
715
+ if (recoveryWorkers.has(sessionId)) {
716
+ state.rerunRequested = true;
717
+ return;
718
+ }
719
+ state.locked = true;
720
+ state.rerunRequested = false;
721
+ void logToFile("worker start session=" + sessionId);
722
+ const worker = drainPendingRecovery(sessionId)
723
+ .catch(() => {})
724
+ .finally(() => {
725
+ void logToFile("worker end session=" + sessionId);
726
+ recoveryWorkers.delete(sessionId);
727
+ const rerun = state.rerunRequested;
728
+ state.rerunRequested = false;
729
+ state.locked = false;
730
+ if (rerun && pendingErrors.has(sessionId)) {
731
+ startRecoveryWorker(sessionId);
732
+ }
733
+ });
734
+ recoveryWorkers.set(sessionId, worker);
735
+ }
736
+
737
+ function clearSession(sessionId) {
738
+ pendingErrors.delete(sessionId);
739
+ sessionStatus.delete(sessionId);
740
+ const state = sessionState.get(sessionId);
741
+ if (state) {
742
+ state.attempt = 0;
743
+ state.rerunRequested = false;
744
+ if (!recoveryWorkers.has(sessionId)) state.locked = false;
745
+ }
746
+ }
747
+
748
+ return {
749
+ event: async ({ event }) => {
750
+ if (!event || typeof event !== "object") return;
751
+ const properties = event.properties || {};
752
+ const sessionId =
753
+ properties.sessionID || properties.sessionId || properties.id || properties.info?.id;
754
+
755
+ if (event.type === "session.status") {
756
+ const current = statusType(properties.status);
757
+ if (sessionId && current) sessionStatus.set(sessionId, current);
758
+ if (sessionId && current === "idle" && pendingErrors.has(sessionId)) {
759
+ startRecoveryWorker(sessionId);
760
+ }
761
+ return;
762
+ }
763
+
764
+ if (event.type === "session.idle") {
765
+ if (sessionId) {
766
+ sessionStatus.set(sessionId, "idle");
767
+ if (pendingErrors.has(sessionId)) startRecoveryWorker(sessionId);
768
+ }
769
+ return;
770
+ }
771
+
772
+ if (event.type === "session.deleted") {
773
+ if (sessionId) clearSession(sessionId);
774
+ return;
775
+ }
776
+
777
+ if (event.type === "message.updated") {
778
+ const info = properties.info;
779
+ if (
780
+ info?.role === "assistant" &&
781
+ info.sessionID &&
782
+ (info.status === undefined || info.status === "completed") &&
783
+ info.time?.completed != null &&
784
+ info.error == null
785
+ ) {
786
+ clearSession(info.sessionID);
787
+ }
788
+ return;
789
+ }
790
+
791
+ if (event.type === "session.error") {
792
+ if (!sessionId) return;
793
+ const error = properties.error || properties;
794
+ if (isUserAbort(error)) {
795
+ clearSession(sessionId);
796
+ void logToFile("classify abort session=" + sessionId);
797
+ return undefined;
798
+ }
799
+ if (!isTransientUnknown(error)) {
800
+ pendingErrors.delete(sessionId);
801
+ getState(sessionId).rerunRequested = false;
802
+ void logToFile("classify permanent session=" + sessionId);
803
+ return { interaction: PERMANENT_INTERACTION, reason: "plugin-ignore-permanent-error" };
804
+ }
805
+ pendingErrors.set(sessionId, { error });
806
+ void logToFile("classify transient session=" + sessionId);
807
+ startRecoveryWorker(sessionId);
808
+ return { pending: true };
809
+ }
810
+ },
811
+ };
812
+ }
813
+ `;
814
+ }
815
+ async function installGeneratedProjectFile(input) {
816
+ const target = path.join(input.repoRoot, input.relativePath);
817
+ if (input.onlyIfMissing) {
818
+ try {
819
+ await readFile(target, "utf-8");
820
+ return {
821
+ path: input.relativePath,
822
+ written: false,
823
+ reason: "unchanged",
824
+ };
825
+ }
826
+ catch {
827
+ // missing → write
828
+ }
829
+ }
830
+ await mkdir(path.dirname(target), { recursive: true });
831
+ await writeFile(target, input.content, "utf-8");
832
+ return { path: input.relativePath, written: true, reason: "written" };
833
+ }
834
+ export async function installProjectOpenCodePlugin(input) {
835
+ return installGeneratedProjectFile({
836
+ repoRoot: input.repoRoot,
837
+ relativePath: OPENCODE_TRANSIENT_RETRY_PLUGIN_PATH,
838
+ content: buildOpenCodeTransientRetryPluginSource(),
839
+ onlyIfMissing: input.onlyIfMissing,
840
+ });
841
+ }
842
+ /**
843
+ * Stable generated source for the OpenCode context-overflow compact plugin.
844
+ * Separate from transient-retry: only overflow → compact/summarize + limited resume.
845
+ */
846
+ export function buildOpenCodeContextOverflowCompactPluginSource() {
847
+ return `/**
848
+ * loop-agent OpenCode context overflow compact plugin
849
+ * Path: ${OPENCODE_CONTEXT_OVERFLOW_COMPACT_PLUGIN_PATH}
850
+ *
851
+ * On context overflow (including Chinese "请求上下文过大"), compact/summarize
852
+ * then resume the same session a limited number of times. Does NOT handle
853
+ * provider transport / 502 recovery (that is loop-agent-transient-retry.js).
854
+ */
855
+ const PLUGIN_PATH = ${JSON.stringify(OPENCODE_CONTEXT_OVERFLOW_COMPACT_PLUGIN_PATH)};
856
+ const MAX_OVERFLOW_RECOVERIES = ${MAX_OVERFLOW_RECOVERIES};
857
+ ${buildGeneratedContextOverflowPatternSource()}
858
+
859
+ const sessionState = new Map();
860
+ const sessionStatus = new Map();
861
+ const pendingOverflow = new Map();
862
+ const deferredResume = new Map();
863
+ const recoveryWorkers = new Map();
864
+
865
+ function getState(sessionId) {
866
+ let state = sessionState.get(sessionId);
867
+ if (!state) {
868
+ state = {
869
+ attempt: 0,
870
+ locked: false,
871
+ rerunRequested: false,
872
+ deferredIdleConfirmed: false,
873
+ };
874
+ sessionState.set(sessionId, state);
875
+ }
876
+ return state;
877
+ }
878
+
879
+ function textOf(error) {
880
+ if (!error) return "";
881
+ if (typeof error === "string") return error;
882
+ try {
883
+ return JSON.stringify(error);
884
+ } catch {
885
+ return String(error);
886
+ }
887
+ }
888
+
889
+ function isContextOverflow(error) {
890
+ return OVERFLOW_PATTERN.test(textOf(error));
891
+ }
892
+
893
+ function buildOverflowResumePrompt(sessionId, error, attempt) {
894
+ return [
895
+ "[loop-agent context overflow recovery] session=" + sessionId + " attempt=" + attempt,
896
+ "Previous model turn failed because the request context was too large: " + textOf(error),
897
+ "Session history was compacted/summarized before this resume.",
898
+ "Before continuing any work, first inspect already completed tool calls and existing file modifications in this session.",
899
+ "Do not re-run side-effecting tools or rewrite files that already reflect successful prior work.",
900
+ "Resume only the remaining unfinished work after that check.",
901
+ "续接前请先检查本 session 已有工具调用与文件改动,避免重复执行有副作用的操作。",
902
+ ].join("\\n");
903
+ }
904
+
905
+ function statusType(status) {
906
+ const type = status && typeof status.type === "string" ? status.type : undefined;
907
+ return type === "idle" || type === "retry" || type === "busy" ? type : undefined;
908
+ }
909
+
910
+ async function readSessionStatus(client, sessionId) {
911
+ const cached = sessionStatus.get(sessionId);
912
+ if (cached === "retry" || cached === "busy") {
913
+ return { ok: true, type: cached };
914
+ }
915
+ try {
916
+ const response = await client.session.status({ throwOnError: true });
917
+ if (!response || typeof response !== "object" || response.error != null) {
918
+ return { ok: false };
919
+ }
920
+ const current = statusType(response?.data?.[sessionId]);
921
+ if (!current) return { ok: false };
922
+ sessionStatus.set(sessionId, current);
923
+ return { ok: true, type: current };
924
+ } catch {
925
+ return { ok: false };
926
+ }
927
+ }
928
+
929
+ function promptWasAccepted(response) {
930
+ return Boolean(
931
+ response &&
932
+ typeof response === "object" &&
933
+ response.error == null &&
934
+ Object.prototype.hasOwnProperty.call(response, "data") &&
935
+ response.data !== null &&
936
+ typeof response.data === "object",
937
+ );
938
+ }
939
+
940
+ async function compactOrSummarize(client, sessionId) {
941
+ const body = { path: { id: sessionId }, throwOnError: true };
942
+ if (typeof client.session.compact === "function") {
943
+ await client.session.compact(body);
944
+ return "compact";
945
+ }
946
+ if (typeof client.session.summarize === "function") {
947
+ await client.session.summarize(body);
948
+ return "summarize";
949
+ }
950
+ throw new Error("session.compact and session.summarize are unavailable");
951
+ }
952
+
953
+ export default async function loopAgentContextOverflowCompactPlugin({ client, $ }) {
954
+ void $;
955
+ void PLUGIN_PATH;
956
+
957
+ async function promptDeferredResume(sessionId, idleConfirmed = false) {
958
+ const deferred = deferredResume.get(sessionId);
959
+ if (!deferred) return;
960
+
961
+ if (!idleConfirmed) {
962
+ const status = await readSessionStatus(client, sessionId);
963
+ if (deferredResume.get(sessionId) !== deferred) return;
964
+ if (!status.ok || status.type !== "idle") return;
965
+ }
966
+
967
+ // An explicit idle event is authoritative even if the SDK status snapshot
968
+ // still lags at busy. Keep deferred facts until promptAsync is accepted so
969
+ // later idle can retry without another compact/summarize.
970
+ const prompt = buildOverflowResumePrompt(sessionId, deferred.error, deferred.attempt);
971
+ let response;
972
+ try {
973
+ response = await client.session.promptAsync({
974
+ path: { id: sessionId },
975
+ body: { parts: [{ type: "text", text: prompt }] },
976
+ throwOnError: true,
977
+ });
978
+ } catch {
979
+ return;
980
+ }
981
+ if (deferredResume.get(sessionId) !== deferred) return;
982
+ if (!promptWasAccepted(response)) return;
983
+ deferredResume.delete(sessionId);
984
+ getState(sessionId).deferredIdleConfirmed = false;
985
+ }
986
+
987
+ async function drainPendingOverflow(sessionId) {
988
+ const state = getState(sessionId);
989
+ // Deferred resume path: only promptAsync, never compact/summarize again.
990
+ if (deferredResume.has(sessionId)) {
991
+ const idleConfirmed = state.deferredIdleConfirmed;
992
+ state.deferredIdleConfirmed = false;
993
+ await promptDeferredResume(sessionId, idleConfirmed);
994
+ return;
995
+ }
996
+
997
+ const pending = pendingOverflow.get(sessionId);
998
+ if (!pending) return;
999
+ if (state.attempt >= MAX_OVERFLOW_RECOVERIES) {
1000
+ pendingOverflow.delete(sessionId);
1001
+ return;
1002
+ }
1003
+
1004
+ const before = await readSessionStatus(client, sessionId);
1005
+ if (pendingOverflow.get(sessionId) !== pending) return;
1006
+ if (!before.ok || before.type !== "idle") return;
1007
+
1008
+ try {
1009
+ await compactOrSummarize(client, sessionId);
1010
+ } catch {
1011
+ // Compact itself failed: do not consume budget (no compact side-effect yet).
1012
+ return;
1013
+ }
1014
+ // Session cleanup may remove this work while compact is in flight. Do not
1015
+ // let that stale worker consume the reset budget or recreate deferred state.
1016
+ // Concurrent overflow cannot replace pending because session.error preserves
1017
+ // the first in-flight recovery facts below.
1018
+ if (pendingOverflow.get(sessionId) !== pending) return;
1019
+
1020
+ // Consume budget immediately and exactly once after an active recovery's
1021
+ // successful compact/summarize.
1022
+ const nextAttempt = Math.min(state.attempt + 1, MAX_OVERFLOW_RECOVERIES);
1023
+ state.attempt = nextAttempt;
1024
+ pendingOverflow.delete(sessionId);
1025
+ // Keep resume facts across temporary post-compact busy/unknown status.
1026
+ deferredResume.set(sessionId, { error: pending.error, attempt: nextAttempt });
1027
+ await promptDeferredResume(sessionId);
1028
+ }
1029
+
1030
+ function startRecoveryWorker(sessionId, deferredIdleConfirmed = false) {
1031
+ const state = getState(sessionId);
1032
+ if (deferredIdleConfirmed && deferredResume.has(sessionId)) {
1033
+ state.deferredIdleConfirmed = true;
1034
+ }
1035
+ if (recoveryWorkers.has(sessionId)) {
1036
+ state.rerunRequested = true;
1037
+ return;
1038
+ }
1039
+ state.locked = true;
1040
+ state.rerunRequested = false;
1041
+ const worker = drainPendingOverflow(sessionId)
1042
+ .catch(() => {})
1043
+ .finally(() => {
1044
+ recoveryWorkers.delete(sessionId);
1045
+ const rerun = state.rerunRequested;
1046
+ state.rerunRequested = false;
1047
+ state.locked = false;
1048
+ if (rerun && (pendingOverflow.has(sessionId) || deferredResume.has(sessionId))) {
1049
+ startRecoveryWorker(sessionId);
1050
+ }
1051
+ });
1052
+ recoveryWorkers.set(sessionId, worker);
1053
+ }
1054
+
1055
+ function clearSession(sessionId) {
1056
+ pendingOverflow.delete(sessionId);
1057
+ deferredResume.delete(sessionId);
1058
+ sessionStatus.delete(sessionId);
1059
+ const state = sessionState.get(sessionId);
1060
+ if (state) {
1061
+ state.attempt = 0;
1062
+ state.rerunRequested = false;
1063
+ state.deferredIdleConfirmed = false;
1064
+ if (!recoveryWorkers.has(sessionId)) state.locked = false;
1065
+ }
1066
+ }
1067
+
1068
+ function hasWork(sessionId) {
1069
+ return pendingOverflow.has(sessionId) || deferredResume.has(sessionId);
1070
+ }
1071
+
1072
+ return {
1073
+ event: async ({ event }) => {
1074
+ if (!event || typeof event !== "object") return;
1075
+ const properties = event.properties || {};
1076
+ const sessionId =
1077
+ properties.sessionID || properties.sessionId || properties.id || properties.info?.id;
1078
+
1079
+ if (event.type === "session.status") {
1080
+ const current = statusType(properties.status);
1081
+ if (sessionId && current) sessionStatus.set(sessionId, current);
1082
+ if (sessionId && current === "idle" && hasWork(sessionId)) {
1083
+ startRecoveryWorker(sessionId, deferredResume.has(sessionId));
1084
+ }
1085
+ return;
1086
+ }
1087
+
1088
+ if (event.type === "session.idle") {
1089
+ if (sessionId) {
1090
+ sessionStatus.set(sessionId, "idle");
1091
+ if (hasWork(sessionId)) {
1092
+ startRecoveryWorker(sessionId, deferredResume.has(sessionId));
1093
+ }
1094
+ }
1095
+ return;
1096
+ }
1097
+
1098
+ if (event.type === "session.deleted") {
1099
+ if (sessionId) clearSession(sessionId);
1100
+ return;
1101
+ }
1102
+
1103
+ if (event.type === "message.updated") {
1104
+ const info = properties.info;
1105
+ if (
1106
+ info?.role === "assistant" &&
1107
+ info.sessionID &&
1108
+ (info.status === undefined || info.status === "completed") &&
1109
+ info.time?.completed != null &&
1110
+ info.error == null
1111
+ ) {
1112
+ clearSession(info.sessionID);
1113
+ }
1114
+ return;
1115
+ }
1116
+
1117
+ if (event.type === "session.error") {
1118
+ if (!sessionId) return;
1119
+ const error = properties.error || properties;
1120
+ if (!isContextOverflow(error)) {
1121
+ return;
1122
+ }
1123
+ if (getState(sessionId).attempt >= MAX_OVERFLOW_RECOVERIES) {
1124
+ pendingOverflow.delete(sessionId);
1125
+ return { interaction: "plugin-ignore-overflow-cap", reason: "plugin-ignore-overflow-cap" };
1126
+ }
1127
+ // Preserve the first overflow facts while compact or deferred resume is
1128
+ // in flight. Concurrent overflow must not replace them or queue compact.
1129
+ if (pendingOverflow.has(sessionId) || deferredResume.has(sessionId)) {
1130
+ return { pending: true };
1131
+ }
1132
+ pendingOverflow.set(sessionId, { error });
1133
+ startRecoveryWorker(sessionId);
1134
+ return { pending: true };
1135
+ }
1136
+ },
1137
+ };
1138
+ }
1139
+ `;
1140
+ }
1141
+ export async function installProjectOpenCodeOverflowCompactPlugin(input) {
1142
+ return installGeneratedProjectFile({
1143
+ repoRoot: input.repoRoot,
1144
+ relativePath: OPENCODE_CONTEXT_OVERFLOW_COMPACT_PLUGIN_PATH,
1145
+ content: buildOpenCodeContextOverflowCompactPluginSource(),
1146
+ onlyIfMissing: input.onlyIfMissing,
1147
+ });
1148
+ }
1149
+ /**
1150
+ * Project-level Pi extension: normalize overflow errorMessage so native Pi
1151
+ * overflow → compact → retry can fire. Does not touch settings or model windows.
1152
+ */
1153
+ export function buildPiContextOverflowExtensionSource() {
1154
+ return `/**
1155
+ * loop-agent Pi context overflow extension
1156
+ * Path: ${PI_CONTEXT_OVERFLOW_EXTENSION_PATH}
1157
+ *
1158
+ * On assistant message_end, rewrite overflow errorMessage to start with
1159
+ * "context_length_exceeded:" so Pi's native overflow recovery can run.
1160
+ * Idempotent. Does not write user settings or model context windows.
1161
+ */
1162
+ const EXTENSION_PATH = ${JSON.stringify(PI_CONTEXT_OVERFLOW_EXTENSION_PATH)};
1163
+ ${buildGeneratedContextOverflowPatternSource()}
1164
+ const NORMALIZED_PREFIX = "context_length_exceeded:";
1165
+
1166
+ function isOverflowMessage(text) {
1167
+ if (typeof text !== "string" || !text) return false;
1168
+ return OVERFLOW_PATTERN.test(text);
1169
+ }
1170
+
1171
+ export default function loopAgentContextOverflowExtension(pi) {
1172
+ void EXTENSION_PATH;
1173
+ pi.on("message_end", (event) => {
1174
+ const message = event && event.message;
1175
+ if (!message || message.role !== "assistant") return;
1176
+ const current = message.errorMessage;
1177
+ if (typeof current !== "string" || !current) return;
1178
+ if (current.startsWith(NORMALIZED_PREFIX) || /context_length_exceeded/i.test(current)) {
1179
+ return;
1180
+ }
1181
+ if (!isOverflowMessage(current)) return;
1182
+ return {
1183
+ message: {
1184
+ ...message,
1185
+ errorMessage: NORMALIZED_PREFIX + " " + current,
1186
+ },
1187
+ };
1188
+ });
1189
+ }
1190
+ `;
1191
+ }
1192
+ export async function installProjectPiContextOverflowExtension(input) {
1193
+ return installGeneratedProjectFile({
1194
+ repoRoot: input.repoRoot,
1195
+ relativePath: PI_CONTEXT_OVERFLOW_EXTENSION_PATH,
1196
+ content: buildPiContextOverflowExtensionSource(),
1197
+ onlyIfMissing: input.onlyIfMissing,
1198
+ });
1199
+ }
1200
+ /**
1201
+ * Nested merge plan for the project-owned Pi settings surface. Existing values
1202
+ * (including explicit disabled flags) always win over recommendations.
1203
+ */
1204
+ export function planProjectPiSettingsMerge(existing) {
1205
+ if (existing === undefined) {
1206
+ return {
1207
+ action: "write",
1208
+ reason: "missing-file",
1209
+ path: PI_PROJECT_SETTINGS_PATH,
1210
+ next: {
1211
+ retry: { ...PI_RECOMMENDED_RETRY, provider: { ...PI_RECOMMENDED_RETRY.provider } },
1212
+ compaction: { ...PI_RECOMMENDED_COMPACTION },
1213
+ },
1214
+ };
1215
+ }
1216
+ if (!isRecord(existing)) {
1217
+ return {
1218
+ action: "report",
1219
+ reason: "invalid-json",
1220
+ path: PI_PROJECT_SETTINGS_PATH,
1221
+ message: "project .pi/settings.json root must be a JSON object",
1222
+ };
1223
+ }
1224
+ const retryPlan = planPiRetryMerge(existing);
1225
+ if (retryPlan.reason === "invalid-json") {
1226
+ return { ...retryPlan, path: PI_PROJECT_SETTINGS_PATH };
1227
+ }
1228
+ const retryDisabled = retryPlan.reason === "enabled-false";
1229
+ const next = retryPlan.next ? { ...retryPlan.next } : { ...existing };
1230
+ const compaction = isRecord(next.compaction) ? { ...next.compaction } : {};
1231
+ let changed = (!retryDisabled && retryPlan.action === "write") ||
1232
+ !isRecord(next.compaction);
1233
+ if (compaction.enabled === undefined) {
1234
+ compaction.enabled = PI_RECOMMENDED_COMPACTION.enabled;
1235
+ changed = true;
1236
+ }
1237
+ next.compaction = compaction;
1238
+ if (changed) {
1239
+ return {
1240
+ action: "write",
1241
+ reason: "missing-fields",
1242
+ path: PI_PROJECT_SETTINGS_PATH,
1243
+ next,
1244
+ };
1245
+ }
1246
+ if (retryDisabled) {
1247
+ return {
1248
+ action: "report",
1249
+ reason: "enabled-false",
1250
+ path: PI_PROJECT_SETTINGS_PATH,
1251
+ next,
1252
+ message: "retry.enabled=false is preserved; compaction settings already require no migration",
1253
+ };
1254
+ }
1255
+ return {
1256
+ action: "noop",
1257
+ reason: "matches",
1258
+ path: PI_PROJECT_SETTINGS_PATH,
1259
+ next,
1260
+ };
1261
+ }
1262
+ async function readJsonMergeTarget(filePath) {
1263
+ try {
1264
+ return JSON.parse(await readFile(filePath, "utf-8"));
1265
+ }
1266
+ catch (error) {
1267
+ if (isMissingFileError(error))
1268
+ return undefined;
1269
+ if (error instanceof SyntaxError)
1270
+ return "__invalid_json__";
1271
+ throw error;
1272
+ }
1273
+ }
1274
+ export async function inspectProjectPiSettings(input) {
1275
+ const settingsPath = path.join(input.repoRoot, PI_PROJECT_SETTINGS_PATH);
1276
+ const parsed = await readJsonMergeTarget(settingsPath);
1277
+ if (parsed === "__invalid_json__") {
1278
+ return { action: "report", reason: "invalid-json", path: PI_PROJECT_SETTINGS_PATH, wrote: false };
1279
+ }
1280
+ return { ...planProjectPiSettingsMerge(parsed), wrote: false };
1281
+ }
1282
+ export async function applyProjectPiSettingsMerge(input) {
1283
+ const settingsPath = path.join(input.repoRoot, PI_PROJECT_SETTINGS_PATH);
1284
+ const parsed = await readJsonMergeTarget(settingsPath);
1285
+ if (parsed === "__invalid_json__") {
1286
+ return { action: "report", reason: "invalid-json", path: PI_PROJECT_SETTINGS_PATH, wrote: false, message: "project .pi/settings.json is not valid JSON; refusing to write" };
1287
+ }
1288
+ const plan = planProjectPiSettingsMerge(parsed);
1289
+ if (plan.action === "write" && plan.next) {
1290
+ await writeJsonAtomic(settingsPath, plan.next);
1291
+ return { ...plan, wrote: true };
1292
+ }
1293
+ return { ...plan, wrote: false };
1294
+ }
1295
+ export function buildProjectPiSettingsSource() {
1296
+ return `${JSON.stringify({ retry: PI_RECOMMENDED_RETRY, compaction: PI_RECOMMENDED_COMPACTION }, null, 2)}\n`;
1297
+ }
1298
+ export async function inspectPiRetryConfig(input) {
1299
+ const homeDir = input.homeDir ?? os.homedir();
1300
+ const settingsPath = piSettingsPath(homeDir);
1301
+ let raw;
1302
+ try {
1303
+ raw = await readFile(settingsPath, "utf-8");
1304
+ }
1305
+ catch (error) {
1306
+ if (!isMissingFileError(error))
1307
+ throw error;
1308
+ return {
1309
+ action: "report",
1310
+ reason: "missing-file",
1311
+ path: settingsPath,
1312
+ wrote: false,
1313
+ };
1314
+ }
1315
+ try {
1316
+ const parsed = JSON.parse(raw);
1317
+ if (!isRecord(parsed)) {
1318
+ return {
1319
+ action: "report",
1320
+ reason: "invalid-json",
1321
+ path: settingsPath,
1322
+ wrote: false,
1323
+ };
1324
+ }
1325
+ const plan = planPiRetryMerge(parsed);
1326
+ return { ...plan, path: settingsPath, wrote: false };
1327
+ }
1328
+ catch {
1329
+ return {
1330
+ action: "report",
1331
+ reason: "invalid-json",
1332
+ path: settingsPath,
1333
+ wrote: false,
1334
+ };
1335
+ }
1336
+ }
1337
+ function skippedInstall(relativePath) {
1338
+ return { path: relativePath, written: false, reason: "skipped" };
1339
+ }
1340
+ /**
1341
+ * Install project recovery artifacts and optionally merge Pi user settings.
1342
+ * - auto/project: recovery plugins/extensions plus project `.pi/settings.json` (no home writes)
1343
+ * - user: the same project files plus explicit legacy Pi home retry merge
1344
+ * - off: skip all
1345
+ */
1346
+ export async function runClientRecovery(input) {
1347
+ const mode = input.mode ?? "auto";
1348
+ if (mode === "off") {
1349
+ return {
1350
+ mode,
1351
+ plugin: skippedInstall(OPENCODE_TRANSIENT_RETRY_PLUGIN_PATH),
1352
+ overflowPlugin: skippedInstall(OPENCODE_CONTEXT_OVERFLOW_COMPACT_PLUGIN_PATH),
1353
+ piExtension: skippedInstall(PI_CONTEXT_OVERFLOW_EXTENSION_PATH),
1354
+ pi: { action: "report", reason: "skipped-mode", path: PI_PROJECT_SETTINGS_PATH, wrote: false },
1355
+ };
1356
+ }
1357
+ const plugin = await installProjectOpenCodePlugin({
1358
+ repoRoot: input.repoRoot,
1359
+ });
1360
+ const overflowPlugin = await installProjectOpenCodeOverflowCompactPlugin({
1361
+ repoRoot: input.repoRoot,
1362
+ });
1363
+ const piExtension = await installProjectPiContextOverflowExtension({
1364
+ repoRoot: input.repoRoot,
1365
+ });
1366
+ const pi = await applyProjectPiSettingsMerge({ repoRoot: input.repoRoot });
1367
+ if (mode !== "user") {
1368
+ return { mode, plugin, overflowPlugin, piExtension, pi };
1369
+ }
1370
+ const homeDir = input.homeDir ?? os.homedir();
1371
+ const userPi = await applyPiRetryMerge({ homeDir });
1372
+ return { mode, plugin, overflowPlugin, piExtension, pi, userPi };
1373
+ }