@fitlab-ai/agent-infra 0.9.3 → 0.9.5
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 +3 -1
- package/README.zh-CN.md +3 -1
- package/bin/cli.ts +12 -0
- package/dist/bin/cli.js +14 -0
- package/dist/bin/internal-cli.js +144 -123
- package/dist/lib/agent-clients/adapter.js +94 -4
- package/dist/lib/{sandbox/credentials.js → agent-clients/adapters/claude-code-credentials.js} +4 -14
- package/dist/lib/agent-clients/adapters/claude-code-refresh.js +85 -0
- package/dist/lib/agent-clients/adapters/claude-code-sandbox.js +247 -0
- package/dist/lib/agent-clients/adapters/claude-code.js +17 -3
- package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +382 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +163 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +211 -0
- package/dist/lib/agent-clients/adapters/codex.js +2 -2
- package/dist/lib/agent-clients/adapters/opencode-sandbox.js +108 -0
- package/dist/lib/agent-clients/adapters/opencode.js +15 -3
- package/dist/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
- package/dist/lib/agent-clients/registry.js +9 -1
- package/dist/lib/git/worktree-identity.js +64 -0
- package/dist/lib/internal/codex-lifecycle.js +202 -0
- package/dist/lib/internal/sandbox-control.js +24 -0
- package/dist/lib/internal/task-activity.js +45 -13
- package/dist/lib/internal/task-create.js +48 -0
- package/dist/lib/internal/task-ledger.js +12 -3
- package/dist/lib/internal/task-lifecycle.js +19 -1
- package/dist/lib/internal/task-orchestration.js +170 -27
- package/dist/lib/platform/github-client.js +19 -2
- package/dist/lib/platform/pr-checks.js +1 -1
- package/dist/lib/platform/pull-requests.js +47 -1
- package/dist/lib/platform/releases.js +13 -5
- package/dist/lib/process-data/index.js +239 -0
- package/dist/lib/process-data/normalize.js +198 -0
- package/dist/lib/process-data/privacy.js +33 -0
- package/dist/lib/process-data/reconcile.js +95 -0
- package/dist/lib/process-data/repair.js +58 -0
- package/dist/lib/process-data/sources.js +345 -0
- package/dist/lib/process-data/store.js +282 -0
- package/dist/lib/process-data/types.js +2 -0
- package/dist/lib/run/index.js +4 -3
- package/dist/lib/run/tui.js +7 -8
- package/dist/lib/sandbox/agent-client-reconciler.js +26 -2
- package/dist/lib/sandbox/capture.js +7 -2
- package/dist/lib/sandbox/commands/create.js +110 -228
- package/dist/lib/sandbox/commands/enter.js +15 -47
- package/dist/lib/sandbox/commands/list-running.js +16 -6
- package/dist/lib/sandbox/commands/ls.js +10 -6
- package/dist/lib/sandbox/commands/rebuild.js +4 -3
- package/dist/lib/sandbox/commands/refresh.js +4 -84
- package/dist/lib/sandbox/commands/rm.js +24 -3
- package/dist/lib/sandbox/commands/show.js +12 -3
- package/dist/lib/sandbox/commands/start.js +7 -4
- package/dist/lib/sandbox/config.js +2 -0
- package/dist/lib/sandbox/constants.js +6 -0
- package/dist/lib/sandbox/control/client.js +58 -0
- package/dist/lib/sandbox/control/protocol.js +54 -0
- package/dist/lib/sandbox/control/server.js +144 -0
- package/dist/lib/sandbox/dockerfile.js +36 -13
- package/dist/lib/sandbox/mounts.js +17 -4
- package/dist/lib/sandbox/recovery.js +128 -5
- package/dist/lib/sandbox/redaction.js +12 -0
- package/dist/lib/sandbox/runtimes/base.dockerfile +24 -74
- package/dist/lib/sandbox/workspace-identity.js +95 -0
- package/dist/lib/sandbox/workspace-view.js +109 -0
- package/dist/lib/task/activity-intent.js +257 -51
- package/dist/lib/task/activity-log.js +32 -5
- package/dist/lib/task/commit-finalization.js +278 -0
- package/dist/lib/task/commit-intent.js +165 -0
- package/dist/lib/task/create-service.js +137 -0
- package/dist/lib/task/create.js +333 -0
- package/dist/lib/task/decision-intents.js +31 -17
- package/dist/lib/task/delegation-receipts.js +2 -2
- package/dist/lib/task/implementation-inputs.js +54 -7
- package/dist/lib/task/ledger-intents.js +35 -1
- package/dist/lib/task/orchestration.js +505 -34
- package/dist/lib/task/resolve-ref.js +41 -1
- package/dist/lib/task/review-fingerprint.js +4 -0
- package/dist/lib/task/workspace-snapshot.js +78 -3
- package/lib/agent-clients/adapter.ts +130 -6
- package/lib/{sandbox/credentials.ts → agent-clients/adapters/claude-code-credentials.ts} +3 -18
- package/lib/agent-clients/adapters/claude-code-refresh.ts +128 -0
- package/lib/agent-clients/adapters/claude-code-sandbox.ts +295 -0
- package/lib/agent-clients/adapters/claude-code.ts +21 -3
- package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +442 -0
- package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +307 -0
- package/lib/agent-clients/adapters/codex-lifecycle/store.ts +250 -0
- package/lib/agent-clients/adapters/codex.ts +2 -2
- package/lib/agent-clients/adapters/opencode-sandbox.ts +136 -0
- package/lib/agent-clients/adapters/opencode.ts +18 -3
- package/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
- package/lib/agent-clients/registry.ts +9 -1
- package/lib/git/worktree-identity.ts +86 -0
- package/lib/internal/codex-lifecycle.ts +204 -0
- package/lib/internal/sandbox-control.ts +24 -0
- package/lib/internal/task-activity.ts +50 -14
- package/lib/internal/task-create.ts +49 -0
- package/lib/internal/task-ledger.ts +12 -3
- package/lib/internal/task-lifecycle.ts +22 -1
- package/lib/internal/task-orchestration.ts +117 -21
- package/lib/platform/github-client.ts +20 -2
- package/lib/platform/pr-checks.ts +1 -1
- package/lib/platform/pull-requests.ts +49 -1
- package/lib/platform/releases.ts +16 -4
- package/lib/process-data/index.ts +224 -0
- package/lib/process-data/normalize.ts +202 -0
- package/lib/process-data/privacy.ts +41 -0
- package/lib/process-data/reconcile.ts +110 -0
- package/lib/process-data/repair.ts +64 -0
- package/lib/process-data/sources.ts +354 -0
- package/lib/process-data/store.ts +315 -0
- package/lib/process-data/types.ts +135 -0
- package/lib/run/index.ts +5 -3
- package/lib/run/tui.ts +11 -8
- package/lib/sandbox/agent-client-reconciler.ts +44 -2
- package/lib/sandbox/capture.ts +9 -2
- package/lib/sandbox/commands/create.ts +127 -260
- package/lib/sandbox/commands/enter.ts +13 -59
- package/lib/sandbox/commands/list-running.ts +23 -6
- package/lib/sandbox/commands/ls.ts +22 -6
- package/lib/sandbox/commands/rebuild.ts +4 -3
- package/lib/sandbox/commands/refresh.ts +4 -126
- package/lib/sandbox/commands/rm.ts +24 -3
- package/lib/sandbox/commands/show.ts +29 -3
- package/lib/sandbox/commands/start.ts +6 -4
- package/lib/sandbox/config.ts +4 -0
- package/lib/sandbox/constants.ts +8 -0
- package/lib/sandbox/control/client.ts +79 -0
- package/lib/sandbox/control/protocol.ts +110 -0
- package/lib/sandbox/control/server.ts +155 -0
- package/lib/sandbox/dockerfile.ts +66 -13
- package/lib/sandbox/mounts.ts +24 -4
- package/lib/sandbox/recovery.ts +163 -6
- package/lib/sandbox/redaction.ts +14 -0
- package/lib/sandbox/runtimes/base.dockerfile +24 -74
- package/lib/sandbox/tool-types.ts +16 -0
- package/lib/sandbox/workspace-identity.ts +123 -0
- package/lib/sandbox/workspace-view.ts +150 -0
- package/lib/task/activity-intent.ts +350 -61
- package/lib/task/activity-log.ts +46 -7
- package/lib/task/commit-finalization.ts +376 -0
- package/lib/task/commit-intent.ts +230 -0
- package/lib/task/create-service.ts +171 -0
- package/lib/task/create.ts +372 -0
- package/lib/task/decision-intents.ts +32 -12
- package/lib/task/delegation-receipts.ts +2 -2
- package/lib/task/implementation-inputs.ts +62 -8
- package/lib/task/ledger-intents.ts +43 -3
- package/lib/task/orchestration.ts +673 -41
- package/lib/task/resolve-ref.ts +46 -1
- package/lib/task/review-fingerprint.ts +9 -0
- package/lib/task/workspace-snapshot.ts +98 -4
- package/package.json +7 -7
- package/templates/.agents/hooks/lifecycle-delegation.js +47 -3
- package/templates/.agents/rules/README.en.md +1 -1
- package/templates/.agents/rules/README.zh-CN.md +1 -1
- package/templates/.agents/rules/human-decision-context.en.md +11 -2
- package/templates/.agents/rules/human-decision-context.zh-CN.md +11 -2
- package/templates/.agents/rules/pr-checks-commands.en.md +1 -1
- package/templates/.agents/rules/pr-checks-commands.github.en.md +1 -1
- package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +2 -2
- package/templates/.agents/rules/pr-checks-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
- package/templates/.agents/rules/task-management.en.md +3 -0
- package/templates/.agents/rules/task-management.zh-CN.md +3 -0
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/SKILL.en.md +21 -17
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +28 -16
- package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +50 -0
- package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +56 -0
- package/templates/.agents/skills/commit/reference/task-status-update.en.md +4 -4
- package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +4 -4
- package/templates/.agents/skills/complete-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/SKILL.en.md +4 -4
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/create-task/SKILL.en.md +26 -43
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +26 -43
- package/templates/.agents/skills/create-task/reference/context-capture.en.md +34 -0
- package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +34 -0
- package/templates/.agents/skills/review-code/SKILL.en.md +2 -2
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-code/reference/output-templates.en.md +1 -1
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +1 -1
- package/templates/.agents/skills/review-pr/SKILL.en.md +36 -8
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +36 -8
- package/templates/.agents/skills/review-pr/reference/report-template.en.md +1 -1
- package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +1 -1
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +67 -50
- package/templates/.agents/skills/watch-pr/SKILL.en.md +4 -4
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +2 -2
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +2 -2
- package/templates/.agents/templates/task.en.md +1 -1
- package/templates/.agents/templates/task.zh-CN.md +1 -1
- package/templates/.claude/commands/watch-pr.en.md +1 -1
- package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
- package/templates/.claude/rules/tool-preferences.en.md +20 -0
- package/templates/.claude/rules/tool-preferences.zh-CN.md +20 -0
- package/templates/.codex/hooks.json +50 -0
- package/templates/.opencode/commands/watch-pr.en.md +1 -1
- package/templates/.opencode/commands/watch-pr.zh-CN.md +1 -1
- package/templates/.gemini/commands/_project_/review-pr.en.toml +0 -10
- package/templates/.gemini/commands/_project_/review-pr.zh-CN.toml +0 -10
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.js';
|
|
2
|
-
import { activateMatchingOrchestrationDelegation, activateOrchestrationDelegation, advanceOrchestration, beginOrResumeOrchestration,
|
|
2
|
+
import { abortCommitIntent, activateMatchingOrchestrationDelegation, activateOrchestrationDelegation, advanceOrchestration, beginCommitIntent, beginOrResumeOrchestration, checkpointCommitIntent, completeCommitIntent, pauseOrchestration, prepareOrchestrationDelegation, recoverCommitIntent, routeOrchestration, sealMatchingOrchestrationDelegation, sealOrchestrationDelegation, startCommitAttempt, statusCommitIntent, statusOrchestration, terminateCommitAttempt } from '../task/orchestration.js';
|
|
3
3
|
import { isAgentClientId } from '../agent-clients/types.js';
|
|
4
|
-
const USAGE = 'Usage: agent-infra-internal task-orchestration <task-ref|auto> <begin-or-resume|route|prepare|hook-start|
|
|
4
|
+
const USAGE = 'Usage: agent-infra-internal task-orchestration <task-ref|auto> <begin-or-resume|route|prepare|hook-start|hook-stop|advance|pause|status|commit-start|commit-begin|commit-checkpoint|commit-complete|commit-recover|commit-abort|commit-terminate|commit-status> [options]\n';
|
|
5
5
|
function usageFailure(message) {
|
|
6
6
|
process.stdout.write(`${JSON.stringify({
|
|
7
7
|
status: 'failed', changed: false,
|
|
@@ -20,21 +20,36 @@ function taskOrchestration(args = []) {
|
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
const [taskRef, intent] = args;
|
|
23
|
-
if (![
|
|
23
|
+
if (![
|
|
24
|
+
'begin-or-resume', 'route', 'prepare', 'hook-start', 'hook-stop', 'advance', 'pause', 'status',
|
|
25
|
+
'commit-start', 'commit-begin', 'commit-checkpoint', 'commit-complete', 'commit-recover', 'commit-abort', 'commit-terminate', 'commit-status'
|
|
26
|
+
].includes(intent)) {
|
|
24
27
|
usageFailure(`unknown intent '${intent}'`);
|
|
25
28
|
return;
|
|
26
29
|
}
|
|
27
30
|
const values = {};
|
|
28
31
|
const seen = new Set();
|
|
32
|
+
let orchestrated = false;
|
|
29
33
|
for (let index = 2; index < args.length; index += 1) {
|
|
30
34
|
const flag = args[index];
|
|
35
|
+
if (flag === '--orchestrated') {
|
|
36
|
+
if (seen.has(flag)) {
|
|
37
|
+
usageFailure(`duplicate option '${flag}'`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
seen.add(flag);
|
|
41
|
+
orchestrated = true;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
31
44
|
if (![
|
|
32
45
|
'--max-steps', '--executor-model', '--executor-reasoning-effort',
|
|
33
46
|
'--reviewer-model', '--reviewer-reasoning-effort',
|
|
34
47
|
'--client', '--requested-model', '--requested-reasoning-effort', '--parent-id', '--before-fingerprint',
|
|
35
48
|
'--native-agent', '--child-id', '--spawn-mode', '--actual-model', '--actual-reasoning-effort',
|
|
36
49
|
'--model-fallback-reason', '--reasoning-effort-fallback-reason',
|
|
37
|
-
'--exit-code', '--after-fingerprint', '--changed-paths', '--code', '--message', '--recoverable', '--agent'
|
|
50
|
+
'--exit-code', '--after-fingerprint', '--changed-paths', '--code', '--message', '--recoverable', '--agent',
|
|
51
|
+
'--baseline-head', '--token', '--kind', '--head', '--remote', '--ref', '--expected-head',
|
|
52
|
+
'--attempt', '--git-worktree-root'
|
|
38
53
|
].includes(flag)) {
|
|
39
54
|
usageFailure(`unknown option '${flag}'`);
|
|
40
55
|
return;
|
|
@@ -51,13 +66,153 @@ function taskOrchestration(args = []) {
|
|
|
51
66
|
}
|
|
52
67
|
values[flag] = value;
|
|
53
68
|
}
|
|
69
|
+
const commitIntentFlags = {
|
|
70
|
+
'commit-start': ['--agent', '--git-worktree-root'],
|
|
71
|
+
'commit-begin': ['--agent', '--baseline-head', '--attempt', '--orchestrated', '--git-worktree-root'],
|
|
72
|
+
'commit-checkpoint': ['--token', '--kind', '--head', '--remote', '--ref', '--git-worktree-root'],
|
|
73
|
+
'commit-complete': ['--token', '--agent', '--git-worktree-root'],
|
|
74
|
+
'commit-recover': ['--agent', '--git-worktree-root'],
|
|
75
|
+
'commit-abort': ['--token', '--expected-head', '--git-worktree-root'],
|
|
76
|
+
'commit-terminate': ['--attempt', '--agent', '--code', '--git-worktree-root'],
|
|
77
|
+
'commit-status': ['--git-worktree-root']
|
|
78
|
+
};
|
|
79
|
+
if (intent in commitIntentFlags) {
|
|
80
|
+
const allowed = commitIntentFlags[intent];
|
|
81
|
+
const invalid = [...seen].find((flag) => !allowed.includes(flag));
|
|
82
|
+
if (invalid) {
|
|
83
|
+
usageFailure(`intent '${intent}' does not accept '${invalid}'`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const commitOnly = [...seen].find((flag) => [
|
|
89
|
+
'--orchestrated', '--baseline-head', '--attempt', '--token', '--kind', '--head', '--remote', '--ref', '--expected-head'
|
|
90
|
+
].includes(flag));
|
|
91
|
+
if (commitOnly) {
|
|
92
|
+
usageFailure(`intent '${intent}' does not accept '${commitOnly}'`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
54
96
|
const requireValues = (flags) => flags.find((flag) => values[flag] === undefined);
|
|
97
|
+
const coreOptions = values['--git-worktree-root'] === undefined
|
|
98
|
+
? {}
|
|
99
|
+
: { gitWorktreeRoot: values['--git-worktree-root'] };
|
|
55
100
|
if (values['--client'] !== undefined && !isAgentClientId(values['--client'])) {
|
|
56
101
|
usageFailure(`unknown client '${values['--client']}'`);
|
|
57
102
|
return;
|
|
58
103
|
}
|
|
59
104
|
let result;
|
|
60
|
-
if (intent === '
|
|
105
|
+
if (intent === 'commit-start') {
|
|
106
|
+
const missing = requireValues(['--agent']);
|
|
107
|
+
if (missing) {
|
|
108
|
+
usageFailure(`intent 'commit-start' requires '${missing}'`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const agent = normalizeAgentToken(values['--agent']);
|
|
112
|
+
if (!agent) {
|
|
113
|
+
usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
result = startCommitAttempt(taskRef, { agent }, coreOptions);
|
|
117
|
+
}
|
|
118
|
+
else if (intent === 'commit-begin') {
|
|
119
|
+
const missing = requireValues(['--agent', '--baseline-head', '--attempt']);
|
|
120
|
+
if (missing) {
|
|
121
|
+
usageFailure(`intent 'commit-begin' requires '${missing}'`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const agent = normalizeAgentToken(values['--agent']);
|
|
125
|
+
if (!agent) {
|
|
126
|
+
usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
result = beginCommitIntent(taskRef, {
|
|
130
|
+
agent, orchestrated, baselineHead: values['--baseline-head'], attempt: values['--attempt']
|
|
131
|
+
}, coreOptions);
|
|
132
|
+
}
|
|
133
|
+
else if (intent === 'commit-checkpoint') {
|
|
134
|
+
const missing = requireValues(['--token', '--kind', '--head']);
|
|
135
|
+
if (missing) {
|
|
136
|
+
usageFailure(`intent 'commit-checkpoint' requires '${missing}'`);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (!['committed', 'pushed'].includes(values['--kind'])) {
|
|
140
|
+
usageFailure('--kind must be committed or pushed');
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (values['--kind'] === 'pushed') {
|
|
144
|
+
const pushedMissing = requireValues(['--remote', '--ref']);
|
|
145
|
+
if (pushedMissing) {
|
|
146
|
+
usageFailure(`pushed checkpoint requires '${pushedMissing}'`);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else if (values['--remote'] !== undefined || values['--ref'] !== undefined) {
|
|
151
|
+
usageFailure('committed checkpoint does not accept --remote or --ref');
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
result = checkpointCommitIntent(taskRef, {
|
|
155
|
+
token: values['--token'], kind: values['--kind'],
|
|
156
|
+
head: values['--head'], remote: values['--remote'], ref: values['--ref']
|
|
157
|
+
}, coreOptions);
|
|
158
|
+
}
|
|
159
|
+
else if (intent === 'commit-complete') {
|
|
160
|
+
const missing = requireValues(['--token', '--agent']);
|
|
161
|
+
if (missing) {
|
|
162
|
+
usageFailure(`intent 'commit-complete' requires '${missing}'`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const agent = normalizeAgentToken(values['--agent']);
|
|
166
|
+
if (!agent) {
|
|
167
|
+
usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
result = completeCommitIntent(taskRef, { token: values['--token'], agent }, coreOptions);
|
|
171
|
+
}
|
|
172
|
+
else if (intent === 'commit-recover') {
|
|
173
|
+
const missing = requireValues(['--agent']);
|
|
174
|
+
if (missing) {
|
|
175
|
+
usageFailure(`intent 'commit-recover' requires '${missing}'`);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const agent = normalizeAgentToken(values['--agent']);
|
|
179
|
+
if (!agent) {
|
|
180
|
+
usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
result = recoverCommitIntent(taskRef, { agent }, coreOptions);
|
|
184
|
+
}
|
|
185
|
+
else if (intent === 'commit-abort') {
|
|
186
|
+
const missing = requireValues(['--token', '--expected-head']);
|
|
187
|
+
if (missing) {
|
|
188
|
+
usageFailure(`intent 'commit-abort' requires '${missing}'`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
result = abortCommitIntent(taskRef, { token: values['--token'], expectedHead: values['--expected-head'] }, coreOptions);
|
|
192
|
+
}
|
|
193
|
+
else if (intent === 'commit-terminate') {
|
|
194
|
+
const missing = requireValues(['--attempt', '--agent', '--code']);
|
|
195
|
+
if (missing) {
|
|
196
|
+
usageFailure(`intent 'commit-terminate' requires '${missing}'`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const agent = normalizeAgentToken(values['--agent']);
|
|
200
|
+
if (!agent) {
|
|
201
|
+
usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (!/^[A-Z][A-Z0-9_]{2,63}$/.test(values['--code'])) {
|
|
205
|
+
usageFailure('--code must be a stable uppercase identifier');
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
result = terminateCommitAttempt(taskRef, {
|
|
209
|
+
attempt: values['--attempt'], agent, code: values['--code']
|
|
210
|
+
}, coreOptions);
|
|
211
|
+
}
|
|
212
|
+
else if (intent === 'commit-status') {
|
|
213
|
+
result = statusCommitIntent(taskRef, coreOptions);
|
|
214
|
+
}
|
|
215
|
+
else if (intent === 'begin-or-resume') {
|
|
61
216
|
const missing = requireValues(['--client']);
|
|
62
217
|
if (missing) {
|
|
63
218
|
usageFailure(`intent 'begin-or-resume' requires '${missing}'`);
|
|
@@ -78,6 +233,7 @@ function taskOrchestration(args = []) {
|
|
|
78
233
|
return;
|
|
79
234
|
}
|
|
80
235
|
result = beginOrResumeOrchestration(taskRef, {
|
|
236
|
+
...coreOptions,
|
|
81
237
|
maxSteps,
|
|
82
238
|
client: values['--client'],
|
|
83
239
|
modelPolicy: hasAnyPolicy ? {
|
|
@@ -93,10 +249,10 @@ function taskOrchestration(args = []) {
|
|
|
93
249
|
});
|
|
94
250
|
}
|
|
95
251
|
else if (intent === 'route') {
|
|
96
|
-
result = routeOrchestration(taskRef);
|
|
252
|
+
result = routeOrchestration(taskRef, coreOptions);
|
|
97
253
|
}
|
|
98
254
|
else if (intent === 'status') {
|
|
99
|
-
result = statusOrchestration(taskRef);
|
|
255
|
+
result = statusOrchestration(taskRef, coreOptions);
|
|
100
256
|
}
|
|
101
257
|
else if (intent === 'prepare') {
|
|
102
258
|
const missing = requireValues(['--client']);
|
|
@@ -108,7 +264,7 @@ function taskOrchestration(args = []) {
|
|
|
108
264
|
client: values['--client'],
|
|
109
265
|
requestedModel: values['--requested-model'],
|
|
110
266
|
requestedReasoningEffort: values['--requested-reasoning-effort']
|
|
111
|
-
});
|
|
267
|
+
}, coreOptions);
|
|
112
268
|
}
|
|
113
269
|
else if (intent === 'hook-start') {
|
|
114
270
|
const missing = requireValues([
|
|
@@ -128,8 +284,8 @@ function taskOrchestration(args = []) {
|
|
|
128
284
|
reasoningEffortFallbackReason: values['--reasoning-effort-fallback-reason']
|
|
129
285
|
};
|
|
130
286
|
result = taskRef === 'auto'
|
|
131
|
-
? activateMatchingOrchestrationDelegation(values['--client'], event)
|
|
132
|
-
: activateOrchestrationDelegation(taskRef, event);
|
|
287
|
+
? activateMatchingOrchestrationDelegation(values['--client'], event, coreOptions)
|
|
288
|
+
: activateOrchestrationDelegation(taskRef, event, coreOptions);
|
|
133
289
|
}
|
|
134
290
|
else if (intent === 'hook-stop') {
|
|
135
291
|
if (taskRef === 'auto') {
|
|
@@ -140,7 +296,7 @@ function taskOrchestration(args = []) {
|
|
|
140
296
|
}
|
|
141
297
|
result = sealMatchingOrchestrationDelegation(values['--client'], {
|
|
142
298
|
nativeAgent: values['--native-agent'], childId: values['--child-id']
|
|
143
|
-
});
|
|
299
|
+
}, coreOptions);
|
|
144
300
|
}
|
|
145
301
|
else {
|
|
146
302
|
const missing = requireValues(['--child-id', '--exit-code', '--after-fingerprint']);
|
|
@@ -157,24 +313,11 @@ function taskOrchestration(args = []) {
|
|
|
157
313
|
childId: values['--child-id'], exitCode,
|
|
158
314
|
afterFingerprint: values['--after-fingerprint'],
|
|
159
315
|
changedPaths: values['--changed-paths'] ? values['--changed-paths'].split(',').filter(Boolean) : []
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
else if (intent === 'stage-completed') {
|
|
164
|
-
const missing = requireValues(['--agent']);
|
|
165
|
-
if (missing) {
|
|
166
|
-
usageFailure(`intent 'stage-completed' requires '${missing}'`);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
const agent = normalizeAgentToken(values['--agent']);
|
|
170
|
-
if (!agent) {
|
|
171
|
-
usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
|
|
172
|
-
return;
|
|
316
|
+
}, coreOptions);
|
|
173
317
|
}
|
|
174
|
-
result = completeCommitOrchestrationStage(taskRef, agent);
|
|
175
318
|
}
|
|
176
319
|
else if (intent === 'advance') {
|
|
177
|
-
result = advanceOrchestration(taskRef);
|
|
320
|
+
result = advanceOrchestration(taskRef, coreOptions);
|
|
178
321
|
}
|
|
179
322
|
else {
|
|
180
323
|
const missing = requireValues(['--code', '--message', '--recoverable']);
|
|
@@ -186,7 +329,7 @@ function taskOrchestration(args = []) {
|
|
|
186
329
|
usageFailure('--recoverable must be true or false');
|
|
187
330
|
return;
|
|
188
331
|
}
|
|
189
|
-
result = pauseOrchestration(taskRef, values['--code'], values['--message'], values['--recoverable'] === 'true');
|
|
332
|
+
result = pauseOrchestration(taskRef, values['--code'], values['--message'], values['--recoverable'] === 'true', coreOptions);
|
|
190
333
|
}
|
|
191
334
|
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
192
335
|
if (result.status === 'failed')
|
|
@@ -2,6 +2,14 @@ import process from 'node:process';
|
|
|
2
2
|
import spawn from 'cross-spawn';
|
|
3
3
|
import semver from 'semver';
|
|
4
4
|
const MINIMUM_GITHUB_CLI_VERSION = '2.16.0';
|
|
5
|
+
const GITHUB_CLI_MAX_BUFFER = 64 * 1024 * 1024;
|
|
6
|
+
const ERROR_DETAIL_LIMIT = 4096;
|
|
7
|
+
function boundedFailureDetail(result) {
|
|
8
|
+
const diagnostic = `${result.stderr}\n${result.error?.message || ''}`.trim() || result.stdout.trim();
|
|
9
|
+
return diagnostic.length <= ERROR_DETAIL_LIMIT
|
|
10
|
+
? diagnostic
|
|
11
|
+
: `${diagnostic.slice(0, ERROR_DETAIL_LIMIT)}… [truncated]`;
|
|
12
|
+
}
|
|
5
13
|
function defaultRunner(args, options) {
|
|
6
14
|
const command = process.env.AGENT_INFRA_GH_BIN || 'gh';
|
|
7
15
|
let prefix = [];
|
|
@@ -16,6 +24,7 @@ function defaultRunner(args, options) {
|
|
|
16
24
|
encoding: 'utf8',
|
|
17
25
|
env: process.env,
|
|
18
26
|
input: options.input,
|
|
27
|
+
maxBuffer: GITHUB_CLI_MAX_BUFFER,
|
|
19
28
|
shell: false
|
|
20
29
|
});
|
|
21
30
|
return {
|
|
@@ -37,7 +46,15 @@ function defaultSleep(delayMs) {
|
|
|
37
46
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, delayMs);
|
|
38
47
|
}
|
|
39
48
|
function classifyGitHubFailure(result) {
|
|
40
|
-
const
|
|
49
|
+
const errorCode = result.error && 'code' in result.error ? result.error.code : undefined;
|
|
50
|
+
if (errorCode === 'ENOBUFS') {
|
|
51
|
+
return {
|
|
52
|
+
code: 'PLATFORM_OUTPUT_TOO_LARGE',
|
|
53
|
+
message: 'GitHub CLI output exceeded the configured limit',
|
|
54
|
+
retryable: false
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const detail = boundedFailureDetail(result);
|
|
41
58
|
const lower = detail.toLowerCase();
|
|
42
59
|
if (/\b401\b|bad credentials|authentication required|not logged into/.test(lower)) {
|
|
43
60
|
return { code: 'AUTH_REQUIRED', message: detail || 'GitHub authentication is required', retryable: false };
|
|
@@ -54,7 +71,7 @@ function classifyGitHubFailure(result) {
|
|
|
54
71
|
if (/\b422\b|validation failed/.test(lower)) {
|
|
55
72
|
return { code: 'PLATFORM_REQUEST_INVALID', message: detail || 'GitHub rejected the request', retryable: false };
|
|
56
73
|
}
|
|
57
|
-
if (
|
|
74
|
+
if (errorCode === 'ENOENT') {
|
|
58
75
|
return { code: 'PLATFORM_DEPENDENCY_MISSING', message: detail || 'GitHub CLI is unavailable', retryable: false };
|
|
59
76
|
}
|
|
60
77
|
return { code: 'PLATFORM_REQUEST_FAILED', message: detail || 'GitHub request failed', retryable: false };
|
|
@@ -85,7 +85,7 @@ registerPlatformCapabilities('github', {
|
|
|
85
85
|
inspectRequiredChecks({ client, repository, number, cwd }) {
|
|
86
86
|
const github = client || createGitHubClient();
|
|
87
87
|
const inspected = github.json([
|
|
88
|
-
'pr', 'checks', String(number), '--repo', repository,
|
|
88
|
+
'pr', 'checks', String(number), '--repo', repository,
|
|
89
89
|
'--json', 'name,state,bucket,link,workflow,startedAt,completedAt'
|
|
90
90
|
], { cwd });
|
|
91
91
|
return inspected.ok
|
|
@@ -11,6 +11,8 @@ import { inspectPlatformIssue } from './issues.js';
|
|
|
11
11
|
import { planPullRequestMetadata } from './pull-request-metadata.js';
|
|
12
12
|
import { platformResult } from './types.js';
|
|
13
13
|
import { inspectCompletionArtifacts } from '../task/finalization-artifacts.js';
|
|
14
|
+
import { inspectCreatePrCommitGate } from '../task/commit-finalization.js';
|
|
15
|
+
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
|
|
14
16
|
function result(status, taskId, issueNumber, prNumber, overrides = {}) {
|
|
15
17
|
return {
|
|
16
18
|
...platformResult(status),
|
|
@@ -612,7 +614,7 @@ function resolveExternalPullRequest(taskRef, options) {
|
|
|
612
614
|
error: null
|
|
613
615
|
}), { mode: 'external', authorization: selected.source, candidates: selected.candidates, eligible: selected.eligible, selected: selected.selected });
|
|
614
616
|
}
|
|
615
|
-
function
|
|
617
|
+
function createPlatformPullRequestUnlocked(taskRef, options) {
|
|
616
618
|
const base = resolvedContext(taskRef, options);
|
|
617
619
|
if (!base.ok)
|
|
618
620
|
return base.output;
|
|
@@ -622,6 +624,17 @@ function createPlatformPullRequest(taskRef, options) {
|
|
|
622
624
|
});
|
|
623
625
|
if (base.prNumber)
|
|
624
626
|
return inspectPlatformPullRequest(taskRef, options);
|
|
627
|
+
const gate = inspectCreatePrCommitGate(base.resolved.taskDir, base.resolved.repoRoot, base.resolved.taskId);
|
|
628
|
+
if (!gate.allowed)
|
|
629
|
+
return result('blocked', base.resolved.taskId, base.issueNumber, null, {
|
|
630
|
+
platform: base.context.platform,
|
|
631
|
+
capabilities: base.context.capabilities,
|
|
632
|
+
error: {
|
|
633
|
+
code: gate.code,
|
|
634
|
+
message: `${gate.message}; action=${gate.action}`,
|
|
635
|
+
retryable: gate.action === 'rerun-commit' || gate.action === 'rerun-review-code'
|
|
636
|
+
}
|
|
637
|
+
});
|
|
625
638
|
const located = locatePullRequest(base, options.head, options.base);
|
|
626
639
|
if (!located.ok && located.error.code === 'PR_IDENTITY_AMBIGUOUS')
|
|
627
640
|
return result('failed', base.resolved.taskId, base.issueNumber, null, {
|
|
@@ -689,6 +702,39 @@ function createPlatformPullRequest(taskRef, options) {
|
|
|
689
702
|
operations: [{ name: created ? 'pr:create' : 'pr:reuse', status: created ? 'applied' : 'no-op', reasonCode: null }, { name: 'task:bind-pr', status: 'applied', reasonCode: null }], error: null
|
|
690
703
|
});
|
|
691
704
|
}
|
|
705
|
+
function createPlatformPullRequest(taskRef, options) {
|
|
706
|
+
const base = resolvedContext(taskRef, options);
|
|
707
|
+
if (!base.ok)
|
|
708
|
+
return base.output;
|
|
709
|
+
if (!options.base || !options.head || !options.title.trim() || !options.body.trim()) {
|
|
710
|
+
return result('failed', base.resolved.taskId, base.issueNumber, base.prNumber, {
|
|
711
|
+
error: { code: 'PR_PAYLOAD_INVALID', message: 'base, head, title and body are required', retryable: false }
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
if (base.prNumber)
|
|
715
|
+
return inspectPlatformPullRequest(taskRef, options);
|
|
716
|
+
try {
|
|
717
|
+
return withTaskExecutionLock(base.resolved.repoRoot, base.resolved.taskId, 'platform-pr.create', () => createPlatformPullRequestUnlocked(taskRef, options));
|
|
718
|
+
}
|
|
719
|
+
catch (error) {
|
|
720
|
+
if (error instanceof TaskExecutionLockError) {
|
|
721
|
+
return result('blocked', base.resolved.taskId, base.issueNumber, null, {
|
|
722
|
+
platform: base.context.platform,
|
|
723
|
+
capabilities: base.context.capabilities,
|
|
724
|
+
error: { code: error.code, message: error.message, retryable: true }
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
return result('failed', base.resolved.taskId, base.issueNumber, null, {
|
|
728
|
+
platform: base.context.platform,
|
|
729
|
+
capabilities: base.context.capabilities,
|
|
730
|
+
error: {
|
|
731
|
+
code: 'PR_CREATE_FAILED',
|
|
732
|
+
message: error instanceof Error ? error.message : String(error),
|
|
733
|
+
retryable: false
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
}
|
|
692
738
|
function syncPlatformPullRequest(taskRef, options) {
|
|
693
739
|
const base = resolvedContext(taskRef, options);
|
|
694
740
|
if (!base.ok)
|
|
@@ -55,9 +55,17 @@ function reconcileReleaseMilestones(version, options = {}) {
|
|
|
55
55
|
const major = Number(match[1]);
|
|
56
56
|
const minor = Number(match[2]);
|
|
57
57
|
const patch = Number(match[3]);
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const nextPatch = `${major}.${minor}.${patch + 1}`;
|
|
59
|
+
const currentLine = `${major}.${minor}.x`;
|
|
60
|
+
const ensure = [
|
|
61
|
+
{ title: nextPatch, description: `Issues that we want to release in v${nextPatch}.` },
|
|
62
|
+
{ title: currentLine, description: `Issues that we want to resolve in ${major}.${minor} line.` }
|
|
63
|
+
];
|
|
64
|
+
if (patch === 0) {
|
|
65
|
+
const nextMinor = `${major}.${minor + 1}.0`;
|
|
66
|
+
const nextLine = `${major}.${minor + 1}.x`;
|
|
67
|
+
ensure.push({ title: nextMinor, description: `Issues that we want to release in v${nextMinor}.` }, { title: nextLine, description: `Issues that we want to resolve in ${major}.${minor + 1} line.` });
|
|
68
|
+
}
|
|
61
69
|
const operations = [];
|
|
62
70
|
const current = milestones.find((item) => item.title === version);
|
|
63
71
|
if (current && current.state !== 'closed') {
|
|
@@ -66,11 +74,11 @@ function reconcileReleaseMilestones(version, options = {}) {
|
|
|
66
74
|
}
|
|
67
75
|
else
|
|
68
76
|
operations.push({ name: 'close-milestone', title: version, status: 'no-op' });
|
|
69
|
-
for (const title of ensure) {
|
|
77
|
+
for (const { title, description } of ensure) {
|
|
70
78
|
if (milestones.some((item) => item.title === title))
|
|
71
79
|
operations.push({ name: 'ensure-milestone', title, status: 'no-op' });
|
|
72
80
|
else {
|
|
73
|
-
const created = client.json(['api', '--method', 'POST', `repos/${context.platform.repository}/milestones`, '-f', `title=${title}`], { cwd: options.cwd });
|
|
81
|
+
const created = client.json(['api', '--method', 'POST', `repos/${context.platform.repository}/milestones`, '-f', `title=${title}`, '-f', `description=${description}`], { cwd: options.cwd });
|
|
74
82
|
operations.push({ name: 'ensure-milestone', title, status: created.ok ? 'applied' : 'failed' });
|
|
75
83
|
}
|
|
76
84
|
}
|