agent-control-plane 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +589 -0
  3. package/SKILL.md +149 -0
  4. package/assets/workflow-catalog.json +57 -0
  5. package/bin/audit-issue-routing.sh +74 -0
  6. package/bin/issue-resource-class.sh +58 -0
  7. package/bin/label-follow-up-issues.sh +114 -0
  8. package/bin/pr-risk.sh +532 -0
  9. package/bin/sync-pr-labels.sh +112 -0
  10. package/hooks/heartbeat-hooks.sh +573 -0
  11. package/hooks/issue-reconcile-hooks.sh +217 -0
  12. package/hooks/pr-reconcile-hooks.sh +225 -0
  13. package/npm/bin/agent-control-plane.js +1984 -0
  14. package/npm/public-bin/agent-control-plane +3 -0
  15. package/package.json +61 -0
  16. package/tools/bin/agent-cleanup-worktree +247 -0
  17. package/tools/bin/agent-github-update-labels +66 -0
  18. package/tools/bin/agent-init-worktree +216 -0
  19. package/tools/bin/agent-project-archive-run +52 -0
  20. package/tools/bin/agent-project-capture-worker +46 -0
  21. package/tools/bin/agent-project-catch-up-merged-prs +137 -0
  22. package/tools/bin/agent-project-cleanup-session +244 -0
  23. package/tools/bin/agent-project-detached-launch +107 -0
  24. package/tools/bin/agent-project-heartbeat-loop +2347 -0
  25. package/tools/bin/agent-project-open-issue-worktree +89 -0
  26. package/tools/bin/agent-project-open-pr-worktree +80 -0
  27. package/tools/bin/agent-project-publish-issue-pr +349 -0
  28. package/tools/bin/agent-project-reconcile-issue-session +1128 -0
  29. package/tools/bin/agent-project-reconcile-pr-session +1005 -0
  30. package/tools/bin/agent-project-retry-state +147 -0
  31. package/tools/bin/agent-project-run-claude-session +657 -0
  32. package/tools/bin/agent-project-run-codex-resilient +718 -0
  33. package/tools/bin/agent-project-run-codex-session +316 -0
  34. package/tools/bin/agent-project-run-kilo-session +27 -0
  35. package/tools/bin/agent-project-run-openclaw-session +984 -0
  36. package/tools/bin/agent-project-run-opencode-session +27 -0
  37. package/tools/bin/agent-project-sync-anchor-repo +128 -0
  38. package/tools/bin/agent-project-worker-status +143 -0
  39. package/tools/bin/audit-agent-worktrees.sh +310 -0
  40. package/tools/bin/audit-issue-routing.sh +11 -0
  41. package/tools/bin/audit-retained-layout.sh +58 -0
  42. package/tools/bin/audit-retained-overlap.sh +135 -0
  43. package/tools/bin/audit-retained-worktrees.sh +228 -0
  44. package/tools/bin/branch-verification-guard.sh +351 -0
  45. package/tools/bin/capture-worker.sh +18 -0
  46. package/tools/bin/check-skill-contracts.sh +324 -0
  47. package/tools/bin/cleanup-worktree.sh +44 -0
  48. package/tools/bin/codex-quota +31 -0
  49. package/tools/bin/create-follow-up-issue.sh +114 -0
  50. package/tools/bin/dashboard-launchd-bootstrap.sh +38 -0
  51. package/tools/bin/flow-config-lib.sh +2127 -0
  52. package/tools/bin/flow-resident-worker-lib.sh +683 -0
  53. package/tools/bin/flow-runtime-doctor.sh +97 -0
  54. package/tools/bin/flow-shell-lib.sh +266 -0
  55. package/tools/bin/heartbeat-recovery-preflight.sh +106 -0
  56. package/tools/bin/heartbeat-safe-auto.sh +551 -0
  57. package/tools/bin/install-dashboard-launchd.sh +152 -0
  58. package/tools/bin/install-project-launchd.sh +219 -0
  59. package/tools/bin/issue-publish-scope-guard.sh +242 -0
  60. package/tools/bin/issue-requires-local-workspace-install.sh +31 -0
  61. package/tools/bin/issue-resource-class.sh +12 -0
  62. package/tools/bin/kick-scheduler.sh +75 -0
  63. package/tools/bin/label-follow-up-issues.sh +14 -0
  64. package/tools/bin/new-pr-worktree.sh +50 -0
  65. package/tools/bin/new-worktree.sh +49 -0
  66. package/tools/bin/pr-risk.sh +12 -0
  67. package/tools/bin/prepare-worktree.sh +140 -0
  68. package/tools/bin/profile-activate.sh +109 -0
  69. package/tools/bin/profile-adopt.sh +219 -0
  70. package/tools/bin/profile-smoke.sh +461 -0
  71. package/tools/bin/project-init.sh +189 -0
  72. package/tools/bin/project-launchd-bootstrap.sh +54 -0
  73. package/tools/bin/project-remove.sh +155 -0
  74. package/tools/bin/project-runtime-supervisor.sh +56 -0
  75. package/tools/bin/project-runtimectl.sh +586 -0
  76. package/tools/bin/provider-cooldown-state.sh +166 -0
  77. package/tools/bin/publish-issue-worker.sh +31 -0
  78. package/tools/bin/reconcile-issue-worker.sh +34 -0
  79. package/tools/bin/reconcile-pr-worker.sh +34 -0
  80. package/tools/bin/record-verification.sh +71 -0
  81. package/tools/bin/render-architecture-infographics.sh +110 -0
  82. package/tools/bin/render-dashboard-demo-media.sh +333 -0
  83. package/tools/bin/render-dashboard-snapshot.py +16 -0
  84. package/tools/bin/render-flow-config.sh +86 -0
  85. package/tools/bin/retry-state.sh +31 -0
  86. package/tools/bin/reuse-issue-worktree.sh +75 -0
  87. package/tools/bin/run-codex-bypass.sh +3 -0
  88. package/tools/bin/run-codex-safe.sh +3 -0
  89. package/tools/bin/run-codex-task.sh +231 -0
  90. package/tools/bin/scaffold-profile.sh +374 -0
  91. package/tools/bin/serve-dashboard.sh +5 -0
  92. package/tools/bin/split-retained-slice.sh +124 -0
  93. package/tools/bin/start-issue-worker.sh +796 -0
  94. package/tools/bin/start-pr-fix-worker.sh +458 -0
  95. package/tools/bin/start-pr-merge-repair-worker.sh +8 -0
  96. package/tools/bin/start-pr-review-worker.sh +227 -0
  97. package/tools/bin/start-resident-issue-loop.sh +908 -0
  98. package/tools/bin/sync-agent-repo.sh +52 -0
  99. package/tools/bin/sync-dependency-baseline.sh +247 -0
  100. package/tools/bin/sync-pr-labels.sh +12 -0
  101. package/tools/bin/sync-recurring-issue-checklist.sh +274 -0
  102. package/tools/bin/sync-shared-agent-home.sh +214 -0
  103. package/tools/bin/sync-vscode-workspace.sh +157 -0
  104. package/tools/bin/test-smoke.sh +63 -0
  105. package/tools/bin/uninstall-project-launchd.sh +55 -0
  106. package/tools/bin/update-github-labels.sh +14 -0
  107. package/tools/bin/worker-status.sh +19 -0
  108. package/tools/bin/workflow-catalog.sh +77 -0
  109. package/tools/dashboard/app.js +286 -0
  110. package/tools/dashboard/dashboard_snapshot.py +466 -0
  111. package/tools/dashboard/index.html +41 -0
  112. package/tools/dashboard/server.py +64 -0
  113. package/tools/dashboard/styles.css +351 -0
  114. package/tools/templates/issue-prompt-template.md +109 -0
  115. package/tools/templates/pr-fix-template.md +120 -0
  116. package/tools/templates/pr-merge-repair-template.md +91 -0
  117. package/tools/templates/pr-review-template.md +62 -0
  118. package/tools/templates/scheduled-issue-prompt-template.md +62 -0
  119. package/tools/tests/test-agent-control-plane-npm-cli.sh +279 -0
  120. package/tools/tests/test-agent-github-update-labels-falls-back-to-repository-id.sh +56 -0
  121. package/tools/tests/test-agent-project-claude-session-wrapper-clears-stale-sandbox-artifacts.sh +89 -0
  122. package/tools/tests/test-agent-project-claude-session-wrapper-does-not-retry-provider-quota.sh +82 -0
  123. package/tools/tests/test-agent-project-claude-session-wrapper-retries-transient-failures.sh +90 -0
  124. package/tools/tests/test-agent-project-claude-session-wrapper-times-out.sh +73 -0
  125. package/tools/tests/test-agent-project-claude-session-wrapper.sh +103 -0
  126. package/tools/tests/test-agent-project-cleanup-session-orphan-fallback.sh +90 -0
  127. package/tools/tests/test-agent-project-cleanup-session-skip-worktree-cleanup.sh +90 -0
  128. package/tools/tests/test-agent-project-codex-live-thread-persist.sh +76 -0
  129. package/tools/tests/test-agent-project-codex-recovery.sh +731 -0
  130. package/tools/tests/test-agent-project-codex-session-wrapper-clears-stale-sandbox-artifacts.sh +105 -0
  131. package/tools/tests/test-agent-project-codex-session-wrapper.sh +97 -0
  132. package/tools/tests/test-agent-project-open-pr-worktree-config-prefix.sh +81 -0
  133. package/tools/tests/test-agent-project-openclaw-session-wrapper-clears-stale-sandbox-artifacts.sh +109 -0
  134. package/tools/tests/test-agent-project-openclaw-session-wrapper-infers-blocked-result-contract.sh +89 -0
  135. package/tools/tests/test-agent-project-openclaw-session-wrapper-recovers-literal-env-artifacts.sh +113 -0
  136. package/tools/tests/test-agent-project-openclaw-session-wrapper-recovers-version-mismatch.sh +135 -0
  137. package/tools/tests/test-agent-project-openclaw-session-wrapper-resident.sh +179 -0
  138. package/tools/tests/test-agent-project-openclaw-session-wrapper-reuses-existing-agent-after-add-race.sh +119 -0
  139. package/tools/tests/test-agent-project-openclaw-session-wrapper-terminates-rate-limit-hang.sh +91 -0
  140. package/tools/tests/test-agent-project-openclaw-session-wrapper.sh +117 -0
  141. package/tools/tests/test-agent-project-publish-issue-pr-prunes-stale-worktree-entry.sh +148 -0
  142. package/tools/tests/test-agent-project-publish-issue-pr-reads-archived-session.sh +146 -0
  143. package/tools/tests/test-agent-project-publish-issue-pr-recovers-final-head.sh +145 -0
  144. package/tools/tests/test-agent-project-publish-issue-pr-reuses-existing-worktree.sh +147 -0
  145. package/tools/tests/test-agent-project-reconcile-failure-reason.sh +456 -0
  146. package/tools/tests/test-agent-project-reconcile-issue-archived-session-fallback.sh +96 -0
  147. package/tools/tests/test-agent-project-reconcile-issue-before-blocked.sh +90 -0
  148. package/tools/tests/test-agent-project-reconcile-issue-host-verification-recovery-uses-recovered-worktree.sh +212 -0
  149. package/tools/tests/test-agent-project-reconcile-issue-host-verification-recovery.sh +207 -0
  150. package/tools/tests/test-agent-project-reconcile-issue-provider-quota-schedules-provider-cooldown.sh +101 -0
  151. package/tools/tests/test-agent-project-reconcile-issue-session-backfills-lane-metadata-from-worker-key.sh +113 -0
  152. package/tools/tests/test-agent-project-reconcile-issue-session-clears-stale-failed-summary.sh +117 -0
  153. package/tools/tests/test-agent-project-reconcile-issue-session-initializes-shared-agent-home.sh +55 -0
  154. package/tools/tests/test-agent-project-reconcile-issue-session-normalizes-runner-state.sh +125 -0
  155. package/tools/tests/test-agent-project-reconcile-issue-session-records-invalid-contract-summary.sh +118 -0
  156. package/tools/tests/test-agent-project-reconcile-issue-session-skips-duplicate-blocked-comment.sh +144 -0
  157. package/tools/tests/test-agent-project-reconcile-issue-session-standardizes-no-commits-blocker.sh +145 -0
  158. package/tools/tests/test-agent-project-reconcile-issue-session-synthesizes-blocked-comment.sh +139 -0
  159. package/tools/tests/test-agent-project-reconcile-pr-blocked-host-recovery.sh +242 -0
  160. package/tools/tests/test-agent-project-reconcile-pr-guard-blocked-no-commit.sh +142 -0
  161. package/tools/tests/test-agent-project-reconcile-pr-provider-quota-schedules-provider-cooldown.sh +106 -0
  162. package/tools/tests/test-agent-project-reconcile-pr-session-initializes-shared-agent-home.sh +66 -0
  163. package/tools/tests/test-agent-project-reconcile-pr-updated-branch-noop.sh +129 -0
  164. package/tools/tests/test-audit-agent-worktrees-active-launch-skips-git-inspection.sh +69 -0
  165. package/tools/tests/test-audit-agent-worktrees-broken-worktree.sh +43 -0
  166. package/tools/tests/test-audit-agent-worktrees-pending-launch-owner.sh +46 -0
  167. package/tools/tests/test-audit-agent-worktrees-unreconciled-owner.sh +79 -0
  168. package/tools/tests/test-audit-issue-routing-managed-branch-globs.sh +56 -0
  169. package/tools/tests/test-branch-verification-guard-generated-artifacts.sh +72 -0
  170. package/tools/tests/test-branch-verification-guard-targeted-coverage.sh +125 -0
  171. package/tools/tests/test-codex-quota-manager-failure-driven-rotation.sh +178 -0
  172. package/tools/tests/test-codex-quota-wrapper.sh +37 -0
  173. package/tools/tests/test-contribution-docs.sh +18 -0
  174. package/tools/tests/test-control-plane-dashboard-runtime-smoke.sh +343 -0
  175. package/tools/tests/test-create-follow-up-issue.sh +73 -0
  176. package/tools/tests/test-dashboard-launchd-bootstrap.sh +55 -0
  177. package/tools/tests/test-flow-export-execution-env-exports-repo-id.sh +30 -0
  178. package/tools/tests/test-flow-export-github-cli-auth-env-prefers-git-credential.sh +48 -0
  179. package/tools/tests/test-flow-github-api-repo-fallback-preserves-input.sh +85 -0
  180. package/tools/tests/test-flow-github-api-repo-prefers-explicit-repository-id.sh +60 -0
  181. package/tools/tests/test-flow-github-issue-list-falls-back-to-repository-id.sh +64 -0
  182. package/tools/tests/test-flow-github-pr-list-falls-back-to-repository-id.sh +77 -0
  183. package/tools/tests/test-flow-resident-can-reuse-does-not-leak-metadata.sh +52 -0
  184. package/tools/tests/test-flow-resident-reap-stale-controllers.sh +63 -0
  185. package/tools/tests/test-flow-resolve-codex-quota-tools.sh +104 -0
  186. package/tools/tests/test-flow-runtime-doctor-profile-selection.sh +27 -0
  187. package/tools/tests/test-heartbeat-codex-pr-linked-issue-exclusion.sh +79 -0
  188. package/tools/tests/test-heartbeat-hooks-enqueue-resident-issue-for-idle-controller.sh +115 -0
  189. package/tools/tests/test-heartbeat-hooks-enqueue-resident-issue-for-live-lane-controller.sh +117 -0
  190. package/tools/tests/test-heartbeat-hooks-start-resident-issue-loop-claude.sh +96 -0
  191. package/tools/tests/test-heartbeat-hooks-start-resident-issue-loop-codex.sh +96 -0
  192. package/tools/tests/test-heartbeat-hooks-start-resident-issue-loop.sh +96 -0
  193. package/tools/tests/test-heartbeat-loop-auth-wait-does-not-consume-capacity.sh +170 -0
  194. package/tools/tests/test-heartbeat-loop-blocked-recovery-lane.sh +201 -0
  195. package/tools/tests/test-heartbeat-loop-blocked-recovery-vs-pr-reservation.sh +201 -0
  196. package/tools/tests/test-heartbeat-loop-idle-resident-controller-does-not-block-launches.sh +160 -0
  197. package/tools/tests/test-heartbeat-loop-pr-launch-dedup.sh +133 -0
  198. package/tools/tests/test-heartbeat-loop-provider-cooldown-suppresses-launches.sh +157 -0
  199. package/tools/tests/test-heartbeat-loop-reaps-stale-resident-controller.sh +181 -0
  200. package/tools/tests/test-heartbeat-loop-waiting-provider-resident-controller-does-not-block-launches.sh +160 -0
  201. package/tools/tests/test-heartbeat-ready-issues-blocked-recovery.sh +134 -0
  202. package/tools/tests/test-heartbeat-safe-auto-dynamic-concurrency.sh +162 -0
  203. package/tools/tests/test-heartbeat-safe-auto-no-tmux-sessions.sh +136 -0
  204. package/tools/tests/test-heartbeat-safe-auto-openclaw-skips-codex-quota.sh +139 -0
  205. package/tools/tests/test-heartbeat-safe-auto-quota-health-signal.sh +119 -0
  206. package/tools/tests/test-heartbeat-safe-auto-stale-shared-loop-pid-does-not-skip.sh +140 -0
  207. package/tools/tests/test-heartbeat-safe-auto-static-capacity-without-quota-cache.sh +142 -0
  208. package/tools/tests/test-heartbeat-safe-auto-zero-healthy-pools.sh +141 -0
  209. package/tools/tests/test-heartbeat-sync-issue-labels-empty-schedule.sh +65 -0
  210. package/tools/tests/test-heartbeat-sync-open-agent-prs-terminal-clears-running.sh +179 -0
  211. package/tools/tests/test-install-dashboard-launchd.sh +78 -0
  212. package/tools/tests/test-install-project-launchd-adds-tool-paths.sh +87 -0
  213. package/tools/tests/test-install-project-launchd.sh +110 -0
  214. package/tools/tests/test-issue-local-workspace-install-policy.sh +81 -0
  215. package/tools/tests/test-issue-publish-scope-guard-docs-signal.sh +70 -0
  216. package/tools/tests/test-issue-reconcile-hooks-success-clears-blocked.sh +36 -0
  217. package/tools/tests/test-kick-scheduler-requires-explicit-profile.sh +47 -0
  218. package/tools/tests/test-label-follow-up-issues-falls-back-to-repository-id.sh +132 -0
  219. package/tools/tests/test-manual-operator-entrypoints-require-explicit-profile.sh +64 -0
  220. package/tools/tests/test-package-funding-metadata.sh +21 -0
  221. package/tools/tests/test-package-public-metadata.sh +62 -0
  222. package/tools/tests/test-placeholder-worker-adapters.sh +38 -0
  223. package/tools/tests/test-pr-reconcile-hooks-refreshes-recurring-issue-checklist.sh +110 -0
  224. package/tools/tests/test-pr-risk-cohesive-mobile-locale-scope.sh +70 -0
  225. package/tools/tests/test-pr-risk-fix-label-semantics.sh +114 -0
  226. package/tools/tests/test-pr-risk-local-first-no-checks.sh +70 -0
  227. package/tools/tests/test-prepare-worktree-simple-repo-baseline.sh +67 -0
  228. package/tools/tests/test-profile-activate.sh +33 -0
  229. package/tools/tests/test-profile-adopt-allow-missing-repo.sh +68 -0
  230. package/tools/tests/test-profile-adopt-skip-workspace-sync-missing-file.sh +61 -0
  231. package/tools/tests/test-profile-adopt-syncs-anchor-and-workspace.sh +90 -0
  232. package/tools/tests/test-profile-smoke-collision.sh +44 -0
  233. package/tools/tests/test-profile-smoke-invalid-claude-config.sh +31 -0
  234. package/tools/tests/test-profile-smoke-invalid-provider-pool.sh +68 -0
  235. package/tools/tests/test-profile-smoke-repo-slug-mismatch.sh +36 -0
  236. package/tools/tests/test-profile-smoke.sh +45 -0
  237. package/tools/tests/test-project-init-force-and-skip-sync.sh +61 -0
  238. package/tools/tests/test-project-init-repo-slug-mismatch.sh +29 -0
  239. package/tools/tests/test-project-init.sh +66 -0
  240. package/tools/tests/test-project-launchd-bootstrap.sh +66 -0
  241. package/tools/tests/test-project-remove.sh +150 -0
  242. package/tools/tests/test-project-runtime-supervisor.sh +47 -0
  243. package/tools/tests/test-project-runtimectl-launchd.sh +115 -0
  244. package/tools/tests/test-project-runtimectl-missing-profile.sh +54 -0
  245. package/tools/tests/test-project-runtimectl-start-falls-back-to-bootstrap.sh +108 -0
  246. package/tools/tests/test-project-runtimectl-status-reports-supervisor-as-heartbeat-parent.sh +95 -0
  247. package/tools/tests/test-project-runtimectl-status-supervisor-running.sh +59 -0
  248. package/tools/tests/test-project-runtimectl-stop-cancels-pending-kick.sh +85 -0
  249. package/tools/tests/test-project-runtimectl-stop-clears-running-labels.sh +78 -0
  250. package/tools/tests/test-project-runtimectl.sh +212 -0
  251. package/tools/tests/test-provider-cooldown-state-prefers-runtime-worker-context.sh +39 -0
  252. package/tools/tests/test-provider-cooldown-state.sh +59 -0
  253. package/tools/tests/test-public-repo-docs.sh +159 -0
  254. package/tools/tests/test-reconcile-pr-worker-acp-config-routing.sh +75 -0
  255. package/tools/tests/test-render-dashboard-snapshot.sh +149 -0
  256. package/tools/tests/test-render-flow-config-demo-profile.sh +36 -0
  257. package/tools/tests/test-render-flow-config-provider-pool-fallback.sh +81 -0
  258. package/tools/tests/test-render-flow-config.sh +52 -0
  259. package/tools/tests/test-run-codex-task-claude-routing.sh +125 -0
  260. package/tools/tests/test-run-codex-task-codex-resident-routing.sh +108 -0
  261. package/tools/tests/test-run-codex-task-kilo-routing.sh +98 -0
  262. package/tools/tests/test-run-codex-task-openclaw-resident-routing.sh +117 -0
  263. package/tools/tests/test-run-codex-task-openclaw-routing.sh +113 -0
  264. package/tools/tests/test-run-codex-task-opencode-routing.sh +98 -0
  265. package/tools/tests/test-run-codex-task-provider-pool-fallback-routing.sh +146 -0
  266. package/tools/tests/test-scaffold-profile.sh +108 -0
  267. package/tools/tests/test-serve-dashboard.sh +93 -0
  268. package/tools/tests/test-start-issue-worker-blocked-context.sh +129 -0
  269. package/tools/tests/test-start-issue-worker-blocks-complete-recurring-checklist.sh +189 -0
  270. package/tools/tests/test-start-issue-worker-local-install-routing.sh +157 -0
  271. package/tools/tests/test-start-issue-worker-profile-template-routing.sh +149 -0
  272. package/tools/tests/test-start-issue-worker-recurring-resident-reuse-codex.sh +212 -0
  273. package/tools/tests/test-start-issue-worker-recurring-resident-reuse.sh +219 -0
  274. package/tools/tests/test-start-issue-worker-renders-verification-snippet.sh +155 -0
  275. package/tools/tests/test-start-issue-worker-resident-reuse-falls-back-to-new-worktree.sh +199 -0
  276. package/tools/tests/test-start-pr-fix-worker-host-blocker-context.sh +275 -0
  277. package/tools/tests/test-start-resident-issue-loop-adopts-next-recurring-issue.sh +185 -0
  278. package/tools/tests/test-start-resident-issue-loop-clears-pending-while-waiting-due.sh +152 -0
  279. package/tools/tests/test-start-resident-issue-loop-consumes-queued-lease.sh +186 -0
  280. package/tools/tests/test-start-resident-issue-loop-fails-over-provider-pool.sh +212 -0
  281. package/tools/tests/test-start-resident-issue-loop-immediate-cycles.sh +148 -0
  282. package/tools/tests/test-start-resident-issue-loop-waits-for-provider.sh +194 -0
  283. package/tools/tests/test-start-resident-issue-loop-waits-for-terminal-reconcile-status.sh +198 -0
  284. package/tools/tests/test-start-resident-issue-loop-yields-to-live-lane-controller.sh +145 -0
  285. package/tools/tests/test-sync-pr-labels-fix-lane-uses-repair-queued.sh +67 -0
  286. package/tools/tests/test-sync-recurring-issue-checklist-backfills-workflow-complete-blocker.sh +70 -0
  287. package/tools/tests/test-sync-recurring-issue-checklist.sh +95 -0
  288. package/tools/tests/test-sync-shared-agent-home-local-source-root.sh +66 -0
  289. package/tools/tests/test-sync-shared-agent-home-preserves-unrelated-workflow-catalog-skill.sh +47 -0
  290. package/tools/tests/test-test-smoke.sh +86 -0
  291. package/tools/tests/test-uninstall-project-launchd.sh +37 -0
  292. package/tools/tests/test-update-github-labels-prefers-sibling-helper.sh +49 -0
  293. package/tools/tests/test-workflow-catalog.sh +43 -0
  294. package/tools/vendor/codex-quota/LICENSE +21 -0
  295. package/tools/vendor/codex-quota/README.md +459 -0
  296. package/tools/vendor/codex-quota/codex-quota.js +261 -0
  297. package/tools/vendor/codex-quota/lib/claude-accounts.js +226 -0
  298. package/tools/vendor/codex-quota/lib/claude-oauth.js +174 -0
  299. package/tools/vendor/codex-quota/lib/claude-tokens.js +471 -0
  300. package/tools/vendor/codex-quota/lib/claude-usage.js +929 -0
  301. package/tools/vendor/codex-quota/lib/codex-accounts.js +205 -0
  302. package/tools/vendor/codex-quota/lib/codex-tokens.js +326 -0
  303. package/tools/vendor/codex-quota/lib/codex-usage.js +32 -0
  304. package/tools/vendor/codex-quota/lib/color.js +72 -0
  305. package/tools/vendor/codex-quota/lib/constants.js +57 -0
  306. package/tools/vendor/codex-quota/lib/container.js +143 -0
  307. package/tools/vendor/codex-quota/lib/display.js +1111 -0
  308. package/tools/vendor/codex-quota/lib/fs.js +63 -0
  309. package/tools/vendor/codex-quota/lib/handlers.js +2060 -0
  310. package/tools/vendor/codex-quota/lib/jwt.js +33 -0
  311. package/tools/vendor/codex-quota/lib/oauth.js +486 -0
  312. package/tools/vendor/codex-quota/lib/paths.js +34 -0
  313. package/tools/vendor/codex-quota/lib/prompts.js +44 -0
  314. package/tools/vendor/codex-quota/lib/sync.js +1438 -0
  315. package/tools/vendor/codex-quota/lib/token-match.js +96 -0
  316. package/tools/vendor/codex-quota-manager/scripts/auto-switch.sh +500 -0
  317. package/tools/vendor/codex-quota-manager/scripts/batch-add.sh +123 -0
