agent-control-plane 0.1.2 → 0.1.3
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.
- package/README.md +6 -0
- package/npm/bin/agent-control-plane.js +149 -5
- package/package.json +1 -2
- package/tools/tests/test-agent-control-plane-npm-cli.sh +0 -280
- package/tools/tests/test-agent-github-update-labels-falls-back-to-repository-id.sh +0 -56
- package/tools/tests/test-agent-project-claude-session-wrapper-clears-stale-sandbox-artifacts.sh +0 -89
- package/tools/tests/test-agent-project-claude-session-wrapper-does-not-retry-provider-quota.sh +0 -82
- package/tools/tests/test-agent-project-claude-session-wrapper-retries-transient-failures.sh +0 -90
- package/tools/tests/test-agent-project-claude-session-wrapper-times-out.sh +0 -73
- package/tools/tests/test-agent-project-claude-session-wrapper.sh +0 -103
- package/tools/tests/test-agent-project-cleanup-session-orphan-fallback.sh +0 -90
- package/tools/tests/test-agent-project-cleanup-session-skip-worktree-cleanup.sh +0 -90
- package/tools/tests/test-agent-project-codex-live-thread-persist.sh +0 -76
- package/tools/tests/test-agent-project-codex-recovery.sh +0 -731
- package/tools/tests/test-agent-project-codex-session-wrapper-clears-stale-sandbox-artifacts.sh +0 -105
- package/tools/tests/test-agent-project-codex-session-wrapper.sh +0 -97
- package/tools/tests/test-agent-project-open-pr-worktree-config-prefix.sh +0 -81
- package/tools/tests/test-agent-project-openclaw-session-wrapper-clears-stale-sandbox-artifacts.sh +0 -109
- package/tools/tests/test-agent-project-openclaw-session-wrapper-infers-blocked-result-contract.sh +0 -89
- package/tools/tests/test-agent-project-openclaw-session-wrapper-recovers-literal-env-artifacts.sh +0 -113
- package/tools/tests/test-agent-project-openclaw-session-wrapper-recovers-version-mismatch.sh +0 -135
- package/tools/tests/test-agent-project-openclaw-session-wrapper-resident.sh +0 -179
- package/tools/tests/test-agent-project-openclaw-session-wrapper-reuses-existing-agent-after-add-race.sh +0 -119
- package/tools/tests/test-agent-project-openclaw-session-wrapper-terminates-rate-limit-hang.sh +0 -91
- package/tools/tests/test-agent-project-openclaw-session-wrapper.sh +0 -117
- package/tools/tests/test-agent-project-publish-issue-pr-prunes-stale-worktree-entry.sh +0 -148
- package/tools/tests/test-agent-project-publish-issue-pr-reads-archived-session.sh +0 -146
- package/tools/tests/test-agent-project-publish-issue-pr-recovers-final-head.sh +0 -145
- package/tools/tests/test-agent-project-publish-issue-pr-reuses-existing-worktree.sh +0 -147
- package/tools/tests/test-agent-project-reconcile-failure-reason.sh +0 -456
- package/tools/tests/test-agent-project-reconcile-issue-archived-session-fallback.sh +0 -96
- package/tools/tests/test-agent-project-reconcile-issue-before-blocked.sh +0 -90
- package/tools/tests/test-agent-project-reconcile-issue-host-verification-recovery-uses-recovered-worktree.sh +0 -212
- package/tools/tests/test-agent-project-reconcile-issue-host-verification-recovery.sh +0 -207
- package/tools/tests/test-agent-project-reconcile-issue-provider-quota-schedules-provider-cooldown.sh +0 -101
- package/tools/tests/test-agent-project-reconcile-issue-session-backfills-lane-metadata-from-worker-key.sh +0 -113
- package/tools/tests/test-agent-project-reconcile-issue-session-clears-stale-failed-summary.sh +0 -117
- package/tools/tests/test-agent-project-reconcile-issue-session-initializes-shared-agent-home.sh +0 -55
- package/tools/tests/test-agent-project-reconcile-issue-session-normalizes-runner-state.sh +0 -125
- package/tools/tests/test-agent-project-reconcile-issue-session-records-invalid-contract-summary.sh +0 -118
- package/tools/tests/test-agent-project-reconcile-issue-session-skips-duplicate-blocked-comment.sh +0 -144
- package/tools/tests/test-agent-project-reconcile-issue-session-standardizes-no-commits-blocker.sh +0 -145
- package/tools/tests/test-agent-project-reconcile-issue-session-synthesizes-blocked-comment.sh +0 -139
- package/tools/tests/test-agent-project-reconcile-pr-blocked-host-recovery.sh +0 -242
- package/tools/tests/test-agent-project-reconcile-pr-guard-blocked-no-commit.sh +0 -142
- package/tools/tests/test-agent-project-reconcile-pr-provider-quota-schedules-provider-cooldown.sh +0 -106
- package/tools/tests/test-agent-project-reconcile-pr-session-initializes-shared-agent-home.sh +0 -66
- package/tools/tests/test-agent-project-reconcile-pr-updated-branch-noop.sh +0 -129
- package/tools/tests/test-audit-agent-worktrees-active-launch-skips-git-inspection.sh +0 -69
- package/tools/tests/test-audit-agent-worktrees-broken-worktree.sh +0 -43
- package/tools/tests/test-audit-agent-worktrees-pending-launch-owner.sh +0 -46
- package/tools/tests/test-audit-agent-worktrees-unreconciled-owner.sh +0 -79
- package/tools/tests/test-audit-issue-routing-managed-branch-globs.sh +0 -56
- package/tools/tests/test-branch-verification-guard-generated-artifacts.sh +0 -72
- package/tools/tests/test-branch-verification-guard-targeted-coverage.sh +0 -125
- package/tools/tests/test-codex-quota-manager-failure-driven-rotation.sh +0 -178
- package/tools/tests/test-codex-quota-wrapper.sh +0 -37
- package/tools/tests/test-contribution-docs.sh +0 -18
- package/tools/tests/test-control-plane-dashboard-runtime-smoke.sh +0 -343
- package/tools/tests/test-create-follow-up-issue.sh +0 -73
- package/tools/tests/test-dashboard-launchd-bootstrap.sh +0 -55
- package/tools/tests/test-flow-export-execution-env-exports-repo-id.sh +0 -30
- package/tools/tests/test-flow-export-github-cli-auth-env-prefers-git-credential.sh +0 -48
- package/tools/tests/test-flow-github-api-repo-fallback-preserves-input.sh +0 -85
- package/tools/tests/test-flow-github-api-repo-prefers-explicit-repository-id.sh +0 -60
- package/tools/tests/test-flow-github-issue-list-falls-back-to-repository-id.sh +0 -64
- package/tools/tests/test-flow-github-pr-list-falls-back-to-repository-id.sh +0 -77
- package/tools/tests/test-flow-resident-can-reuse-does-not-leak-metadata.sh +0 -52
- package/tools/tests/test-flow-resident-reap-stale-controllers.sh +0 -63
- package/tools/tests/test-flow-resolve-codex-quota-tools.sh +0 -104
- package/tools/tests/test-flow-runtime-doctor-profile-selection.sh +0 -27
- package/tools/tests/test-heartbeat-codex-pr-linked-issue-exclusion.sh +0 -79
- package/tools/tests/test-heartbeat-hooks-enqueue-resident-issue-for-idle-controller.sh +0 -115
- package/tools/tests/test-heartbeat-hooks-enqueue-resident-issue-for-live-lane-controller.sh +0 -117
- package/tools/tests/test-heartbeat-hooks-start-resident-issue-loop-claude.sh +0 -96
- package/tools/tests/test-heartbeat-hooks-start-resident-issue-loop-codex.sh +0 -96
- package/tools/tests/test-heartbeat-hooks-start-resident-issue-loop.sh +0 -96
- package/tools/tests/test-heartbeat-loop-auth-wait-does-not-consume-capacity.sh +0 -170
- package/tools/tests/test-heartbeat-loop-blocked-recovery-lane.sh +0 -201
- package/tools/tests/test-heartbeat-loop-blocked-recovery-vs-pr-reservation.sh +0 -201
- package/tools/tests/test-heartbeat-loop-idle-resident-controller-does-not-block-launches.sh +0 -160
- package/tools/tests/test-heartbeat-loop-pr-launch-dedup.sh +0 -133
- package/tools/tests/test-heartbeat-loop-provider-cooldown-suppresses-launches.sh +0 -157
- package/tools/tests/test-heartbeat-loop-reaps-stale-resident-controller.sh +0 -181
- package/tools/tests/test-heartbeat-loop-waiting-provider-resident-controller-does-not-block-launches.sh +0 -160
- package/tools/tests/test-heartbeat-ready-issues-blocked-recovery.sh +0 -134
- package/tools/tests/test-heartbeat-safe-auto-dynamic-concurrency.sh +0 -162
- package/tools/tests/test-heartbeat-safe-auto-no-tmux-sessions.sh +0 -136
- package/tools/tests/test-heartbeat-safe-auto-openclaw-skips-codex-quota.sh +0 -139
- package/tools/tests/test-heartbeat-safe-auto-quota-health-signal.sh +0 -119
- package/tools/tests/test-heartbeat-safe-auto-stale-shared-loop-pid-does-not-skip.sh +0 -140
- package/tools/tests/test-heartbeat-safe-auto-static-capacity-without-quota-cache.sh +0 -142
- package/tools/tests/test-heartbeat-safe-auto-zero-healthy-pools.sh +0 -141
- package/tools/tests/test-heartbeat-sync-issue-labels-empty-schedule.sh +0 -65
- package/tools/tests/test-heartbeat-sync-open-agent-prs-terminal-clears-running.sh +0 -179
- package/tools/tests/test-install-dashboard-launchd.sh +0 -78
- package/tools/tests/test-install-project-launchd-adds-tool-paths.sh +0 -87
- package/tools/tests/test-install-project-launchd.sh +0 -110
- package/tools/tests/test-issue-local-workspace-install-policy.sh +0 -81
- package/tools/tests/test-issue-publish-scope-guard-docs-signal.sh +0 -70
- package/tools/tests/test-issue-reconcile-hooks-success-clears-blocked.sh +0 -36
- package/tools/tests/test-kick-scheduler-requires-explicit-profile.sh +0 -47
- package/tools/tests/test-label-follow-up-issues-falls-back-to-repository-id.sh +0 -132
- package/tools/tests/test-manual-operator-entrypoints-require-explicit-profile.sh +0 -64
- package/tools/tests/test-package-funding-metadata.sh +0 -21
- package/tools/tests/test-package-public-metadata.sh +0 -62
- package/tools/tests/test-placeholder-worker-adapters.sh +0 -38
- package/tools/tests/test-pr-reconcile-hooks-refreshes-recurring-issue-checklist.sh +0 -110
- package/tools/tests/test-pr-risk-cohesive-mobile-locale-scope.sh +0 -70
- package/tools/tests/test-pr-risk-fix-label-semantics.sh +0 -114
- package/tools/tests/test-pr-risk-local-first-no-checks.sh +0 -70
- package/tools/tests/test-prepare-worktree-simple-repo-baseline.sh +0 -67
- package/tools/tests/test-profile-activate.sh +0 -33
- package/tools/tests/test-profile-adopt-allow-missing-repo.sh +0 -68
- package/tools/tests/test-profile-adopt-skip-workspace-sync-missing-file.sh +0 -61
- package/tools/tests/test-profile-adopt-syncs-anchor-and-workspace.sh +0 -90
- package/tools/tests/test-profile-smoke-collision.sh +0 -44
- package/tools/tests/test-profile-smoke-invalid-claude-config.sh +0 -31
- package/tools/tests/test-profile-smoke-invalid-provider-pool.sh +0 -68
- package/tools/tests/test-profile-smoke-repo-slug-mismatch.sh +0 -36
- package/tools/tests/test-profile-smoke.sh +0 -45
- package/tools/tests/test-project-init-force-and-skip-sync.sh +0 -61
- package/tools/tests/test-project-init-repo-slug-mismatch.sh +0 -29
- package/tools/tests/test-project-init.sh +0 -66
- package/tools/tests/test-project-launchd-bootstrap.sh +0 -66
- package/tools/tests/test-project-remove.sh +0 -150
- package/tools/tests/test-project-runtime-supervisor.sh +0 -47
- package/tools/tests/test-project-runtimectl-launchd.sh +0 -115
- package/tools/tests/test-project-runtimectl-missing-profile.sh +0 -54
- package/tools/tests/test-project-runtimectl-start-falls-back-to-bootstrap.sh +0 -108
- package/tools/tests/test-project-runtimectl-status-reports-supervisor-as-heartbeat-parent.sh +0 -95
- package/tools/tests/test-project-runtimectl-status-supervisor-running.sh +0 -59
- package/tools/tests/test-project-runtimectl-stop-cancels-pending-kick.sh +0 -85
- package/tools/tests/test-project-runtimectl-stop-clears-running-labels.sh +0 -78
- package/tools/tests/test-project-runtimectl.sh +0 -212
- package/tools/tests/test-provider-cooldown-state-prefers-runtime-worker-context.sh +0 -39
- package/tools/tests/test-provider-cooldown-state.sh +0 -59
- package/tools/tests/test-public-repo-docs.sh +0 -161
- package/tools/tests/test-reconcile-pr-worker-acp-config-routing.sh +0 -75
- package/tools/tests/test-render-dashboard-snapshot.sh +0 -149
- package/tools/tests/test-render-flow-config-demo-profile.sh +0 -36
- package/tools/tests/test-render-flow-config-provider-pool-fallback.sh +0 -81
- package/tools/tests/test-render-flow-config.sh +0 -52
- package/tools/tests/test-run-codex-task-claude-routing.sh +0 -125
- package/tools/tests/test-run-codex-task-codex-resident-routing.sh +0 -108
- package/tools/tests/test-run-codex-task-kilo-routing.sh +0 -98
- package/tools/tests/test-run-codex-task-openclaw-resident-routing.sh +0 -117
- package/tools/tests/test-run-codex-task-openclaw-routing.sh +0 -113
- package/tools/tests/test-run-codex-task-opencode-routing.sh +0 -98
- package/tools/tests/test-run-codex-task-provider-pool-fallback-routing.sh +0 -146
- package/tools/tests/test-scaffold-profile.sh +0 -108
- package/tools/tests/test-serve-dashboard.sh +0 -93
- package/tools/tests/test-start-issue-worker-blocked-context.sh +0 -129
- package/tools/tests/test-start-issue-worker-blocks-complete-recurring-checklist.sh +0 -189
- package/tools/tests/test-start-issue-worker-local-install-routing.sh +0 -157
- package/tools/tests/test-start-issue-worker-profile-template-routing.sh +0 -149
- package/tools/tests/test-start-issue-worker-recurring-resident-reuse-codex.sh +0 -212
- package/tools/tests/test-start-issue-worker-recurring-resident-reuse.sh +0 -219
- package/tools/tests/test-start-issue-worker-renders-verification-snippet.sh +0 -155
- package/tools/tests/test-start-issue-worker-resident-reuse-falls-back-to-new-worktree.sh +0 -199
- package/tools/tests/test-start-pr-fix-worker-host-blocker-context.sh +0 -275
- package/tools/tests/test-start-resident-issue-loop-adopts-next-recurring-issue.sh +0 -185
- package/tools/tests/test-start-resident-issue-loop-clears-pending-while-waiting-due.sh +0 -152
- package/tools/tests/test-start-resident-issue-loop-consumes-queued-lease.sh +0 -186
- package/tools/tests/test-start-resident-issue-loop-fails-over-provider-pool.sh +0 -212
- package/tools/tests/test-start-resident-issue-loop-immediate-cycles.sh +0 -148
- package/tools/tests/test-start-resident-issue-loop-waits-for-provider.sh +0 -194
- package/tools/tests/test-start-resident-issue-loop-waits-for-terminal-reconcile-status.sh +0 -198
- package/tools/tests/test-start-resident-issue-loop-yields-to-live-lane-controller.sh +0 -145
- package/tools/tests/test-sync-pr-labels-fix-lane-uses-repair-queued.sh +0 -67
- package/tools/tests/test-sync-recurring-issue-checklist-backfills-workflow-complete-blocker.sh +0 -70
- package/tools/tests/test-sync-recurring-issue-checklist.sh +0 -95
- package/tools/tests/test-sync-shared-agent-home-local-source-root.sh +0 -66
- package/tools/tests/test-sync-shared-agent-home-preserves-unrelated-workflow-catalog-skill.sh +0 -47
- package/tools/tests/test-test-smoke.sh +0 -86
- package/tools/tests/test-uninstall-project-launchd.sh +0 -37
- package/tools/tests/test-update-github-labels-prefers-sibling-helper.sh +0 -49
- package/tools/tests/test-vendored-codex-quota-claude-oauth-only.sh +0 -38
- package/tools/tests/test-workflow-catalog.sh +0 -43
package/README.md
CHANGED
|
@@ -302,6 +302,9 @@ During `setup`, ACP can:
|
|
|
302
302
|
`openclaw` when ACP knows a safe install command, and otherwise show
|
|
303
303
|
backend-specific next steps, install/auth/verify examples, and a docs URL it
|
|
304
304
|
can open for you on interactive machines
|
|
305
|
+
- defer anchor repo sync automatically when ACP can scaffold the profile but
|
|
306
|
+
cannot reach the repo remote yet, so setup can still finish with a clear
|
|
307
|
+
follow-up instead of failing half way through
|
|
305
308
|
- run one final fix-up summary at the end so you can clear whatever is still
|
|
306
309
|
red instead of guessing which step to retry next
|
|
307
310
|
- scaffold the profile, run doctor checks, and optionally start the runtime in
|
|
@@ -550,6 +553,9 @@ Use `--purge-paths` only when you want ACP-managed directories removed too.
|
|
|
550
553
|
`launchd-uninstall`, and `remove`.
|
|
551
554
|
- `gh` cannot access the repo
|
|
552
555
|
Re-run `gh auth login` and confirm the repo slug in the profile is correct.
|
|
556
|
+
- setup deferred anchor repo sync
|
|
557
|
+
ACP could not reach the repo remote yet. Fix Git access or the remote URL,
|
|
558
|
+
then rerun `setup` or `init` without `--skip-anchor-sync`.
|
|
553
559
|
- backend auth failures from `codex`, `claude`, or `openclaw`
|
|
554
560
|
Authenticate that backend before starting ACP in the background.
|
|
555
561
|
- `node` is older than `18`
|
|
@@ -191,12 +191,14 @@ function runCapture(command, args, options = {}) {
|
|
|
191
191
|
const result = spawnSync(command, args, {
|
|
192
192
|
encoding: "utf8",
|
|
193
193
|
env: options.env || process.env,
|
|
194
|
-
cwd: options.cwd || process.cwd()
|
|
194
|
+
cwd: options.cwd || process.cwd(),
|
|
195
|
+
timeout: options.timeoutMs || 0
|
|
195
196
|
});
|
|
196
197
|
return {
|
|
197
198
|
status: typeof result.status === "number" ? result.status : (result.error ? 1 : 0),
|
|
198
199
|
stdout: result.stdout || "",
|
|
199
|
-
stderr: result.stderr || ""
|
|
200
|
+
stderr: result.stderr || "",
|
|
201
|
+
error: result.error || null
|
|
200
202
|
};
|
|
201
203
|
}
|
|
202
204
|
|
|
@@ -1044,6 +1046,92 @@ function printPrereqSummary(prereq) {
|
|
|
1044
1046
|
console.log(`- backend note: ${backendReadinessHint(prereq.workerCommand)}`);
|
|
1045
1047
|
}
|
|
1046
1048
|
|
|
1049
|
+
function probeAnchorSyncReadiness(repoRoot) {
|
|
1050
|
+
if (!repoRoot || !fs.existsSync(repoRoot)) {
|
|
1051
|
+
return {
|
|
1052
|
+
status: "deferred",
|
|
1053
|
+
reason: "source-repo-missing",
|
|
1054
|
+
remoteUrl: "",
|
|
1055
|
+
details: ""
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
const remoteResult = runCapture("git", ["remote", "get-url", "origin"], {
|
|
1060
|
+
cwd: repoRoot,
|
|
1061
|
+
timeoutMs: 5000
|
|
1062
|
+
});
|
|
1063
|
+
const remoteUrl = remoteResult.stdout.trim();
|
|
1064
|
+
if (remoteResult.status !== 0 || !remoteUrl) {
|
|
1065
|
+
return {
|
|
1066
|
+
status: "deferred",
|
|
1067
|
+
reason: "no-origin-remote",
|
|
1068
|
+
remoteUrl: "",
|
|
1069
|
+
details: `${remoteResult.stdout}${remoteResult.stderr}`.trim()
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
const probeResult = runCapture("git", ["ls-remote", "--exit-code", "origin", "HEAD"], {
|
|
1074
|
+
cwd: repoRoot,
|
|
1075
|
+
timeoutMs: 15000
|
|
1076
|
+
});
|
|
1077
|
+
if (probeResult.status === 0) {
|
|
1078
|
+
return {
|
|
1079
|
+
status: "ready",
|
|
1080
|
+
reason: "",
|
|
1081
|
+
remoteUrl,
|
|
1082
|
+
details: ""
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
const details = `${probeResult.stdout}${probeResult.stderr}`.trim();
|
|
1087
|
+
let reason = "git-remote-unreachable";
|
|
1088
|
+
if (probeResult.error && probeResult.error.code === "ETIMEDOUT") {
|
|
1089
|
+
reason = "git-remote-timeout";
|
|
1090
|
+
} else if (/could not read Username|Authentication failed|Permission denied|Repository not found|access denied|not found/i.test(details)) {
|
|
1091
|
+
reason = "git-remote-auth-or-access-error";
|
|
1092
|
+
} else if (/Could not resolve host|Name or service not known|Temporary failure in name resolution/i.test(details)) {
|
|
1093
|
+
reason = "git-remote-dns-error";
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
return {
|
|
1097
|
+
status: "deferred",
|
|
1098
|
+
reason,
|
|
1099
|
+
remoteUrl,
|
|
1100
|
+
details
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
function buildAnchorSyncDecision(options, sourceRepoRoot) {
|
|
1105
|
+
if (options.skipAnchorSync) {
|
|
1106
|
+
return {
|
|
1107
|
+
status: "skipped",
|
|
1108
|
+
reason: "disabled",
|
|
1109
|
+
remoteUrl: "",
|
|
1110
|
+
details: "",
|
|
1111
|
+
skipAnchorSync: true
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
const probe = probeAnchorSyncReadiness(sourceRepoRoot);
|
|
1116
|
+
if (probe.status === "ready") {
|
|
1117
|
+
return {
|
|
1118
|
+
status: "ok",
|
|
1119
|
+
reason: "",
|
|
1120
|
+
remoteUrl: probe.remoteUrl,
|
|
1121
|
+
details: probe.details,
|
|
1122
|
+
skipAnchorSync: false
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
return {
|
|
1127
|
+
status: "deferred",
|
|
1128
|
+
reason: probe.reason,
|
|
1129
|
+
remoteUrl: probe.remoteUrl,
|
|
1130
|
+
details: probe.details,
|
|
1131
|
+
skipAnchorSync: true
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1047
1135
|
function profileExists(profileRegistryRoot, profileId) {
|
|
1048
1136
|
return fs.existsSync(path.join(profileRegistryRoot, profileId, "control-plane.yaml"));
|
|
1049
1137
|
}
|
|
@@ -1082,6 +1170,7 @@ function buildSetupDryRunPlan(options, context, config) {
|
|
|
1082
1170
|
const dependencyPlan = buildDependencyInstallPlan(prereq.missingRequired);
|
|
1083
1171
|
const workerInstallPlan = buildWorkerBackendInstallPlan(prereq.workerCommand);
|
|
1084
1172
|
const workerGuide = backendSetupGuide(prereq.workerCommand);
|
|
1173
|
+
const anchorSync = buildAnchorSyncDecision(options, config.paths.sourceRepoRoot);
|
|
1085
1174
|
|
|
1086
1175
|
let dependencyAction = planStatusWithReason("not-needed");
|
|
1087
1176
|
if (!prereq.coreToolsOk) {
|
|
@@ -1128,6 +1217,8 @@ function buildSetupDryRunPlan(options, context, config) {
|
|
|
1128
1217
|
runtimeStartAction = planStatusWithReason("blocked", `missing-tools:${prereq.missingRequired.join(",")}`);
|
|
1129
1218
|
} else if (!prereq.workerAvailable) {
|
|
1130
1219
|
runtimeStartAction = planStatusWithReason("blocked", `missing-worker:${prereq.workerCommand}`);
|
|
1220
|
+
} else if (anchorSync.status !== "ok") {
|
|
1221
|
+
runtimeStartAction = planStatusWithReason("blocked", `anchor-sync-${anchorSync.reason}`);
|
|
1131
1222
|
} else if (!prereq.ghAuthOk) {
|
|
1132
1223
|
runtimeStartAction = planStatusWithReason("blocked", "gh-auth-not-ready");
|
|
1133
1224
|
} else {
|
|
@@ -1156,6 +1247,7 @@ function buildSetupDryRunPlan(options, context, config) {
|
|
|
1156
1247
|
workerInstallPlan,
|
|
1157
1248
|
workerAction,
|
|
1158
1249
|
workerGuide,
|
|
1250
|
+
anchorSync,
|
|
1159
1251
|
githubAuthAction,
|
|
1160
1252
|
runtimeStartAction,
|
|
1161
1253
|
launchdAction
|
|
@@ -1170,6 +1262,7 @@ function printSetupDryRunPlan(context, config, plan) {
|
|
|
1170
1262
|
console.log(`- profile registry root: ${context.profileRegistryRoot}`);
|
|
1171
1263
|
console.log(`- sync packaged runtime: would-run`);
|
|
1172
1264
|
console.log(`- scaffold/adopt profile: would-run`);
|
|
1265
|
+
console.log(`- anchor repo sync: ${plan.anchorSync.status === "ok" ? "would-run" : `${plan.anchorSync.status} (${plan.anchorSync.reason})`}`);
|
|
1173
1266
|
console.log(`- doctor: would-run`);
|
|
1174
1267
|
console.log(`- dependency install: ${plan.dependencyAction.status}${plan.dependencyAction.reason ? ` (${plan.dependencyAction.reason})` : ""}`);
|
|
1175
1268
|
if (plan.dependencyAction.status !== "not-needed" && plan.dependencyPlan && plan.dependencyPlan.commands.length > 0) {
|
|
@@ -1202,6 +1295,11 @@ function buildSetupResultPayload(params) {
|
|
|
1202
1295
|
status: params.coreToolsStatus,
|
|
1203
1296
|
missingRequiredTools: params.missingRequiredTools
|
|
1204
1297
|
},
|
|
1298
|
+
anchorSync: {
|
|
1299
|
+
status: params.anchorSyncStatus,
|
|
1300
|
+
reason: params.anchorSyncReason,
|
|
1301
|
+
remoteUrl: params.anchorSyncRemoteUrl
|
|
1302
|
+
},
|
|
1205
1303
|
workerBackend: {
|
|
1206
1304
|
command: params.workerBackendCommand,
|
|
1207
1305
|
status: params.workerBackendStatus,
|
|
@@ -1252,6 +1350,9 @@ function emitSetupJsonPayload(payload) {
|
|
|
1252
1350
|
|
|
1253
1351
|
function collectFinalSetupIssues(config, prereq, doctorKv, runtimeStartStatus) {
|
|
1254
1352
|
const issues = [];
|
|
1353
|
+
if (config.anchorSync && config.anchorSync.status !== "ok") {
|
|
1354
|
+
issues.push(`anchor repo sync ${config.anchorSync.status}: ${config.anchorSync.reason}`);
|
|
1355
|
+
}
|
|
1255
1356
|
if (!prereq.coreToolsOk) {
|
|
1256
1357
|
issues.push(`missing core tools: ${prereq.missingRequired.join(", ")}`);
|
|
1257
1358
|
}
|
|
@@ -1271,7 +1372,11 @@ function collectFinalSetupIssues(config, prereq, doctorKv, runtimeStartStatus) {
|
|
|
1271
1372
|
}
|
|
1272
1373
|
|
|
1273
1374
|
async function maybeRunFinalSetupFixups(options, scopedContext, config, currentState) {
|
|
1274
|
-
const
|
|
1375
|
+
const effectiveConfig = {
|
|
1376
|
+
...config,
|
|
1377
|
+
anchorSync: currentState.anchorSync || config.anchorSync || null
|
|
1378
|
+
};
|
|
1379
|
+
const issues = collectFinalSetupIssues(effectiveConfig, currentState.prereq, currentState.doctorKv, currentState.runtimeStartStatus);
|
|
1275
1380
|
if (issues.length === 0) {
|
|
1276
1381
|
return {
|
|
1277
1382
|
status: "not-needed",
|
|
@@ -1315,6 +1420,7 @@ async function maybeRunFinalSetupFixups(options, scopedContext, config, currentS
|
|
|
1315
1420
|
let githubAuthStep = currentState.githubAuthStep;
|
|
1316
1421
|
let workerSetupStep = currentState.workerSetupStep;
|
|
1317
1422
|
let doctorKv = currentState.doctorKv;
|
|
1423
|
+
let anchorSync = currentState.anchorSync || effectiveConfig.anchorSync || null;
|
|
1318
1424
|
let runtimeStartStatus = currentState.runtimeStartStatus;
|
|
1319
1425
|
let runtimeStartReason = currentState.runtimeStartReason;
|
|
1320
1426
|
let runtimeStatusKv = currentState.runtimeStatusKv;
|
|
@@ -1353,6 +1459,9 @@ async function maybeRunFinalSetupFixups(options, scopedContext, config, currentS
|
|
|
1353
1459
|
} else if (!prereq.workerAvailable) {
|
|
1354
1460
|
runtimeStartStatus = "skipped";
|
|
1355
1461
|
runtimeStartReason = `missing-worker:${prereq.workerCommand}`;
|
|
1462
|
+
} else if (anchorSync && anchorSync.status !== "ok") {
|
|
1463
|
+
runtimeStartStatus = "skipped";
|
|
1464
|
+
runtimeStartReason = `anchor-sync-${anchorSync.reason}`;
|
|
1356
1465
|
} else if (!prereq.ghAuthOk) {
|
|
1357
1466
|
runtimeStartStatus = "skipped";
|
|
1358
1467
|
runtimeStartReason = "gh-auth-not-ready";
|
|
@@ -1376,7 +1485,7 @@ async function maybeRunFinalSetupFixups(options, scopedContext, config, currentS
|
|
|
1376
1485
|
launchdInstallReason = "";
|
|
1377
1486
|
}
|
|
1378
1487
|
|
|
1379
|
-
const finalIssues = collectFinalSetupIssues(
|
|
1488
|
+
const finalIssues = collectFinalSetupIssues({ ...effectiveConfig, anchorSync }, prereq, doctorKv, runtimeStartStatus);
|
|
1380
1489
|
let status = "ok";
|
|
1381
1490
|
if (dependencyInstall.status === "failed" || githubAuthStep.status === "failed" || workerSetupStep.installStatus === "failed") {
|
|
1382
1491
|
status = "failed";
|
|
@@ -1387,6 +1496,7 @@ async function maybeRunFinalSetupFixups(options, scopedContext, config, currentS
|
|
|
1387
1496
|
return {
|
|
1388
1497
|
status,
|
|
1389
1498
|
actions,
|
|
1499
|
+
anchorSync,
|
|
1390
1500
|
prereq,
|
|
1391
1501
|
dependencyInstall,
|
|
1392
1502
|
githubAuthStep,
|
|
@@ -1564,6 +1674,9 @@ async function runSetupFlow(forwardedArgs) {
|
|
|
1564
1674
|
worktreeRoot: config.paths.worktreeRoot,
|
|
1565
1675
|
coreToolsStatus: plan.prereq.coreToolsOk ? "ok" : "missing",
|
|
1566
1676
|
missingRequiredTools: plan.prereq.missingRequired,
|
|
1677
|
+
anchorSyncStatus: plan.anchorSync.status === "ok" ? "would-run" : plan.anchorSync.status,
|
|
1678
|
+
anchorSyncReason: plan.anchorSync.reason || "",
|
|
1679
|
+
anchorSyncRemoteUrl: plan.anchorSync.remoteUrl || "",
|
|
1567
1680
|
workerBackendCommand: plan.prereq.workerCommand,
|
|
1568
1681
|
workerBackendStatus: plan.prereq.workerAvailable ? "ok" : "missing",
|
|
1569
1682
|
workerSetupGuideStatus: "planned",
|
|
@@ -1610,6 +1723,13 @@ async function runSetupFlow(forwardedArgs) {
|
|
|
1610
1723
|
console.log(`PROFILE_EXISTS=${plan.profileExists ? "yes" : "no"}`);
|
|
1611
1724
|
console.log(`CORE_TOOLS_STATUS=${plan.prereq.coreToolsOk ? "ok" : "missing"}`);
|
|
1612
1725
|
console.log(`MISSING_REQUIRED_TOOLS=${plan.prereq.missingRequired.join(",")}`);
|
|
1726
|
+
console.log(`ANCHOR_SYNC_STATUS=${plan.anchorSync.status === "ok" ? "would-run" : plan.anchorSync.status}`);
|
|
1727
|
+
if (plan.anchorSync.reason) {
|
|
1728
|
+
console.log(`ANCHOR_SYNC_REASON=${plan.anchorSync.reason}`);
|
|
1729
|
+
}
|
|
1730
|
+
if (plan.anchorSync.remoteUrl) {
|
|
1731
|
+
console.log(`ANCHOR_SYNC_REMOTE_URL=${plan.anchorSync.remoteUrl}`);
|
|
1732
|
+
}
|
|
1613
1733
|
console.log(`WORKER_BACKEND_COMMAND=${plan.prereq.workerCommand}`);
|
|
1614
1734
|
console.log(`WORKER_BACKEND_STATUS=${plan.prereq.workerAvailable ? "ok" : "missing"}`);
|
|
1615
1735
|
console.log(`GITHUB_AUTH_STATUS=${plan.prereq.ghAuthOk ? "ok" : "not-ready"}`);
|
|
@@ -1686,6 +1806,16 @@ async function runSetupFlow(forwardedArgs) {
|
|
|
1686
1806
|
prereq = collectPrereqStatus(config.codingWorker);
|
|
1687
1807
|
|
|
1688
1808
|
const scopedContext = buildScopedContext(context, config.profileId);
|
|
1809
|
+
const anchorSync = buildAnchorSyncDecision(options, config.paths.sourceRepoRoot);
|
|
1810
|
+
|
|
1811
|
+
if (anchorSync.status === "deferred") {
|
|
1812
|
+
console.log("\nAnchor repo sync will be deferred for this setup run.");
|
|
1813
|
+
if (anchorSync.remoteUrl) {
|
|
1814
|
+
console.log(`- remote: ${anchorSync.remoteUrl}`);
|
|
1815
|
+
}
|
|
1816
|
+
console.log(`- reason: ${anchorSync.reason}`);
|
|
1817
|
+
console.log("- next step: authenticate Git access or fix the repo remote, then rerun `setup` or `init` without skipping anchor sync.");
|
|
1818
|
+
}
|
|
1689
1819
|
|
|
1690
1820
|
runSetupStep(scopedContext, "Sync packaged runtime into ~/.agent-runtime", "tools/bin/sync-shared-agent-home.sh", []);
|
|
1691
1821
|
|
|
@@ -1704,7 +1834,7 @@ async function runSetupFlow(forwardedArgs) {
|
|
|
1704
1834
|
if (options.force) {
|
|
1705
1835
|
initArgs.push("--force");
|
|
1706
1836
|
}
|
|
1707
|
-
if (
|
|
1837
|
+
if (anchorSync.skipAnchorSync) {
|
|
1708
1838
|
initArgs.push("--skip-anchor-sync");
|
|
1709
1839
|
}
|
|
1710
1840
|
if (options.skipWorkspaceSync) {
|
|
@@ -1731,6 +1861,9 @@ async function runSetupFlow(forwardedArgs) {
|
|
|
1731
1861
|
} else if (!prereq.workerAvailable) {
|
|
1732
1862
|
runtimeStartReason = `missing-worker:${prereq.workerCommand}`;
|
|
1733
1863
|
console.log(`runtime start skipped: ${prereq.workerCommand} is not available on PATH`);
|
|
1864
|
+
} else if (anchorSync.status !== "ok") {
|
|
1865
|
+
runtimeStartReason = `anchor-sync-${anchorSync.reason}`;
|
|
1866
|
+
console.log("runtime start skipped: ACP deferred anchor repo sync for this setup run.");
|
|
1734
1867
|
} else if (!prereq.ghAuthOk) {
|
|
1735
1868
|
runtimeStartReason = "gh-auth-not-ready";
|
|
1736
1869
|
console.log("runtime start skipped: GitHub CLI is not authenticated yet. Run `gh auth login` and start the runtime afterwards.");
|
|
@@ -1760,6 +1893,7 @@ async function runSetupFlow(forwardedArgs) {
|
|
|
1760
1893
|
}
|
|
1761
1894
|
|
|
1762
1895
|
const finalFixup = await maybeRunFinalSetupFixups(options, scopedContext, config, {
|
|
1896
|
+
anchorSync,
|
|
1763
1897
|
prereq,
|
|
1764
1898
|
dependencyInstall,
|
|
1765
1899
|
githubAuthStep,
|
|
@@ -1796,6 +1930,9 @@ async function runSetupFlow(forwardedArgs) {
|
|
|
1796
1930
|
worktreeRoot: config.paths.worktreeRoot,
|
|
1797
1931
|
coreToolsStatus: prereq.coreToolsOk ? "ok" : "missing",
|
|
1798
1932
|
missingRequiredTools: prereq.missingRequired,
|
|
1933
|
+
anchorSyncStatus: anchorSync.status,
|
|
1934
|
+
anchorSyncReason: anchorSync.reason || "",
|
|
1935
|
+
anchorSyncRemoteUrl: anchorSync.remoteUrl || "",
|
|
1799
1936
|
workerBackendCommand: prereq.workerCommand,
|
|
1800
1937
|
workerBackendStatus: prereq.workerAvailable ? "ok" : "missing",
|
|
1801
1938
|
workerSetupGuideStatus: workerSetupStep.status,
|
|
@@ -1846,6 +1983,13 @@ async function runSetupFlow(forwardedArgs) {
|
|
|
1846
1983
|
console.log(`CODING_WORKER=${config.codingWorker}`);
|
|
1847
1984
|
console.log(`CORE_TOOLS_STATUS=${prereq.coreToolsOk ? "ok" : "missing"}`);
|
|
1848
1985
|
console.log(`MISSING_REQUIRED_TOOLS=${prereq.missingRequired.join(",")}`);
|
|
1986
|
+
console.log(`ANCHOR_SYNC_STATUS=${anchorSync.status}`);
|
|
1987
|
+
if (anchorSync.reason) {
|
|
1988
|
+
console.log(`ANCHOR_SYNC_REASON=${anchorSync.reason}`);
|
|
1989
|
+
}
|
|
1990
|
+
if (anchorSync.remoteUrl) {
|
|
1991
|
+
console.log(`ANCHOR_SYNC_REMOTE_URL=${anchorSync.remoteUrl}`);
|
|
1992
|
+
}
|
|
1849
1993
|
console.log(`WORKER_BACKEND_COMMAND=${prereq.workerCommand}`);
|
|
1850
1994
|
console.log(`WORKER_BACKEND_STATUS=${prereq.workerAvailable ? "ok" : "missing"}`);
|
|
1851
1995
|
console.log(`WORKER_SETUP_GUIDE_STATUS=${workerSetupStep.status}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-control-plane",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Help a repo keep GitHub-driven coding agents running reliably without constant human babysitting",
|
|
5
5
|
"homepage": "https://github.com/ducminhnguyen0319/agent-control-plane",
|
|
6
6
|
"bugs": {
|
|
@@ -32,7 +32,6 @@
|
|
|
32
32
|
"tools/dashboard/server.py",
|
|
33
33
|
"tools/dashboard/styles.css",
|
|
34
34
|
"tools/templates",
|
|
35
|
-
"tools/tests",
|
|
36
35
|
"tools/vendor/codex-quota/LICENSE",
|
|
37
36
|
"tools/vendor/codex-quota/codex-quota.js",
|
|
38
37
|
"tools/vendor/codex-quota/lib",
|
|
@@ -1,280 +0,0 @@
|
|
|
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
|
-
PACKAGE_VERSION="$(node -p "require('${FLOW_ROOT}/package.json').version")"
|
|
8
|
-
|
|
9
|
-
tmpdir="$(mktemp -d)"
|
|
10
|
-
trap 'rm -rf "${tmpdir}"' EXIT
|
|
11
|
-
|
|
12
|
-
platform_home="${tmpdir}/platform"
|
|
13
|
-
home_dir="${tmpdir}/home"
|
|
14
|
-
fake_bin="${tmpdir}/fake-bin"
|
|
15
|
-
mkdir -p "${platform_home}" "${home_dir}"
|
|
16
|
-
mkdir -p "${fake_bin}"
|
|
17
|
-
|
|
18
|
-
cat >"${fake_bin}/gh" <<'EOF'
|
|
19
|
-
#!/usr/bin/env bash
|
|
20
|
-
set -euo pipefail
|
|
21
|
-
|
|
22
|
-
if [[ "${1:-}" == "auth" && "${2:-}" == "status" ]]; then
|
|
23
|
-
echo "gh auth ok"
|
|
24
|
-
exit 0
|
|
25
|
-
fi
|
|
26
|
-
|
|
27
|
-
if [[ "${1:-}" == "auth" && "${2:-}" == "login" ]]; then
|
|
28
|
-
echo "gh auth login stub"
|
|
29
|
-
exit 0
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
echo "gh stub: unsupported invocation: $*" >&2
|
|
33
|
-
exit 0
|
|
34
|
-
EOF
|
|
35
|
-
|
|
36
|
-
cat >"${fake_bin}/jq" <<'EOF'
|
|
37
|
-
#!/usr/bin/env bash
|
|
38
|
-
exit 0
|
|
39
|
-
EOF
|
|
40
|
-
|
|
41
|
-
cat >"${fake_bin}/codex" <<'EOF'
|
|
42
|
-
#!/usr/bin/env bash
|
|
43
|
-
if [[ "${1:-}" == "--version" ]]; then
|
|
44
|
-
echo "codex stub 0.0.0"
|
|
45
|
-
exit 0
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
|
-
if [[ "${1:-}" == "login" && "${2:-}" == "status" ]]; then
|
|
49
|
-
echo "codex login ok"
|
|
50
|
-
exit 0
|
|
51
|
-
fi
|
|
52
|
-
|
|
53
|
-
echo "codex stub"
|
|
54
|
-
exit 0
|
|
55
|
-
EOF
|
|
56
|
-
|
|
57
|
-
chmod +x "${fake_bin}/gh" "${fake_bin}/jq" "${fake_bin}/codex"
|
|
58
|
-
|
|
59
|
-
help_output="$(
|
|
60
|
-
HOME="${home_dir}" \
|
|
61
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
62
|
-
node "${CLI_SCRIPT}" help
|
|
63
|
-
)"
|
|
64
|
-
|
|
65
|
-
grep -q '^Usage:$' <<<"${help_output}"
|
|
66
|
-
grep -q '^ setup' <<<"${help_output}"
|
|
67
|
-
grep -q '^ sync' <<<"${help_output}"
|
|
68
|
-
grep -q '^ profile-smoke' <<<"${help_output}"
|
|
69
|
-
grep -q '^ launchd-install' <<<"${help_output}"
|
|
70
|
-
grep -q '^ remove' <<<"${help_output}"
|
|
71
|
-
|
|
72
|
-
version_output="$(
|
|
73
|
-
HOME="${home_dir}" \
|
|
74
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
75
|
-
node "${CLI_SCRIPT}" version
|
|
76
|
-
)"
|
|
77
|
-
|
|
78
|
-
grep -q "^${PACKAGE_VERSION}$" <<<"${version_output}"
|
|
79
|
-
|
|
80
|
-
HOME="${home_dir}" \
|
|
81
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
82
|
-
node "${CLI_SCRIPT}" sync >/dev/null
|
|
83
|
-
|
|
84
|
-
test -f "${platform_home}/runtime-home/skills/openclaw/agent-control-plane/SKILL.md"
|
|
85
|
-
test -f "${platform_home}/runtime-home/tools/bin/flow-runtime-doctor.sh"
|
|
86
|
-
test -f "${platform_home}/runtime-home/skills/openclaw/agent-control-plane/tools/bin/codex-quota"
|
|
87
|
-
test -f "${platform_home}/runtime-home/skills/openclaw/agent-control-plane/tools/vendor/codex-quota-manager/scripts/auto-switch.sh"
|
|
88
|
-
|
|
89
|
-
doctor_output="$(
|
|
90
|
-
HOME="${home_dir}" \
|
|
91
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
92
|
-
node "${CLI_SCRIPT}" doctor
|
|
93
|
-
)"
|
|
94
|
-
|
|
95
|
-
grep -q '^CONTROL_PLANE_NAME=agent-control-plane$' <<<"${doctor_output}"
|
|
96
|
-
grep -q '^SOURCE_READY=yes$' <<<"${doctor_output}"
|
|
97
|
-
|
|
98
|
-
init_output="$(
|
|
99
|
-
HOME="${home_dir}" \
|
|
100
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
101
|
-
node "${CLI_SCRIPT}" init \
|
|
102
|
-
--profile-id alpha \
|
|
103
|
-
--repo-slug example-owner/alpha \
|
|
104
|
-
--allow-missing-repo \
|
|
105
|
-
--skip-anchor-sync \
|
|
106
|
-
--skip-workspace-sync
|
|
107
|
-
)"
|
|
108
|
-
|
|
109
|
-
grep -q '^PROJECT_INIT_STATUS=ok$' <<<"${init_output}"
|
|
110
|
-
grep -q '^PROFILE_ID=alpha$' <<<"${init_output}"
|
|
111
|
-
grep -q "^RUNTIME_HOME=${platform_home}/runtime-home$" <<<"${init_output}"
|
|
112
|
-
|
|
113
|
-
profile_smoke_output="$(
|
|
114
|
-
HOME="${home_dir}" \
|
|
115
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
116
|
-
node "${CLI_SCRIPT}" profile-smoke --profile-id alpha
|
|
117
|
-
)"
|
|
118
|
-
|
|
119
|
-
grep -q '^PROFILE_ID=alpha$' <<<"${profile_smoke_output}"
|
|
120
|
-
grep -q '^PROFILE_STATUS=ok$' <<<"${profile_smoke_output}"
|
|
121
|
-
|
|
122
|
-
runtime_status_output="$(
|
|
123
|
-
HOME="${home_dir}" \
|
|
124
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
125
|
-
node "${CLI_SCRIPT}" runtime status --profile-id alpha
|
|
126
|
-
)"
|
|
127
|
-
|
|
128
|
-
grep -q '^PROFILE_ID=alpha$' <<<"${runtime_status_output}"
|
|
129
|
-
grep -q "^CONFIG_YAML=${platform_home}/control-plane/profiles/alpha/control-plane.yaml$" <<<"${runtime_status_output}"
|
|
130
|
-
|
|
131
|
-
launchd_help="$(
|
|
132
|
-
HOME="${home_dir}" \
|
|
133
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
134
|
-
node "${CLI_SCRIPT}" launchd-install --help
|
|
135
|
-
)"
|
|
136
|
-
|
|
137
|
-
grep -q '^Usage:$' <<<"${launchd_help}"
|
|
138
|
-
|
|
139
|
-
remove_help="$(
|
|
140
|
-
HOME="${home_dir}" \
|
|
141
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
142
|
-
node "${CLI_SCRIPT}" remove --help
|
|
143
|
-
)"
|
|
144
|
-
|
|
145
|
-
grep -q '^Usage:$' <<<"${remove_help}"
|
|
146
|
-
|
|
147
|
-
setup_help="$(
|
|
148
|
-
HOME="${home_dir}" \
|
|
149
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
150
|
-
node "${CLI_SCRIPT}" setup --help
|
|
151
|
-
)"
|
|
152
|
-
|
|
153
|
-
grep -q -- '--install-missing-deps' <<<"${setup_help}"
|
|
154
|
-
grep -q -- '--no-install-missing-deps' <<<"${setup_help}"
|
|
155
|
-
grep -q -- '--install-missing-backend' <<<"${setup_help}"
|
|
156
|
-
grep -q -- '--no-install-missing-backend' <<<"${setup_help}"
|
|
157
|
-
grep -q -- '--gh-auth-login' <<<"${setup_help}"
|
|
158
|
-
grep -q -- '--no-gh-auth-login' <<<"${setup_help}"
|
|
159
|
-
grep -q -- '--dry-run' <<<"${setup_help}"
|
|
160
|
-
grep -q -- '--plan' <<<"${setup_help}"
|
|
161
|
-
grep -q -- '--json' <<<"${setup_help}"
|
|
162
|
-
|
|
163
|
-
setup_repo="${tmpdir}/setup-demo"
|
|
164
|
-
mkdir -p "${setup_repo}"
|
|
165
|
-
git -C "${setup_repo}" init -q -b main
|
|
166
|
-
git -C "${setup_repo}" config user.name "ACP Test"
|
|
167
|
-
git -C "${setup_repo}" config user.email "acp-test@example.com"
|
|
168
|
-
printf '# setup demo\n' >"${setup_repo}/README.md"
|
|
169
|
-
git -C "${setup_repo}" add README.md
|
|
170
|
-
git -C "${setup_repo}" commit -q -m "init"
|
|
171
|
-
git -C "${setup_repo}" remote add origin "https://github.com/example-owner/setup-demo.git"
|
|
172
|
-
|
|
173
|
-
setup_output="$(
|
|
174
|
-
HOME="${home_dir}" \
|
|
175
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
176
|
-
PATH="${fake_bin}:${PATH}" \
|
|
177
|
-
node "${CLI_SCRIPT}" setup \
|
|
178
|
-
--non-interactive \
|
|
179
|
-
--repo-root "${setup_repo}" \
|
|
180
|
-
--no-start-runtime \
|
|
181
|
-
--skip-anchor-sync \
|
|
182
|
-
--skip-workspace-sync
|
|
183
|
-
)"
|
|
184
|
-
|
|
185
|
-
grep -q '^SETUP_STATUS=ok$' <<<"${setup_output}"
|
|
186
|
-
grep -q '^PROFILE_ID=setup-demo$' <<<"${setup_output}"
|
|
187
|
-
grep -q '^REPO_SLUG=example-owner/setup-demo$' <<<"${setup_output}"
|
|
188
|
-
grep -q '^CODING_WORKER=' <<<"${setup_output}"
|
|
189
|
-
grep -q '^CORE_TOOLS_STATUS=ok$' <<<"${setup_output}"
|
|
190
|
-
grep -q '^WORKER_BACKEND_COMMAND=' <<<"${setup_output}"
|
|
191
|
-
grep -q '^WORKER_BACKEND_STATUS=ok$' <<<"${setup_output}"
|
|
192
|
-
grep -q '^WORKER_SETUP_GUIDE_STATUS=' <<<"${setup_output}"
|
|
193
|
-
grep -q '^WORKER_BACKEND_INSTALL_STATUS=' <<<"${setup_output}"
|
|
194
|
-
grep -q '^WORKER_SETUP_DOCS_OPENED=' <<<"${setup_output}"
|
|
195
|
-
grep -q '^WORKER_BACKEND_DOCS_URL=' <<<"${setup_output}"
|
|
196
|
-
grep -q '^WORKER_BACKEND_AUTH_EXAMPLE=' <<<"${setup_output}"
|
|
197
|
-
grep -q '^WORKER_BACKEND_VERIFY_EXAMPLE=' <<<"${setup_output}"
|
|
198
|
-
grep -q '^GITHUB_AUTH_STATUS=' <<<"${setup_output}"
|
|
199
|
-
grep -q '^FINAL_FIXUP_STATUS=' <<<"${setup_output}"
|
|
200
|
-
grep -q '^FINAL_FIXUP_ACTIONS=' <<<"${setup_output}"
|
|
201
|
-
grep -q '^DEPENDENCY_INSTALL_STATUS=' <<<"${setup_output}"
|
|
202
|
-
grep -q '^GITHUB_AUTH_STEP_STATUS=' <<<"${setup_output}"
|
|
203
|
-
grep -q '^PROJECT_INIT_STATUS=ok$' <<<"${setup_output}"
|
|
204
|
-
grep -q '^DOCTOR_STATUS=ok$' <<<"${setup_output}"
|
|
205
|
-
grep -q '^RUNTIME_START_STATUS=skipped$' <<<"${setup_output}"
|
|
206
|
-
grep -q '^RUNTIME_START_REASON=not-requested$' <<<"${setup_output}"
|
|
207
|
-
test -f "${platform_home}/control-plane/profiles/setup-demo/control-plane.yaml"
|
|
208
|
-
|
|
209
|
-
setup_dry_run_output="$(
|
|
210
|
-
HOME="${home_dir}" \
|
|
211
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
212
|
-
PATH="${fake_bin}:${PATH}" \
|
|
213
|
-
node "${CLI_SCRIPT}" setup \
|
|
214
|
-
--dry-run \
|
|
215
|
-
--non-interactive \
|
|
216
|
-
--repo-root "${setup_repo}" \
|
|
217
|
-
--no-start-runtime \
|
|
218
|
-
--skip-anchor-sync \
|
|
219
|
-
--skip-workspace-sync
|
|
220
|
-
)"
|
|
221
|
-
|
|
222
|
-
grep -q '^SETUP_STATUS=dry-run$' <<<"${setup_dry_run_output}"
|
|
223
|
-
grep -q '^SETUP_MODE=dry-run$' <<<"${setup_dry_run_output}"
|
|
224
|
-
grep -q '^PROJECT_INIT_STATUS=would-run$' <<<"${setup_dry_run_output}"
|
|
225
|
-
grep -q '^DOCTOR_STATUS=would-run$' <<<"${setup_dry_run_output}"
|
|
226
|
-
grep -q '^FINAL_FIXUP_STATUS=planned$' <<<"${setup_dry_run_output}"
|
|
227
|
-
grep -q '^FINAL_FIXUP_ACTIONS=review-plan$' <<<"${setup_dry_run_output}"
|
|
228
|
-
|
|
229
|
-
setup_json_output="$(
|
|
230
|
-
HOME="${home_dir}" \
|
|
231
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
232
|
-
PATH="${fake_bin}:${PATH}" \
|
|
233
|
-
node "${CLI_SCRIPT}" setup \
|
|
234
|
-
--json \
|
|
235
|
-
--repo-root "${setup_repo}" \
|
|
236
|
-
--profile-id setup-json \
|
|
237
|
-
--no-start-runtime \
|
|
238
|
-
--skip-anchor-sync \
|
|
239
|
-
--skip-workspace-sync
|
|
240
|
-
)"
|
|
241
|
-
|
|
242
|
-
printf '%s' "${setup_json_output}" | node -e '
|
|
243
|
-
const fs = require("fs");
|
|
244
|
-
const data = JSON.parse(fs.readFileSync(0, "utf8"));
|
|
245
|
-
if (data.setupStatus !== "ok") process.exit(1);
|
|
246
|
-
if (data.setupMode !== "run") process.exit(1);
|
|
247
|
-
if (data.profileId !== "setup-json") process.exit(1);
|
|
248
|
-
if (data.projectInitStatus !== "ok") process.exit(1);
|
|
249
|
-
if (data.doctorStatus !== "ok") process.exit(1);
|
|
250
|
-
if (!data.workerBackend || !data.githubAuth || !data.finalFixup) process.exit(1);
|
|
251
|
-
'
|
|
252
|
-
|
|
253
|
-
setup_dry_run_json_output="$(
|
|
254
|
-
HOME="${home_dir}" \
|
|
255
|
-
AGENT_PLATFORM_HOME="${platform_home}" \
|
|
256
|
-
PATH="${fake_bin}:${PATH}" \
|
|
257
|
-
node "${CLI_SCRIPT}" setup \
|
|
258
|
-
--json \
|
|
259
|
-
--dry-run \
|
|
260
|
-
--repo-root "${setup_repo}" \
|
|
261
|
-
--profile-id dry-run-json \
|
|
262
|
-
--no-start-runtime \
|
|
263
|
-
--skip-anchor-sync \
|
|
264
|
-
--skip-workspace-sync
|
|
265
|
-
)"
|
|
266
|
-
|
|
267
|
-
printf '%s' "${setup_dry_run_json_output}" | node -e '
|
|
268
|
-
const fs = require("fs");
|
|
269
|
-
const data = JSON.parse(fs.readFileSync(0, "utf8"));
|
|
270
|
-
if (data.setupStatus !== "dry-run") process.exit(1);
|
|
271
|
-
if (data.setupMode !== "dry-run") process.exit(1);
|
|
272
|
-
if (data.profileId !== "dry-run-json") process.exit(1);
|
|
273
|
-
if (data.projectInitStatus !== "would-run") process.exit(1);
|
|
274
|
-
if (data.doctorStatus !== "would-run") process.exit(1);
|
|
275
|
-
if (!data.finalFixup || data.finalFixup.status !== "planned") process.exit(1);
|
|
276
|
-
if (data.dependencyInstall && data.dependencyInstall.status === "not-needed" && data.dependencyInstall.command !== "") process.exit(1);
|
|
277
|
-
if (data.workerBackend && data.workerBackend.installStatus === "not-needed" && data.workerBackend.installCommand !== "") process.exit(1);
|
|
278
|
-
'
|
|
279
|
-
|
|
280
|
-
test ! -e "${platform_home}/control-plane/profiles/dry-run-json/control-plane.yaml"
|
|
@@ -1,56 +0,0 @@
|
|
|
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"
|