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,97 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ # shellcheck source=/dev/null
6
+ source "${SCRIPT_DIR}/flow-config-lib.sh"
7
+
8
+ FLOW_SKILL_DIR="$(resolve_flow_skill_dir "${BASH_SOURCE[0]}")"
9
+ SHARED_AGENT_HOME="$(resolve_shared_agent_home "${FLOW_SKILL_DIR}")"
10
+ PROFILE_REGISTRY_ROOT="$(resolve_flow_profile_registry_root)"
11
+ CONTROL_PLANE_NAME="$(flow_canonical_skill_name)"
12
+ COMPAT_SKILL_ALIAS="$(flow_compat_skill_alias)"
13
+ SOURCE_CANONICAL_SKILL_DIR="$(resolve_source_canonical_skill_dir "${SHARED_AGENT_HOME}")"
14
+ SOURCE_COMPAT_SKILL_DIR="$(resolve_source_compat_skill_dir "${SHARED_AGENT_HOME}")"
15
+ RUNTIME_HOME="$(resolve_runtime_home)"
16
+ RUNTIME_CANONICAL_SKILL_DIR="$(resolve_runtime_canonical_skill_dir)"
17
+ RUNTIME_COMPAT_SKILL_DIR="$(resolve_runtime_compat_skill_dir)"
18
+ CATALOG_FILE="${FLOW_SKILL_DIR}/assets/workflow-catalog.json"
19
+ CONFIG_YAML="$(resolve_flow_config_yaml "${BASH_SOURCE[0]}")"
20
+ SYNC_SCRIPT="${FLOW_SKILL_DIR}/tools/bin/sync-shared-agent-home.sh"
21
+ PROFILE_ID="$(flow_resolve_adapter_id "${CONFIG_YAML}")"
22
+ AVAILABLE_PROFILES="$(flow_list_profile_ids "${FLOW_SKILL_DIR}" | paste -sd, -)"
23
+ INSTALLED_PROFILES="$(flow_list_installed_profile_ids | paste -sd, -)"
24
+ PROFILE_SELECTION_MODE="$(flow_profile_selection_mode "${FLOW_SKILL_DIR}")"
25
+ PROFILE_SELECTION_HINT="$(flow_profile_selection_hint "${FLOW_SKILL_DIR}")"
26
+ PROFILE_NOTES="$(flow_resolve_profile_notes_file "${CONFIG_YAML}")"
27
+
28
+ exists_flag() {
29
+ local candidate="${1:-}"
30
+ if [[ -e "${candidate}" ]]; then
31
+ printf 'yes\n'
32
+ else
33
+ printf 'no\n'
34
+ fi
35
+ }
36
+
37
+ source_canonical_exists="$(exists_flag "${SOURCE_CANONICAL_SKILL_DIR}")"
38
+ source_compat_exists="$(exists_flag "${SOURCE_COMPAT_SKILL_DIR}")"
39
+ runtime_canonical_exists="$(exists_flag "${RUNTIME_CANONICAL_SKILL_DIR}")"
40
+ runtime_compat_exists="$(exists_flag "${RUNTIME_COMPAT_SKILL_DIR}")"
41
+ catalog_exists="$(exists_flag "${CATALOG_FILE}")"
42
+ profile_exists="$(exists_flag "${CONFIG_YAML}")"
43
+ active_checkout_is_canonical="no"
44
+ source_ready="${source_canonical_exists}"
45
+
46
+ if [[ "$(basename "${FLOW_SKILL_DIR}")" == "${CONTROL_PLANE_NAME}" ]]; then
47
+ active_checkout_is_canonical="yes"
48
+ source_ready="yes"
49
+ fi
50
+
51
+ status="ok"
52
+ if [[ "${source_ready}" != "yes" || "${runtime_canonical_exists}" != "yes" || "${profile_exists}" != "yes" ]]; then
53
+ status="needs-sync"
54
+ fi
55
+
56
+ printf 'CONTROL_PLANE_NAME=%s\n' "${CONTROL_PLANE_NAME}"
57
+ printf 'COMPAT_SKILL_ALIAS=%s\n' "${COMPAT_SKILL_ALIAS}"
58
+ printf 'FLOW_SKILL_DIR=%s\n' "${FLOW_SKILL_DIR}"
59
+ printf 'PROFILE_REGISTRY_ROOT=%s\n' "${PROFILE_REGISTRY_ROOT}"
60
+ printf 'CONFIG_YAML=%s\n' "${CONFIG_YAML}"
61
+ printf 'PROFILE_ID=%s\n' "${PROFILE_ID}"
62
+ printf 'PROFILE_SELECTION_MODE=%s\n' "${PROFILE_SELECTION_MODE}"
63
+ if [[ -n "${PROFILE_SELECTION_HINT}" ]]; then
64
+ printf 'PROFILE_SELECTION_HINT=%s\n' "${PROFILE_SELECTION_HINT}"
65
+ fi
66
+ printf 'PROFILE_NOTES=%s\n' "${PROFILE_NOTES}"
67
+ if [[ -f "${PROFILE_NOTES}" ]]; then
68
+ printf 'PROFILE_NOTES_EXISTS=yes\n'
69
+ else
70
+ printf 'PROFILE_NOTES_EXISTS=no\n'
71
+ fi
72
+ printf 'PROFILE_EXISTS=%s\n' "${profile_exists}"
73
+ printf 'AVAILABLE_PROFILES=%s\n' "${AVAILABLE_PROFILES}"
74
+ printf 'INSTALLED_PROFILES=%s\n' "${INSTALLED_PROFILES}"
75
+ printf 'SHARED_AGENT_HOME=%s\n' "${SHARED_AGENT_HOME}"
76
+ printf 'SOURCE_CANONICAL_SKILL_DIR=%s\n' "${SOURCE_CANONICAL_SKILL_DIR}"
77
+ printf 'SOURCE_CANONICAL_EXISTS=%s\n' "${source_canonical_exists}"
78
+ printf 'ACTIVE_CHECKOUT_IS_CANONICAL=%s\n' "${active_checkout_is_canonical}"
79
+ printf 'SOURCE_READY=%s\n' "${source_ready}"
80
+ printf 'SOURCE_COMPAT_SKILL_DIR=%s\n' "${SOURCE_COMPAT_SKILL_DIR}"
81
+ printf 'SOURCE_COMPAT_EXISTS=%s\n' "${source_compat_exists}"
82
+ printf 'RUNTIME_HOME=%s\n' "${RUNTIME_HOME}"
83
+ printf 'RUNTIME_CANONICAL_SKILL_DIR=%s\n' "${RUNTIME_CANONICAL_SKILL_DIR}"
84
+ printf 'RUNTIME_CANONICAL_EXISTS=%s\n' "${runtime_canonical_exists}"
85
+ printf 'RUNTIME_COMPAT_SKILL_DIR=%s\n' "${RUNTIME_COMPAT_SKILL_DIR}"
86
+ printf 'RUNTIME_COMPAT_EXISTS=%s\n' "${runtime_compat_exists}"
87
+ printf 'WORKFLOW_CATALOG=%s\n' "${CATALOG_FILE}"
88
+ printf 'WORKFLOW_CATALOG_EXISTS=%s\n' "${catalog_exists}"
89
+ printf 'DOCTOR_STATUS=%s\n' "${status}"
90
+
91
+ if [[ -n "${PROFILE_SELECTION_HINT}" ]]; then
92
+ printf 'PROFILE_SELECTION_NEXT_STEP=ACP_PROJECT_ID=<id> bash %s/tools/bin/render-flow-config.sh\n' "${FLOW_SKILL_DIR}"
93
+ fi
94
+
95
+ if [[ "${status}" != "ok" ]]; then
96
+ printf 'NEXT_STEP=bash %q %q %q\n' "${SYNC_SCRIPT}" "${SHARED_AGENT_HOME}" "${RUNTIME_HOME}"
97
+ fi
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ flow_canonical_skill_name() {
5
+ printf '%s\n' "${AGENT_CONTROL_PLANE_SKILL_NAME:-agent-control-plane}"
6
+ }
7
+
8
+ flow_compat_skill_alias() {
9
+ printf '%s\n' "${AGENT_CONTROL_PLANE_COMPAT_ALIAS:-}"
10
+ }
11
+
12
+ flow_export_env_alias_if_unset() {
13
+ local target_name="${1:?target name required}"
14
+ local source_name="${2:?source name required}"
15
+ local source_value="${!source_name:-}"
16
+
17
+ if [[ -n "${source_value}" && -z "${!target_name:-}" ]]; then
18
+ export "${target_name}=${source_value}"
19
+ fi
20
+ }
21
+
22
+ flow_export_compat_env_aliases() {
23
+ flow_export_env_alias_if_unset F_LOSNING_FLOW_ROOT AGENT_CONTROL_PLANE_ROOT
24
+ flow_export_env_alias_if_unset F_LOSNING_FLOW_ROOT ACP_ROOT
25
+ flow_export_env_alias_if_unset F_LOSNING_REPO_SLUG ACP_REPO_SLUG
26
+ flow_export_env_alias_if_unset F_LOSNING_REPO_ID ACP_REPO_ID
27
+ flow_export_env_alias_if_unset F_LOSNING_GITHUB_REPOSITORY_ID ACP_GITHUB_REPOSITORY_ID
28
+ flow_export_env_alias_if_unset F_LOSNING_REPO_ROOT ACP_REPO_ROOT
29
+ flow_export_env_alias_if_unset F_LOSNING_AGENT_ROOT ACP_AGENT_ROOT
30
+ flow_export_env_alias_if_unset F_LOSNING_AGENT_REPO_ROOT ACP_AGENT_REPO_ROOT
31
+ flow_export_env_alias_if_unset F_LOSNING_WORKTREE_ROOT ACP_WORKTREE_ROOT
32
+ flow_export_env_alias_if_unset F_LOSNING_RUNS_ROOT ACP_RUNS_ROOT
33
+ flow_export_env_alias_if_unset F_LOSNING_STATE_ROOT ACP_STATE_ROOT
34
+ flow_export_env_alias_if_unset F_LOSNING_HISTORY_ROOT ACP_HISTORY_ROOT
35
+ flow_export_env_alias_if_unset F_LOSNING_MEMORY_DIR ACP_MEMORY_DIR
36
+ flow_export_env_alias_if_unset F_LOSNING_RETAINED_REPO_ROOT ACP_RETAINED_REPO_ROOT
37
+ flow_export_env_alias_if_unset F_LOSNING_VSCODE_WORKSPACE_FILE ACP_VSCODE_WORKSPACE_FILE
38
+ flow_export_env_alias_if_unset F_LOSNING_CODING_WORKER ACP_CODING_WORKER
39
+ flow_export_env_alias_if_unset F_LOSNING_CODEX_PROFILE_SAFE ACP_CODEX_PROFILE_SAFE
40
+ flow_export_env_alias_if_unset F_LOSNING_CODEX_PROFILE_BYPASS ACP_CODEX_PROFILE_BYPASS
41
+ flow_export_env_alias_if_unset F_LOSNING_CLAUDE_MODEL ACP_CLAUDE_MODEL
42
+ flow_export_env_alias_if_unset F_LOSNING_CLAUDE_PERMISSION_MODE ACP_CLAUDE_PERMISSION_MODE
43
+ flow_export_env_alias_if_unset F_LOSNING_CLAUDE_EFFORT ACP_CLAUDE_EFFORT
44
+ flow_export_env_alias_if_unset F_LOSNING_CLAUDE_TIMEOUT_SECONDS ACP_CLAUDE_TIMEOUT_SECONDS
45
+ flow_export_env_alias_if_unset F_LOSNING_CLAUDE_MAX_ATTEMPTS ACP_CLAUDE_MAX_ATTEMPTS
46
+ flow_export_env_alias_if_unset F_LOSNING_CLAUDE_RETRY_BACKOFF_SECONDS ACP_CLAUDE_RETRY_BACKOFF_SECONDS
47
+ flow_export_env_alias_if_unset F_LOSNING_ISSUE_SESSION_PREFIX ACP_ISSUE_SESSION_PREFIX
48
+ flow_export_env_alias_if_unset F_LOSNING_PR_SESSION_PREFIX ACP_PR_SESSION_PREFIX
49
+ flow_export_env_alias_if_unset F_LOSNING_ISSUE_BRANCH_PREFIX ACP_ISSUE_BRANCH_PREFIX
50
+ flow_export_env_alias_if_unset F_LOSNING_PR_WORKTREE_BRANCH_PREFIX ACP_PR_WORKTREE_BRANCH_PREFIX
51
+ flow_export_env_alias_if_unset F_LOSNING_MANAGED_PR_BRANCH_GLOBS ACP_MANAGED_PR_BRANCH_GLOBS
52
+ flow_export_env_alias_if_unset F_LOSNING_OPENCLAW_MODEL ACP_OPENCLAW_MODEL
53
+ flow_export_env_alias_if_unset F_LOSNING_OPENCLAW_THINKING ACP_OPENCLAW_THINKING
54
+ flow_export_env_alias_if_unset F_LOSNING_OPENCLAW_TIMEOUT_SECONDS ACP_OPENCLAW_TIMEOUT_SECONDS
55
+ flow_export_env_alias_if_unset F_LOSNING_ALLOW_INFRA_CI_BYPASS ACP_ALLOW_INFRA_CI_BYPASS
56
+ flow_export_env_alias_if_unset F_LOSNING_LOCAL_FIRST_PR_POLICY ACP_LOCAL_FIRST_PR_POLICY
57
+ flow_export_env_alias_if_unset F_LOSNING_PR_RISK_CACHE_TTL_SECONDS ACP_PR_RISK_CACHE_TTL_SECONDS
58
+ flow_export_env_alias_if_unset F_LOSNING_RETRY_COOLDOWNS ACP_RETRY_COOLDOWNS
59
+ flow_export_env_alias_if_unset F_LOSNING_WORKTREE_LOCAL_INSTALL ACP_WORKTREE_LOCAL_INSTALL
60
+ flow_export_env_alias_if_unset F_LOSNING_BOOTSTRAP_SCRIPT ACP_BOOTSTRAP_SCRIPT
61
+ flow_export_env_alias_if_unset F_LOSNING_FLOW_HEARTBEAT_SCRIPT ACP_FLOW_HEARTBEAT_SCRIPT
62
+ flow_export_env_alias_if_unset F_LOSNING_TIMEOUT_CHILD_PID_FILE ACP_TIMEOUT_CHILD_PID_FILE
63
+ flow_export_env_alias_if_unset F_LOSNING_ISSUE_ID ACP_ISSUE_ID
64
+ flow_export_env_alias_if_unset F_LOSNING_ISSUE_URL ACP_ISSUE_URL
65
+ flow_export_env_alias_if_unset F_LOSNING_ISSUE_AUTOMERGE ACP_ISSUE_AUTOMERGE
66
+ flow_export_env_alias_if_unset F_LOSNING_PR_NUMBER ACP_PR_NUMBER
67
+ flow_export_env_alias_if_unset F_LOSNING_PR_URL ACP_PR_URL
68
+ flow_export_env_alias_if_unset F_LOSNING_PR_HEAD_REF ACP_PR_HEAD_REF
69
+ }
70
+
71
+ flow_export_canonical_env_aliases() {
72
+ flow_export_env_alias_if_unset ACP_ROOT F_LOSNING_FLOW_ROOT
73
+ flow_export_env_alias_if_unset ACP_REPO_SLUG F_LOSNING_REPO_SLUG
74
+ flow_export_env_alias_if_unset ACP_REPO_ID F_LOSNING_REPO_ID
75
+ flow_export_env_alias_if_unset ACP_GITHUB_REPOSITORY_ID F_LOSNING_GITHUB_REPOSITORY_ID
76
+ flow_export_env_alias_if_unset ACP_REPO_ROOT F_LOSNING_REPO_ROOT
77
+ flow_export_env_alias_if_unset ACP_AGENT_ROOT F_LOSNING_AGENT_ROOT
78
+ flow_export_env_alias_if_unset ACP_AGENT_REPO_ROOT F_LOSNING_AGENT_REPO_ROOT
79
+ flow_export_env_alias_if_unset ACP_WORKTREE_ROOT F_LOSNING_WORKTREE_ROOT
80
+ flow_export_env_alias_if_unset ACP_RUNS_ROOT F_LOSNING_RUNS_ROOT
81
+ flow_export_env_alias_if_unset ACP_STATE_ROOT F_LOSNING_STATE_ROOT
82
+ flow_export_env_alias_if_unset ACP_HISTORY_ROOT F_LOSNING_HISTORY_ROOT
83
+ flow_export_env_alias_if_unset ACP_MEMORY_DIR F_LOSNING_MEMORY_DIR
84
+ flow_export_env_alias_if_unset ACP_RETAINED_REPO_ROOT F_LOSNING_RETAINED_REPO_ROOT
85
+ flow_export_env_alias_if_unset ACP_VSCODE_WORKSPACE_FILE F_LOSNING_VSCODE_WORKSPACE_FILE
86
+ flow_export_env_alias_if_unset ACP_CODING_WORKER F_LOSNING_CODING_WORKER
87
+ flow_export_env_alias_if_unset ACP_CODEX_PROFILE_SAFE F_LOSNING_CODEX_PROFILE_SAFE
88
+ flow_export_env_alias_if_unset ACP_CODEX_PROFILE_BYPASS F_LOSNING_CODEX_PROFILE_BYPASS
89
+ flow_export_env_alias_if_unset ACP_CLAUDE_MODEL F_LOSNING_CLAUDE_MODEL
90
+ flow_export_env_alias_if_unset ACP_CLAUDE_PERMISSION_MODE F_LOSNING_CLAUDE_PERMISSION_MODE
91
+ flow_export_env_alias_if_unset ACP_CLAUDE_EFFORT F_LOSNING_CLAUDE_EFFORT
92
+ flow_export_env_alias_if_unset ACP_CLAUDE_TIMEOUT_SECONDS F_LOSNING_CLAUDE_TIMEOUT_SECONDS
93
+ flow_export_env_alias_if_unset ACP_CLAUDE_MAX_ATTEMPTS F_LOSNING_CLAUDE_MAX_ATTEMPTS
94
+ flow_export_env_alias_if_unset ACP_CLAUDE_RETRY_BACKOFF_SECONDS F_LOSNING_CLAUDE_RETRY_BACKOFF_SECONDS
95
+ flow_export_env_alias_if_unset ACP_ISSUE_SESSION_PREFIX F_LOSNING_ISSUE_SESSION_PREFIX
96
+ flow_export_env_alias_if_unset ACP_PR_SESSION_PREFIX F_LOSNING_PR_SESSION_PREFIX
97
+ flow_export_env_alias_if_unset ACP_ISSUE_BRANCH_PREFIX F_LOSNING_ISSUE_BRANCH_PREFIX
98
+ flow_export_env_alias_if_unset ACP_PR_WORKTREE_BRANCH_PREFIX F_LOSNING_PR_WORKTREE_BRANCH_PREFIX
99
+ flow_export_env_alias_if_unset ACP_MANAGED_PR_BRANCH_GLOBS F_LOSNING_MANAGED_PR_BRANCH_GLOBS
100
+ flow_export_env_alias_if_unset ACP_OPENCLAW_MODEL F_LOSNING_OPENCLAW_MODEL
101
+ flow_export_env_alias_if_unset ACP_OPENCLAW_THINKING F_LOSNING_OPENCLAW_THINKING
102
+ flow_export_env_alias_if_unset ACP_OPENCLAW_TIMEOUT_SECONDS F_LOSNING_OPENCLAW_TIMEOUT_SECONDS
103
+ flow_export_env_alias_if_unset ACP_ALLOW_INFRA_CI_BYPASS F_LOSNING_ALLOW_INFRA_CI_BYPASS
104
+ flow_export_env_alias_if_unset ACP_LOCAL_FIRST_PR_POLICY F_LOSNING_LOCAL_FIRST_PR_POLICY
105
+ flow_export_env_alias_if_unset ACP_PR_RISK_CACHE_TTL_SECONDS F_LOSNING_PR_RISK_CACHE_TTL_SECONDS
106
+ flow_export_env_alias_if_unset ACP_RETRY_COOLDOWNS F_LOSNING_RETRY_COOLDOWNS
107
+ flow_export_env_alias_if_unset ACP_WORKTREE_LOCAL_INSTALL F_LOSNING_WORKTREE_LOCAL_INSTALL
108
+ flow_export_env_alias_if_unset ACP_BOOTSTRAP_SCRIPT F_LOSNING_BOOTSTRAP_SCRIPT
109
+ flow_export_env_alias_if_unset ACP_FLOW_HEARTBEAT_SCRIPT F_LOSNING_FLOW_HEARTBEAT_SCRIPT
110
+ flow_export_env_alias_if_unset ACP_TIMEOUT_CHILD_PID_FILE F_LOSNING_TIMEOUT_CHILD_PID_FILE
111
+ flow_export_env_alias_if_unset ACP_ISSUE_ID F_LOSNING_ISSUE_ID
112
+ flow_export_env_alias_if_unset ACP_ISSUE_URL F_LOSNING_ISSUE_URL
113
+ flow_export_env_alias_if_unset ACP_ISSUE_AUTOMERGE F_LOSNING_ISSUE_AUTOMERGE
114
+ flow_export_env_alias_if_unset ACP_PR_NUMBER F_LOSNING_PR_NUMBER
115
+ flow_export_env_alias_if_unset ACP_PR_URL F_LOSNING_PR_URL
116
+ flow_export_env_alias_if_unset ACP_PR_HEAD_REF F_LOSNING_PR_HEAD_REF
117
+ }
118
+
119
+ flow_export_project_env_aliases() {
120
+ flow_export_compat_env_aliases
121
+ flow_export_canonical_env_aliases
122
+ }
123
+
124
+ flow_is_skill_root() {
125
+ local candidate="${1:-}"
126
+ [[ -n "${candidate}" ]] || return 1
127
+ [[ -d "${candidate}" ]] || return 1
128
+ [[ -d "${candidate}/tools/bin" ]] || return 1
129
+
130
+ if [[ -f "${candidate}/SKILL.md" \
131
+ || -f "${candidate}/assets/workflow-catalog.json" ]]; then
132
+ return 0
133
+ fi
134
+
135
+ [[ -d "${candidate}/bin" || -d "${candidate}/hooks" ]]
136
+ }
137
+
138
+ flow_print_dir() {
139
+ local candidate="${1:-}"
140
+ [[ -n "${candidate}" ]] || return 1
141
+ (cd "${candidate}" && pwd -P)
142
+ }
143
+
144
+ resolve_flow_skill_dir() {
145
+ local script_path="${1:-}"
146
+ local candidate=""
147
+ local skill_name=""
148
+
149
+ for candidate in \
150
+ "${AGENT_CONTROL_PLANE_ROOT:-}" \
151
+ "${ACP_ROOT:-}" \
152
+ "${F_LOSNING_FLOW_ROOT:-}" \
153
+ "${AGENT_FLOW_SKILL_ROOT:-}"; do
154
+ if flow_is_skill_root "${candidate}"; then
155
+ flow_print_dir "${candidate}"
156
+ return 0
157
+ fi
158
+ done
159
+
160
+ if [[ -n "${script_path}" ]]; then
161
+ candidate="$(
162
+ cd "$(dirname "${script_path}")/../.." 2>/dev/null && pwd -P
163
+ )" || candidate=""
164
+ if flow_is_skill_root "${candidate}"; then
165
+ printf '%s\n' "${candidate}"
166
+ return 0
167
+ fi
168
+ fi
169
+
170
+ if [[ -n "${SHARED_AGENT_HOME:-}" ]]; then
171
+ for skill_name in "$(flow_canonical_skill_name)" "$(flow_compat_skill_alias)"; do
172
+ candidate="${SHARED_AGENT_HOME}/skills/openclaw/${skill_name}"
173
+ if flow_is_skill_root "${candidate}"; then
174
+ flow_print_dir "${candidate}"
175
+ return 0
176
+ fi
177
+ done
178
+ fi
179
+
180
+ for skill_name in "$(flow_canonical_skill_name)" "$(flow_compat_skill_alias)"; do
181
+ candidate="${AGENT_PLATFORM_HOME:-${HOME}/.agent-runtime}/runtime-home/skills/openclaw/${skill_name}"
182
+ if flow_is_skill_root "${candidate}"; then
183
+ flow_print_dir "${candidate}"
184
+ return 0
185
+ fi
186
+ done
187
+
188
+ echo "unable to resolve agent control plane root" >&2
189
+ return 1
190
+ }
191
+
192
+ resolve_shared_agent_home() {
193
+ local flow_root="${1:-}"
194
+
195
+ if [[ -n "${SHARED_AGENT_HOME:-}" ]]; then
196
+ flow_print_dir "${SHARED_AGENT_HOME}"
197
+ return 0
198
+ fi
199
+
200
+ if [[ -z "${flow_root}" ]]; then
201
+ flow_root="$(resolve_flow_skill_dir "${BASH_SOURCE[1]:-${BASH_SOURCE[0]}}")"
202
+ fi
203
+
204
+ flow_print_dir "${flow_root}/../../.."
205
+ }
206
+
207
+ resolve_runtime_home() {
208
+ flow_print_dir "${AGENT_PLATFORM_HOME:-${HOME}/.agent-runtime}/runtime-home"
209
+ }
210
+
211
+ resolve_runtime_canonical_skill_dir() {
212
+ local runtime_home
213
+ runtime_home="$(resolve_runtime_home)"
214
+ printf '%s/skills/openclaw/%s\n' "${runtime_home}" "$(flow_canonical_skill_name)"
215
+ }
216
+
217
+ resolve_runtime_compat_skill_dir() {
218
+ local runtime_home
219
+ local compat_alias=""
220
+ runtime_home="$(resolve_runtime_home)"
221
+ compat_alias="$(flow_compat_skill_alias)"
222
+ if [[ -z "${compat_alias}" ]]; then
223
+ printf '\n'
224
+ return 0
225
+ fi
226
+ printf '%s/skills/openclaw/%s\n' "${runtime_home}" "${compat_alias}"
227
+ }
228
+
229
+ resolve_runtime_skill_dir() {
230
+ local candidate=""
231
+
232
+ for candidate in \
233
+ "$(resolve_runtime_canonical_skill_dir)" \
234
+ "$(resolve_runtime_compat_skill_dir)"; do
235
+ if [[ -e "${candidate}" ]]; then
236
+ printf '%s\n' "${candidate}"
237
+ return 0
238
+ fi
239
+ done
240
+
241
+ resolve_runtime_compat_skill_dir
242
+ }
243
+
244
+ resolve_source_canonical_skill_dir() {
245
+ local shared_home="${1:-}"
246
+ if [[ -z "${shared_home}" ]]; then
247
+ shared_home="$(resolve_shared_agent_home)"
248
+ fi
249
+ printf '%s/skills/openclaw/%s\n' "${shared_home}" "$(flow_canonical_skill_name)"
250
+ }
251
+
252
+ resolve_source_compat_skill_dir() {
253
+ local shared_home="${1:-}"
254
+ local compat_alias=""
255
+ if [[ -z "${shared_home}" ]]; then
256
+ shared_home="$(resolve_shared_agent_home)"
257
+ fi
258
+ compat_alias="$(flow_compat_skill_alias)"
259
+ if [[ -z "${compat_alias}" ]]; then
260
+ printf '\n'
261
+ return 0
262
+ fi
263
+ printf '%s/skills/openclaw/%s\n' "${shared_home}" "${compat_alias}"
264
+ }
265
+
266
+ flow_export_project_env_aliases
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ FLOW_TOOLS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+ TEST_DIR="${FLOW_TOOLS_DIR%/bin}/tests"
6
+ TEST_TIMEOUT_SECONDS="${F_LOSNING_HEARTBEAT_PREFLIGHT_TEST_TIMEOUT_SECONDS:-120}"
7
+
8
+ run_with_timeout() {
9
+ local timeout_seconds="${1:?timeout seconds required}"
10
+ shift
11
+
12
+ /opt/homebrew/bin/python3 - "$timeout_seconds" "$@" <<'PY'
13
+ import os
14
+ import signal
15
+ import subprocess
16
+ import sys
17
+
18
+ timeout_seconds = float(sys.argv[1])
19
+ argv = sys.argv[2:]
20
+
21
+ if not argv:
22
+ sys.exit(64)
23
+
24
+ proc = subprocess.Popen(argv, start_new_session=True)
25
+ try:
26
+ sys.exit(proc.wait(timeout=timeout_seconds))
27
+ except subprocess.TimeoutExpired:
28
+ try:
29
+ os.killpg(proc.pid, signal.SIGTERM)
30
+ except ProcessLookupError:
31
+ pass
32
+ try:
33
+ proc.wait(timeout=2)
34
+ except subprocess.TimeoutExpired:
35
+ try:
36
+ os.killpg(proc.pid, signal.SIGKILL)
37
+ except ProcessLookupError:
38
+ pass
39
+ proc.wait()
40
+ sys.exit(124)
41
+ PY
42
+ }
43
+
44
+ run_preflight_test() {
45
+ local label="${1:?label required}"
46
+ local script_path="${2:?script path required}"
47
+ local started_at
48
+
49
+ started_at="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
50
+ printf '[%s] heartbeat preflight start name=%s\n' "$started_at" "$label"
51
+
52
+ if run_with_timeout "$TEST_TIMEOUT_SECONDS" bash "$script_path"; then
53
+ printf '[%s] heartbeat preflight end name=%s status=0\n' "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" "$label"
54
+ return 0
55
+ fi
56
+
57
+ local test_status=$?
58
+ if [[ "$test_status" == "124" ]]; then
59
+ printf 'HEARTBEAT_PREFLIGHT_TIMEOUT=%s\n' "$label"
60
+ fi
61
+ printf '[%s] heartbeat preflight end name=%s status=%s\n' "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" "$label" "$test_status"
62
+ return "$test_status"
63
+ }
64
+
65
+ run_preflight_test "codex-recovery" "${TEST_DIR}/test-agent-project-codex-recovery.sh"
66
+ run_preflight_test "codex-quota-manager-failure-driven-rotation" "${TEST_DIR}/test-codex-quota-manager-failure-driven-rotation.sh"
67
+ run_preflight_test "codex-quota-wrapper" "${TEST_DIR}/test-codex-quota-wrapper.sh"
68
+ run_preflight_test "codex-quota-resolvers" "${TEST_DIR}/test-flow-resolve-codex-quota-tools.sh"
69
+ run_preflight_test "codex-live-thread-persist" "${TEST_DIR}/test-agent-project-codex-live-thread-persist.sh"
70
+ run_preflight_test "reconcile-failure-reason" "${TEST_DIR}/test-agent-project-reconcile-failure-reason.sh"
71
+ run_preflight_test "reconcile-pr-updated-branch-noop" "${TEST_DIR}/test-agent-project-reconcile-pr-updated-branch-noop.sh"
72
+ run_preflight_test "reconcile-pr-guard-blocked-no-commit" "${TEST_DIR}/test-agent-project-reconcile-pr-guard-blocked-no-commit.sh"
73
+ run_preflight_test "reconcile-pr-blocked-host-recovery" "${TEST_DIR}/test-agent-project-reconcile-pr-blocked-host-recovery.sh"
74
+ run_preflight_test "branch-verification-guard-targeted-coverage" "${TEST_DIR}/test-branch-verification-guard-targeted-coverage.sh"
75
+ run_preflight_test "branch-verification-guard-generated-artifacts" "${TEST_DIR}/test-branch-verification-guard-generated-artifacts.sh"
76
+ run_preflight_test "codex-session-wrapper" "${TEST_DIR}/test-agent-project-codex-session-wrapper.sh"
77
+ run_preflight_test "openclaw-session-wrapper" "${TEST_DIR}/test-agent-project-openclaw-session-wrapper.sh"
78
+ run_preflight_test "cleanup-session-orphan-fallback" "${TEST_DIR}/test-agent-project-cleanup-session-orphan-fallback.sh"
79
+ run_preflight_test "heartbeat-no-tmux-sessions" "${TEST_DIR}/test-heartbeat-safe-auto-no-tmux-sessions.sh"
80
+ run_preflight_test "heartbeat-static-capacity-without-quota-cache" "${TEST_DIR}/test-heartbeat-safe-auto-static-capacity-without-quota-cache.sh"
81
+ run_preflight_test "heartbeat-openclaw-skips-codex-quota" "${TEST_DIR}/test-heartbeat-safe-auto-openclaw-skips-codex-quota.sh"
82
+ run_preflight_test "heartbeat-empty-schedule-label-sync" "${TEST_DIR}/test-heartbeat-sync-issue-labels-empty-schedule.sh"
83
+ run_preflight_test "heartbeat-open-pr-terminal-sync" "${TEST_DIR}/test-heartbeat-sync-open-agent-prs-terminal-clears-running.sh"
84
+ run_preflight_test "heartbeat-pr-launch-dedup" "${TEST_DIR}/test-heartbeat-loop-pr-launch-dedup.sh"
85
+ run_preflight_test "heartbeat-auth-wait-capacity" "${TEST_DIR}/test-heartbeat-loop-auth-wait-does-not-consume-capacity.sh"
86
+ run_preflight_test "heartbeat-blocked-recovery-ready" "${TEST_DIR}/test-heartbeat-ready-issues-blocked-recovery.sh"
87
+ run_preflight_test "heartbeat-blocked-recovery-lane" "${TEST_DIR}/test-heartbeat-loop-blocked-recovery-lane.sh"
88
+ run_preflight_test "heartbeat-blocked-recovery-vs-pr-reservation" "${TEST_DIR}/test-heartbeat-loop-blocked-recovery-vs-pr-reservation.sh"
89
+ run_preflight_test "heartbeat-codex-pr-linked-issue-exclusion" "${TEST_DIR}/test-heartbeat-codex-pr-linked-issue-exclusion.sh"
90
+ run_preflight_test "create-follow-up-issue" "${TEST_DIR}/test-create-follow-up-issue.sh"
91
+ run_preflight_test "issue-local-workspace-install-policy" "${TEST_DIR}/test-issue-local-workspace-install-policy.sh"
92
+ run_preflight_test "issue-publish-scope-guard-docs-signal" "${TEST_DIR}/test-issue-publish-scope-guard-docs-signal.sh"
93
+ run_preflight_test "issue-before-blocked-hook" "${TEST_DIR}/test-agent-project-reconcile-issue-before-blocked.sh"
94
+ run_preflight_test "start-issue-worker-local-install-routing" "${TEST_DIR}/test-start-issue-worker-local-install-routing.sh"
95
+ run_preflight_test "start-issue-worker-blocked-context" "${TEST_DIR}/test-start-issue-worker-blocked-context.sh"
96
+ run_preflight_test "start-pr-fix-worker-host-blocker-context" "${TEST_DIR}/test-start-pr-fix-worker-host-blocker-context.sh"
97
+ run_preflight_test "run-codex-task-openclaw-routing" "${TEST_DIR}/test-run-codex-task-openclaw-routing.sh"
98
+ run_preflight_test "pr-risk-local-first-no-checks" "${TEST_DIR}/test-pr-risk-local-first-no-checks.sh"
99
+ run_preflight_test "pr-risk-fix-label-semantics" "${TEST_DIR}/test-pr-risk-fix-label-semantics.sh"
100
+ run_preflight_test "sync-pr-labels-fix-lane-uses-repair-queued" "${TEST_DIR}/test-sync-pr-labels-fix-lane-uses-repair-queued.sh"
101
+ run_preflight_test "audit-broken-worktree-cleanup" "${TEST_DIR}/test-audit-agent-worktrees-broken-worktree.sh"
102
+ run_preflight_test "audit-active-launch-skip" "${TEST_DIR}/test-audit-agent-worktrees-active-launch-skips-git-inspection.sh"
103
+ run_preflight_test "audit-pending-launch-owner" "${TEST_DIR}/test-audit-agent-worktrees-pending-launch-owner.sh"
104
+ run_preflight_test "audit-unreconciled-owner" "${TEST_DIR}/test-audit-agent-worktrees-unreconciled-owner.sh"
105
+
106
+ printf 'HEARTBEAT_PREFLIGHT_OK\n'