@@ -0,0 +1,62 @@
1
+ You are the PR review and final-merge worker for `{REPO_SLUG}`.
2
+
3
+ Before making any decision:
4
+
5
+ 1. Read `{REPO_ROOT}/AGENTS.md` and any repo-specific conventions or design docs relevant to the PR.
6
+ 2. Do not edit product code in this worktree. This is review and final-review only.
7
+ 3. Never run dependency bootstrap or workspace-mutating commands here.
8
+
9
+ PR metadata:
10
+
11
+ - PR: {PR_NUMBER} - {PR_TITLE}
12
+ - URL: {PR_URL}
13
+ - Base branch: {PR_BASE_REF}
14
+ - Head branch: {PR_HEAD_REF}
15
+ - Linked issue: {PR_LINKED_ISSUE_ID}
16
+ - Risk classification: {PR_RISK}
17
+ - Risk reason: {PR_RISK_REASON}
18
+ - Review lane: {PR_AGENT_LANE}
19
+ - Double-check stage: {PR_DOUBLE_CHECK_STAGE}
20
+ - Review intent: {PR_REVIEW_STAGE_TEXT}
21
+ - Merge state: {PR_MERGE_STATE_STATUS}
22
+ - Infra-only CI bypass active: {PR_CHECKS_BYPASSED}
23
+
24
+ Current GitHub checks:
25
+ {PR_CHECKS_TEXT}
26
+
27
+ Changed files:
28
+ {PR_FILES_TEXT}
29
+
30
+ PR body:
31
+ {PR_BODY}
32
+
33
+ Required flow:
34
+
35
+ 1. Stay local to this worktree. Do not rely on live GitHub mutations from inside the worker.
36
+ 2. Treat every review pass as independent, even if another agent reviewed this PR earlier.
37
+ 3. Review the diff for correctness, regressions, and mismatch with the PR summary:
38
+ - `openspec list` if the repo uses OpenSpec
39
+ - `git diff --stat origin/main...HEAD`
40
+ - `git diff --check origin/main...HEAD`
41
+ - if the diff includes locale resources, run the repo's locale validation command if one exists
42
+ - if the PR would touch too many non-test product files, treat that as a scope blocker and request a split
43
+ - if the PR changes auth, login, session, reset, or identity normalization paths, verify legacy flows still remain safe
44
+ - if the PR changes or removes a public endpoint, public route, or operator-visible workflow, search downstream consumers in `scripts/`, `docs/`, and specs before approving
45
+ - if a local command fails only because the detached review worktree lacks linked dependencies, treat that as an environment note rather than a product blocker
46
+ 4. If you find a concrete problem or verification fails:
47
+ - If GitHub checks are failing only because of infrastructure-only startup failures and `Infra-only CI bypass active` is `true`, do not block solely on those remote checks.
48
+ - Save a short blocker summary to `$ACP_RUN_DIR/pr-comment.md` with the exact heading `## PR final review blocker`.
49
+ - Write `$ACP_RESULT_FILE` exactly like this:
50
+ ```bash
51
+ cat > "$ACP_RESULT_FILE" <<'EOF'
52
+ OUTCOME=blocked
53
+ ACTION=requested-changes-or-blocked
54
+ PR_NUMBER={PR_NUMBER}
55
+ ISSUE_ID={PR_LINKED_ISSUE_ID}
56
+ EOF
57
+ ```
58
+ 5. If the PR is safe and your local final review passes:
59
+ - for `double-check-1`, write `OUTCOME=approved-local-review-passed` with `ACTION=host-advance-double-check-2`
60
+ - for `double-check-2` or `automerge`, write `OUTCOME=approved-local-review-passed` with `ACTION=host-approve-and-merge`
61
+ - for `human-review`, keep the same outcome and use `ACTION=host-await-human-review`
62
+ 6. Exit after recording the result file. The host reconciler owns the final transition.
@@ -0,0 +1,62 @@
1
+ # Task
2
+
3
+ Run the scheduled verification task for issue #{ISSUE_ID} in `{REPO_SLUG}`.
4
+
5
+ # Issue Context
6
+
7
+ - Title: {ISSUE_TITLE}
8
+ - URL: {ISSUE_URL}
9
+
10
+ {ISSUE_BODY}
11
+ {ISSUE_BLOCKER_CONTEXT}
12
+
13
+ # Scheduled Task Rules
14
+
15
+ - This is a scheduled check/report cycle, not an implementation cycle.
16
+ - Do not modify code, do not create a commit, do not open a PR, and do not change production state.
17
+ - Use the issue body as the source of truth for what to verify and which commands or checks to run.
18
+ - If the issue body is too vague to run a safe scheduled check, treat that as an alert and report it instead of inventing scope.
19
+ - Work only inside the dedicated worktree for this issue.
20
+ - The dedicated worktree may use an agent branch name. That is acceptable for scheduled checks.
21
+ - The host prepared this run against baseline commit `{ISSUE_BASELINE_HEAD_SHA}`. Treat that fixed SHA as the source of truth for the run.
22
+ - Before commands start, confirm the dedicated worktree `HEAD` exactly matches `{ISSUE_BASELINE_HEAD_SHA}`.
23
+ - The host may prepare linked dependencies or generated artifacts that are expected for this scheduled run.
24
+ - Only alert if the checked-out commit is wrong or if there are unexpected tracked or untracked product changes beyond those expected worker artifacts.
25
+
26
+ # Verification
27
+
28
+ - Run the narrowest commands or health checks that satisfy the scheduled task.
29
+ - Prefer deterministic read-only commands.
30
+ - For prod or system-health checks, do not perform destructive operations.
31
+ - Retry transient network-dependent failures before declaring an alert unless the issue defines a stricter rule.
32
+ - Capture concrete pass/fail evidence: commands run, key output, and the main signal you relied on.
33
+
34
+ # Result Contract
35
+
36
+ - Write `$ACP_RUN_DIR/issue-comment.md` with a short Markdown report containing:
37
+ - `## Scheduled check result`
38
+ - `Outcome: pass` or `Outcome: alert`
39
+ - `Commands run`
40
+ - `Evidence`
41
+ - `Next due behavior remains host-controlled by schedule`
42
+ - If everything is healthy, write `$ACP_RESULT_FILE` exactly like this:
43
+ ```bash
44
+ cat > "$ACP_RESULT_FILE" <<'EOF'
45
+ OUTCOME=reported
46
+ ACTION=host-comment-scheduled-report
47
+ ISSUE_ID={ISSUE_ID}
48
+ EOF
49
+ ```
50
+ - If any check fails, the schedule definition is ambiguous, credentials are missing, or you detect a regression, still report instead of blocking the lane. Write `$ACP_RESULT_FILE` exactly like this:
51
+ ```bash
52
+ cat > "$ACP_RESULT_FILE" <<'EOF'
53
+ OUTCOME=reported
54
+ ACTION=host-comment-scheduled-alert
55
+ ISSUE_ID={ISSUE_ID}
56
+ EOF
57
+ ```
58
+
59
+ # Stop
60
+
61
+ - Stop after writing the Markdown report and the result file.
62
+ - The host reconciler will post the report comment, keep the issue open, clean the session, and let the next run be driven by the stored schedule.
@@ -0,0 +1,279 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ FLOW_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
6
+ CLI_SCRIPT="${FLOW_ROOT}/npm/bin/agent-control-plane.js"
7
+
8
+ tmpdir="$(mktemp -d)"
9
+ trap 'rm -rf "${tmpdir}"' EXIT
10
+
11
+ platform_home="${tmpdir}/platform"
12
+ home_dir="${tmpdir}/home"
13
+ fake_bin="${tmpdir}/fake-bin"
14
+ mkdir -p "${platform_home}" "${home_dir}"
15
+ mkdir -p "${fake_bin}"
16
+
17
+ cat >"${fake_bin}/gh" <<'EOF'
18
+ #!/usr/bin/env bash
19
+ set -euo pipefail
20
+
21
+ if [[ "${1:-}" == "auth" && "${2:-}" == "status" ]]; then
22
+ echo "gh auth ok"
23
+ exit 0
24
+ fi
25
+
26
+ if [[ "${1:-}" == "auth" && "${2:-}" == "login" ]]; then
27
+ echo "gh auth login stub"
28
+ exit 0
29
+ fi
30
+
31
+ echo "gh stub: unsupported invocation: $*" >&2
32
+ exit 0
33
+ EOF
34
+
35
+ cat >"${fake_bin}/jq" <<'EOF'
36
+ #!/usr/bin/env bash
37
+ exit 0
38
+ EOF
39
+
40
+ cat >"${fake_bin}/codex" <<'EOF'
41
+ #!/usr/bin/env bash
42
+ if [[ "${1:-}" == "--version" ]]; then
43
+ echo "codex stub 0.0.0"
44
+ exit 0
45
+ fi
46
+
47
+ if [[ "${1:-}" == "login" && "${2:-}" == "status" ]]; then
48
+ echo "codex login ok"
49
+ exit 0
50
+ fi
51
+
52
+ echo "codex stub"
53
+ exit 0
54
+ EOF
55
+
56
+ chmod +x "${fake_bin}/gh" "${fake_bin}/jq" "${fake_bin}/codex"
57
+
58
+ help_output="$(
59
+ HOME="${home_dir}" \
60
+ AGENT_PLATFORM_HOME="${platform_home}" \
61
+ node "${CLI_SCRIPT}" help
62
+ )"
63
+
64
+ grep -q '^Usage:$' <<<"${help_output}"
65
+ grep -q '^ setup' <<<"${help_output}"
66
+ grep -q '^ sync' <<<"${help_output}"
67
+ grep -q '^ profile-smoke' <<<"${help_output}"
68
+ grep -q '^ launchd-install' <<<"${help_output}"
69
+ grep -q '^ remove' <<<"${help_output}"
70
+
71
+ version_output="$(
72
+ HOME="${home_dir}" \
73
+ AGENT_PLATFORM_HOME="${platform_home}" \
74
+ node "${CLI_SCRIPT}" version
75
+ )"
76
+
77
+ grep -q '^0\.1\.0$' <<<"${version_output}"
78
+
79
+ HOME="${home_dir}" \
80
+ AGENT_PLATFORM_HOME="${platform_home}" \
81
+ node "${CLI_SCRIPT}" sync >/dev/null
82
+
83
+ test -f "${platform_home}/runtime-home/skills/openclaw/agent-control-plane/SKILL.md"
84
+ test -f "${platform_home}/runtime-home/tools/bin/flow-runtime-doctor.sh"
85
+ test -f "${platform_home}/runtime-home/skills/openclaw/agent-control-plane/tools/bin/codex-quota"
86
+ test -f "${platform_home}/runtime-home/skills/openclaw/agent-control-plane/tools/vendor/codex-quota-manager/scripts/auto-switch.sh"
87
+
88
+ doctor_output="$(
89
+ HOME="${home_dir}" \
90
+ AGENT_PLATFORM_HOME="${platform_home}" \
91
+ node "${CLI_SCRIPT}" doctor
92
+ )"
93
+
94
+ grep -q '^CONTROL_PLANE_NAME=agent-control-plane$' <<<"${doctor_output}"
95
+ grep -q '^SOURCE_READY=yes$' <<<"${doctor_output}"
96
+
97
+ init_output="$(
98
+ HOME="${home_dir}" \
99
+ AGENT_PLATFORM_HOME="${platform_home}" \
100
+ node "${CLI_SCRIPT}" init \
101
+ --profile-id alpha \
102
+ --repo-slug example-owner/alpha \
103
+ --allow-missing-repo \
104
+ --skip-anchor-sync \
105
+ --skip-workspace-sync
106
+ )"
107
+
108
+ grep -q '^PROJECT_INIT_STATUS=ok$' <<<"${init_output}"
109
+ grep -q '^PROFILE_ID=alpha$' <<<"${init_output}"
110
+ grep -q "^RUNTIME_HOME=${platform_home}/runtime-home$" <<<"${init_output}"
111
+
112
+ profile_smoke_output="$(
113
+ HOME="${home_dir}" \
114
+ AGENT_PLATFORM_HOME="${platform_home}" \
115
+ node "${CLI_SCRIPT}" profile-smoke --profile-id alpha
116
+ )"
117
+
118
+ grep -q '^PROFILE_ID=alpha$' <<<"${profile_smoke_output}"
119
+ grep -q '^PROFILE_STATUS=ok$' <<<"${profile_smoke_output}"
120
+
121
+ runtime_status_output="$(
122
+ HOME="${home_dir}" \
123
+ AGENT_PLATFORM_HOME="${platform_home}" \
124
+ node "${CLI_SCRIPT}" runtime status --profile-id alpha
125
+ )"
126
+
127
+ grep -q '^PROFILE_ID=alpha$' <<<"${runtime_status_output}"
128
+ grep -q "^CONFIG_YAML=${platform_home}/control-plane/profiles/alpha/control-plane.yaml$" <<<"${runtime_status_output}"
129
+
130
+ launchd_help="$(
131
+ HOME="${home_dir}" \
132
+ AGENT_PLATFORM_HOME="${platform_home}" \
133
+ node "${CLI_SCRIPT}" launchd-install --help
134
+ )"
135
+
136
+ grep -q '^Usage:$' <<<"${launchd_help}"
137
+
138
+ remove_help="$(
139
+ HOME="${home_dir}" \
140
+ AGENT_PLATFORM_HOME="${platform_home}" \
141
+ node "${CLI_SCRIPT}" remove --help
142
+ )"
143
+
144
+ grep -q '^Usage:$' <<<"${remove_help}"
145
+
146
+ setup_help="$(
147
+ HOME="${home_dir}" \
148
+ AGENT_PLATFORM_HOME="${platform_home}" \
149
+ node "${CLI_SCRIPT}" setup --help
150
+ )"
151
+
152
+ grep -q -- '--install-missing-deps' <<<"${setup_help}"
153
+ grep -q -- '--no-install-missing-deps' <<<"${setup_help}"
154
+ grep -q -- '--install-missing-backend' <<<"${setup_help}"
155
+ grep -q -- '--no-install-missing-backend' <<<"${setup_help}"
156
+ grep -q -- '--gh-auth-login' <<<"${setup_help}"
157
+ grep -q -- '--no-gh-auth-login' <<<"${setup_help}"
158
+ grep -q -- '--dry-run' <<<"${setup_help}"
159
+ grep -q -- '--plan' <<<"${setup_help}"
160
+ grep -q -- '--json' <<<"${setup_help}"
161
+
162
+ setup_repo="${tmpdir}/setup-demo"
163
+ mkdir -p "${setup_repo}"
164
+ git -C "${setup_repo}" init -q -b main
165
+ git -C "${setup_repo}" config user.name "ACP Test"
166
+ git -C "${setup_repo}" config user.email "acp-test@example.com"
167
+ printf '# setup demo\n' >"${setup_repo}/README.md"
168
+ git -C "${setup_repo}" add README.md
169
+ git -C "${setup_repo}" commit -q -m "init"
170
+ git -C "${setup_repo}" remote add origin "https://github.com/example-owner/setup-demo.git"
171
+
172
+ setup_output="$(
173
+ HOME="${home_dir}" \
174
+ AGENT_PLATFORM_HOME="${platform_home}" \
175
+ PATH="${fake_bin}:${PATH}" \
176
+ node "${CLI_SCRIPT}" setup \
177
+ --non-interactive \
178
+ --repo-root "${setup_repo}" \
179
+ --no-start-runtime \
180
+ --skip-anchor-sync \
181
+ --skip-workspace-sync
182
+ )"
183
+
184
+ grep -q '^SETUP_STATUS=ok$' <<<"${setup_output}"
185
+ grep -q '^PROFILE_ID=setup-demo$' <<<"${setup_output}"
186
+ grep -q '^REPO_SLUG=example-owner/setup-demo$' <<<"${setup_output}"
187
+ grep -q '^CODING_WORKER=' <<<"${setup_output}"
188
+ grep -q '^CORE_TOOLS_STATUS=ok$' <<<"${setup_output}"
189
+ grep -q '^WORKER_BACKEND_COMMAND=' <<<"${setup_output}"
190
+ grep -q '^WORKER_BACKEND_STATUS=ok$' <<<"${setup_output}"
191
+ grep -q '^WORKER_SETUP_GUIDE_STATUS=' <<<"${setup_output}"
192
+ grep -q '^WORKER_BACKEND_INSTALL_STATUS=' <<<"${setup_output}"
193
+ grep -q '^WORKER_SETUP_DOCS_OPENED=' <<<"${setup_output}"
194
+ grep -q '^WORKER_BACKEND_DOCS_URL=' <<<"${setup_output}"
195
+ grep -q '^WORKER_BACKEND_AUTH_EXAMPLE=' <<<"${setup_output}"
196
+ grep -q '^WORKER_BACKEND_VERIFY_EXAMPLE=' <<<"${setup_output}"
197
+ grep -q '^GITHUB_AUTH_STATUS=' <<<"${setup_output}"
198
+ grep -q '^FINAL_FIXUP_STATUS=' <<<"${setup_output}"
199
+ grep -q '^FINAL_FIXUP_ACTIONS=' <<<"${setup_output}"
200
+ grep -q '^DEPENDENCY_INSTALL_STATUS=' <<<"${setup_output}"
201
+ grep -q '^GITHUB_AUTH_STEP_STATUS=' <<<"${setup_output}"
202
+ grep -q '^PROJECT_INIT_STATUS=ok$' <<<"${setup_output}"
203
+ grep -q '^DOCTOR_STATUS=ok$' <<<"${setup_output}"
204
+ grep -q '^RUNTIME_START_STATUS=skipped$' <<<"${setup_output}"
205
+ grep -q '^RUNTIME_START_REASON=not-requested$' <<<"${setup_output}"
206
+ test -f "${platform_home}/control-plane/profiles/setup-demo/control-plane.yaml"
207
+
208
+ setup_dry_run_output="$(
209
+ HOME="${home_dir}" \
210
+ AGENT_PLATFORM_HOME="${platform_home}" \
211
+ PATH="${fake_bin}:${PATH}" \
212
+ node "${CLI_SCRIPT}" setup \
213
+ --dry-run \
214
+ --non-interactive \
215
+ --repo-root "${setup_repo}" \
216
+ --no-start-runtime \
217
+ --skip-anchor-sync \
218
+ --skip-workspace-sync
219
+ )"
220
+
221
+ grep -q '^SETUP_STATUS=dry-run$' <<<"${setup_dry_run_output}"
222
+ grep -q '^SETUP_MODE=dry-run$' <<<"${setup_dry_run_output}"
223
+ grep -q '^PROJECT_INIT_STATUS=would-run$' <<<"${setup_dry_run_output}"
224
+ grep -q '^DOCTOR_STATUS=would-run$' <<<"${setup_dry_run_output}"
225
+ grep -q '^FINAL_FIXUP_STATUS=planned$' <<<"${setup_dry_run_output}"
226
+ grep -q '^FINAL_FIXUP_ACTIONS=review-plan$' <<<"${setup_dry_run_output}"
227
+
228
+ setup_json_output="$(
229
+ HOME="${home_dir}" \
230
+ AGENT_PLATFORM_HOME="${platform_home}" \
231
+ PATH="${fake_bin}:${PATH}" \
232
+ node "${CLI_SCRIPT}" setup \
233
+ --json \
234
+ --repo-root "${setup_repo}" \
235
+ --profile-id setup-json \
236
+ --no-start-runtime \
237
+ --skip-anchor-sync \
238
+ --skip-workspace-sync
239
+ )"
240
+
241
+ printf '%s' "${setup_json_output}" | node -e '
242
+ const fs = require("fs");
243
+ const data = JSON.parse(fs.readFileSync(0, "utf8"));
244
+ if (data.setupStatus !== "ok") process.exit(1);
245
+ if (data.setupMode !== "run") process.exit(1);
246
+ if (data.profileId !== "setup-json") process.exit(1);
247
+ if (data.projectInitStatus !== "ok") process.exit(1);
248
+ if (data.doctorStatus !== "ok") process.exit(1);
249
+ if (!data.workerBackend || !data.githubAuth || !data.finalFixup) process.exit(1);
250
+ '
251
+
252
+ setup_dry_run_json_output="$(
253
+ HOME="${home_dir}" \
254
+ AGENT_PLATFORM_HOME="${platform_home}" \
255
+ PATH="${fake_bin}:${PATH}" \
256
+ node "${CLI_SCRIPT}" setup \
257
+ --json \
258
+ --dry-run \
259
+ --repo-root "${setup_repo}" \
260
+ --profile-id dry-run-json \
261
+ --no-start-runtime \
262
+ --skip-anchor-sync \
263
+ --skip-workspace-sync
264
+ )"
265
+
266
+ printf '%s' "${setup_dry_run_json_output}" | node -e '
267
+ const fs = require("fs");
268
+ const data = JSON.parse(fs.readFileSync(0, "utf8"));
269
+ if (data.setupStatus !== "dry-run") process.exit(1);
270
+ if (data.setupMode !== "dry-run") process.exit(1);
271
+ if (data.profileId !== "dry-run-json") process.exit(1);
272
+ if (data.projectInitStatus !== "would-run") process.exit(1);
273
+ if (data.doctorStatus !== "would-run") process.exit(1);
274
+ if (!data.finalFixup || data.finalFixup.status !== "planned") process.exit(1);
275
+ if (data.dependencyInstall && data.dependencyInstall.status === "not-needed" && data.dependencyInstall.command !== "") process.exit(1);
276
+ if (data.workerBackend && data.workerBackend.installStatus === "not-needed" && data.workerBackend.installCommand !== "") process.exit(1);
277
+ '
278
+
279
+ test ! -e "${platform_home}/control-plane/profiles/dry-run-json/control-plane.yaml"
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ FLOW_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ SCRIPT_SRC="${FLOW_ROOT}/tools/bin/agent-github-update-labels"
6
+ CONFIG_LIB_SRC="${FLOW_ROOT}/tools/bin/flow-config-lib.sh"
7
+ SHELL_LIB_SRC="${FLOW_ROOT}/tools/bin/flow-shell-lib.sh"
8
+
9
+ tmpdir="$(mktemp -d)"
10
+ trap 'rm -rf "$tmpdir"' EXIT
11
+
12
+ bin_dir="$tmpdir/bin"
13
+ payload_file="$tmpdir/payload.json"
14
+ mkdir -p "$bin_dir"
15
+
16
+ cp "$SCRIPT_SRC" "$bin_dir/agent-github-update-labels"
17
+ cp "$CONFIG_LIB_SRC" "$bin_dir/flow-config-lib.sh"
18
+ cp "$SHELL_LIB_SRC" "$bin_dir/flow-shell-lib.sh"
19
+
20
+ cat >"$bin_dir/gh" <<'EOF'
21
+ #!/usr/bin/env bash
22
+ set -euo pipefail
23
+
24
+ if [[ "${1:-}" == "api" ]]; then
25
+ route="${2:-}"
26
+ if [[ "$route" == "repos/example/demo/issues/42" ]]; then
27
+ echo '{"message":"Not Found"}' >&2
28
+ exit 1
29
+ fi
30
+ if [[ "$route" == user/repos\?* ]]; then
31
+ printf '[[{"id":123,"full_name":"example/demo"}]]\n'
32
+ exit 0
33
+ fi
34
+ if [[ "$route" == "repositories/123/issues/42" ]]; then
35
+ if [[ " $* " == *" --method PATCH "* ]]; then
36
+ cat >"${TEST_PAYLOAD_FILE:?}"
37
+ exit 0
38
+ fi
39
+ printf '{"labels":[{"name":"agent-blocked"}]}\n'
40
+ exit 0
41
+ fi
42
+ fi
43
+
44
+ echo "unexpected gh invocation: $*" >&2
45
+ exit 1
46
+ EOF
47
+ chmod +x "$bin_dir/gh" "$bin_dir/agent-github-update-labels"
48
+
49
+ TEST_PAYLOAD_FILE="$payload_file" \
50
+ PATH="$bin_dir:$PATH" \
51
+ bash "$bin_dir/agent-github-update-labels" --repo-slug example/demo --number 42 --add agent-running --remove agent-blocked
52
+
53
+ test "$(jq -r '.labels[0]' "$payload_file")" = "agent-running"
54
+ test "$(jq '.labels | length' "$payload_file")" -eq 1
55
+
56
+ echo "agent github update labels falls back to repository id test passed"
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ FLOW_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ SESSION_SRC="${FLOW_ROOT}/tools/bin/agent-project-run-claude-session"
6
+
7
+ tmpdir="$(mktemp -d)"
8
+ trap 'rm -rf "$tmpdir"' EXIT
9
+
10
+ tools_dir="$tmpdir/tools"
11
+ bin_dir="$tmpdir/bin"
12
+ worktree="$tmpdir/worktree"
13
+ runs_root="$tmpdir/runs"
14
+ prompt_file="$tmpdir/prompt.md"
15
+ session="acp-claude-stale-sandbox"
16
+ run_dir="$runs_root/$session"
17
+ sandbox_run_dir="$worktree/.openclaw-artifacts/$session"
18
+
19
+ mkdir -p "$tools_dir" "$bin_dir" "$worktree" "$runs_root" "$sandbox_run_dir"
20
+ cp "$SESSION_SRC" "$tools_dir/agent-project-run-claude-session"
21
+
22
+ printf 'stale-result\n' >"$sandbox_run_dir/result.env"
23
+ printf '{"timestamp":"old","status":"pass","command":"stale verification"}\n' >"$sandbox_run_dir/verification.jsonl"
24
+ printf 'stale blocker\n' >"$sandbox_run_dir/issue-comment.md"
25
+
26
+ cat >"$bin_dir/claude" <<'EOF'
27
+ #!/usr/bin/env bash
28
+ set -euo pipefail
29
+
30
+ cat >"${ACP_RESULT_FILE:?}" <<'RESULT'
31
+ OUTCOME=implemented
32
+ ACTION=host-publish-issue-pr
33
+ RESULT
34
+ printf '{"timestamp":"new","status":"pass","command":"fresh verification"}\n' >"${ACP_RUN_DIR:?}/verification.jsonl"
35
+ printf 'mock claude finished\n'
36
+ EOF
37
+
38
+ chmod +x "$tools_dir/agent-project-run-claude-session" "$bin_dir/claude"
39
+
40
+ git -C "$worktree" init -b test >/dev/null 2>&1
41
+ printf 'Prompt body\n' >"$prompt_file"
42
+
43
+ PATH="$bin_dir:$PATH" \
44
+ bash "$tools_dir/agent-project-run-claude-session" \
45
+ --mode safe \
46
+ --session "$session" \
47
+ --worktree "$worktree" \
48
+ --prompt-file "$prompt_file" \
49
+ --runs-root "$runs_root" \
50
+ --adapter-id alpha \
51
+ --task-kind issue \
52
+ --task-id 123 \
53
+ --claude-model sonnet \
54
+ --claude-permission-mode dontAsk \
55
+ --claude-effort high \
56
+ --collect-file verification.jsonl \
57
+ --collect-file issue-comment.md \
58
+ >/dev/null
59
+
60
+ for _ in $(seq 1 50); do
61
+ if ! tmux has-session -t "$session" 2>/dev/null; then
62
+ break
63
+ fi
64
+ sleep 0.2
65
+ done
66
+
67
+ if tmux has-session -t "$session" 2>/dev/null; then
68
+ echo "tmux session did not exit" >&2
69
+ exit 1
70
+ fi
71
+
72
+ test -f "$run_dir/result.env"
73
+ test -f "$run_dir/verification.jsonl"
74
+ grep -q '^OUTCOME=implemented$' "$run_dir/result.env"
75
+ grep -q 'fresh verification' "$run_dir/verification.jsonl"
76
+ if grep -q 'stale verification' "$run_dir/verification.jsonl"; then
77
+ echo "stale verification entry leaked into claude cycle" >&2
78
+ exit 1
79
+ fi
80
+ if [[ -e "$run_dir/issue-comment.md" ]]; then
81
+ echo "stale claude issue comment leaked into host run dir" >&2
82
+ exit 1
83
+ fi
84
+ if [[ -e "$sandbox_run_dir/issue-comment.md" ]]; then
85
+ echo "stale claude sandbox comment artifact was not cleared" >&2
86
+ exit 1
87
+ fi
88
+
89
+ echo "agent-project claude session wrapper clears stale sandbox artifacts test passed"
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ FLOW_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5
+ SESSION_SRC="${FLOW_ROOT}/tools/bin/agent-project-run-claude-session"
6
+
7
+ tmpdir="$(mktemp -d)"
8
+ trap 'rm -rf "$tmpdir"' EXIT
9
+
10
+ tools_dir="$tmpdir/tools"
11
+ bin_dir="$tmpdir/bin"
12
+ worktree="$tmpdir/worktree"
13
+ runs_root="$tmpdir/runs"
14
+ prompt_file="$tmpdir/prompt.md"
15
+ session="acp-issue-claude-provider-quota"
16
+ run_dir="$runs_root/$session"
17
+
18
+ mkdir -p "$tools_dir" "$bin_dir" "$worktree" "$runs_root"
19
+ cp "$SESSION_SRC" "$tools_dir/agent-project-run-claude-session"
20
+
21
+ cat >"$bin_dir/claude" <<'EOF'
22
+ #!/usr/bin/env bash
23
+ set -euo pipefail
24
+
25
+ attempt_file="${ACP_HOST_RUN_DIR:?}/attempt-count"
26
+ attempt="0"
27
+ if [[ -f "$attempt_file" ]]; then
28
+ attempt="$(cat "$attempt_file")"
29
+ fi
30
+ attempt="$((attempt + 1))"
31
+ printf '%s' "$attempt" >"$attempt_file"
32
+
33
+ printf '429 rate limit exceeded\n' >&2
34
+ exit 1
35
+ EOF
36
+
37
+ chmod +x "$tools_dir/agent-project-run-claude-session" "$bin_dir/claude"
38
+
39
+ git -C "$worktree" init -b test >/dev/null 2>&1
40
+ printf 'Prompt body\n' >"$prompt_file"
41
+
42
+ PATH="$bin_dir:$PATH" \
43
+ bash "$tools_dir/agent-project-run-claude-session" \
44
+ --mode safe \
45
+ --session "$session" \
46
+ --worktree "$worktree" \
47
+ --prompt-file "$prompt_file" \
48
+ --runs-root "$runs_root" \
49
+ --adapter-id alpha \
50
+ --task-kind issue \
51
+ --task-id 123 \
52
+ --claude-model sonnet \
53
+ --claude-permission-mode dontAsk \
54
+ --claude-effort medium \
55
+ --claude-timeout-seconds 10 \
56
+ --claude-max-attempts 3 \
57
+ --claude-retry-backoff-seconds 0 \
58
+ >/dev/null
59
+
60
+ for _ in $(seq 1 50); do
61
+ if ! tmux has-session -t "$session" 2>/dev/null; then
62
+ break
63
+ fi
64
+ sleep 0.2
65
+ done
66
+
67
+ if tmux has-session -t "$session" 2>/dev/null; then
68
+ echo "tmux session did not exit" >&2
69
+ exit 1
70
+ fi
71
+
72
+ grep -q '^RUNNER_STATE=failed$' "$run_dir/runner.env"
73
+ grep -q '^ATTEMPT=1$' "$run_dir/runner.env"
74
+ grep -q '^RESUME_COUNT=0$' "$run_dir/runner.env"
75
+ grep -q '^1$' "$run_dir/attempt-count"
76
+ if grep -q '\[claude-retry\]' "$run_dir/$session.log"; then
77
+ echo "provider quota failure unexpectedly retried" >&2
78
+ exit 1
79
+ fi
80
+ grep -q '__CLAUDE_EXIT__:1' "$run_dir/$session.log"
81
+
82
+ echo "agent-project claude provider quota no-retry test passed"