@fitlab-ai/agent-infra 0.11.15 → 0.12.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.
- package/bin/cli.ts +1 -1
- package/dist/bin/cli.js +1 -1
- package/dist/bin/internal-cli.js +6 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +6 -6
- package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +8 -18
- package/dist/lib/agent-clients/adapters/codex-orchestration.js +1 -1
- package/dist/lib/decide.js +2 -7
- package/dist/lib/internal/cli-route-inventory.js +3 -0
- package/dist/lib/internal/manual-validation.js +8 -16
- package/dist/lib/internal/platform-comment.js +3 -2
- package/dist/lib/internal/task-activity.js +1 -12
- package/dist/lib/internal/task-event.js +1 -12
- package/dist/lib/internal/task-ledger.js +1 -12
- package/dist/lib/internal/task-operation-registry.js +2 -1
- package/dist/lib/internal/task-qualification.js +6 -15
- package/dist/lib/internal/task-review.js +3 -16
- package/dist/lib/internal/task-short-id.js +2 -1
- package/dist/lib/internal/task-verify.js +1 -11
- package/dist/lib/internal/task-warning.js +1 -12
- package/dist/lib/internal/task-workspace.js +43 -0
- package/dist/lib/merge.js +4 -3
- package/dist/lib/platform/pr-summary.js +6 -15
- package/dist/lib/platform/pull-requests.js +3 -15
- package/dist/lib/pr-review/evidence-grading.js +3 -2
- package/dist/lib/process-data/index.js +5 -4
- package/dist/lib/process-data/sources.js +6 -0
- package/dist/lib/run/index.js +3 -2
- package/dist/lib/sandbox/commands/create.js +5 -1
- package/dist/lib/sandbox/commands/enter.js +1 -1
- package/dist/lib/sandbox/commands/list-running.js +2 -1
- package/dist/lib/sandbox/control/client.js +8 -13
- package/dist/lib/sandbox/control/completed-reentry.js +2 -1
- package/dist/lib/sandbox/control/task-view.js +4 -2
- package/dist/lib/sandbox/mounts.js +4 -4
- package/dist/lib/sandbox/recovery.js +26 -16
- package/dist/lib/sandbox/removal.js +3 -10
- package/dist/lib/sandbox/task-resolver.js +9 -6
- package/dist/lib/sandbox/workspace-identity.js +6 -5
- package/dist/lib/sandbox/workspace-view.js +29 -22
- package/dist/lib/task/activity-intent.js +2 -12
- package/dist/lib/task/artifact-lifecycle.js +17 -11
- package/dist/lib/task/artifact-operations.js +41 -49
- package/dist/lib/task/capabilities.js +2 -2
- package/dist/lib/task/commands/ls.js +4 -3
- package/dist/lib/task/commands/status.js +1 -1
- package/dist/lib/task/commit-operation.js +6 -6
- package/dist/lib/task/control-authority.js +32 -32
- package/dist/lib/task/create-service.js +2 -4
- package/dist/lib/task/create.js +12 -65
- package/dist/lib/task/delegation-receipts.js +1 -1
- package/dist/lib/task/delivery.js +2 -8
- package/dist/lib/task/events.js +5 -31
- package/dist/lib/task/finalization.js +17 -22
- package/dist/lib/task/lifecycle.js +9 -48
- package/dist/lib/task/local-artifact-finalization.js +1 -2
- package/dist/lib/task/orchestration.js +24 -57
- package/dist/lib/task/platform-operation-recovery.js +1 -2
- package/dist/lib/task/resolve-ref.js +17 -12
- package/dist/lib/task/review-finalization.js +2 -35
- package/dist/lib/task/review-identity.js +3 -1
- package/dist/lib/task/short-id.js +10 -8
- package/dist/lib/task/verification-engine.js +19 -58
- package/dist/lib/task/workspace-root.js +59 -0
- package/dist/lib/task/workspace-snapshot.js +4 -3
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +6 -6
- package/lib/agent-clients/adapters/codex-lifecycle/store.ts +8 -34
- package/lib/agent-clients/adapters/codex-orchestration.ts +1 -1
- package/lib/decide.ts +2 -7
- package/lib/internal/cli-route-inventory.ts +2 -0
- package/lib/internal/manual-validation.ts +8 -19
- package/lib/internal/platform-comment.ts +3 -2
- package/lib/internal/task-activity.ts +1 -10
- package/lib/internal/task-event.ts +1 -10
- package/lib/internal/task-ledger.ts +1 -10
- package/lib/internal/task-operation-registry.ts +2 -1
- package/lib/internal/task-qualification.ts +5 -11
- package/lib/internal/task-review.ts +3 -14
- package/lib/internal/task-short-id.ts +2 -1
- package/lib/internal/task-verify.ts +1 -9
- package/lib/internal/task-warning.ts +1 -10
- package/lib/internal/task-workspace.ts +39 -0
- package/lib/merge.ts +4 -3
- package/lib/platform/pr-summary.ts +7 -16
- package/lib/platform/pull-requests.ts +3 -24
- package/lib/pr-review/evidence-grading.ts +3 -2
- package/lib/process-data/index.ts +4 -3
- package/lib/process-data/sources.ts +6 -0
- package/lib/run/index.ts +3 -2
- package/lib/sandbox/commands/create.ts +5 -1
- package/lib/sandbox/commands/enter.ts +1 -1
- package/lib/sandbox/commands/list-running.ts +2 -1
- package/lib/sandbox/control/client.ts +7 -12
- package/lib/sandbox/control/completed-reentry.ts +2 -1
- package/lib/sandbox/control/task-view.ts +4 -2
- package/lib/sandbox/mounts.ts +4 -4
- package/lib/sandbox/recovery.ts +26 -18
- package/lib/sandbox/removal.ts +3 -26
- package/lib/sandbox/task-resolver.ts +9 -6
- package/lib/sandbox/workspace-identity.ts +6 -5
- package/lib/sandbox/workspace-view.ts +28 -20
- package/lib/task/activity-intent.ts +3 -17
- package/lib/task/artifact-lifecycle.ts +39 -11
- package/lib/task/artifact-operations.ts +28 -35
- package/lib/task/capabilities.ts +2 -2
- package/lib/task/commands/ls.ts +4 -3
- package/lib/task/commands/status.ts +1 -1
- package/lib/task/commit-operation.ts +5 -6
- package/lib/task/control-authority.ts +29 -35
- package/lib/task/create-service.ts +2 -4
- package/lib/task/create.ts +10 -51
- package/lib/task/delegation-receipts.ts +1 -1
- package/lib/task/delivery.ts +2 -10
- package/lib/task/events.ts +5 -32
- package/lib/task/finalization.ts +16 -24
- package/lib/task/lifecycle.ts +9 -50
- package/lib/task/local-artifact-finalization.ts +1 -4
- package/lib/task/orchestration.ts +31 -80
- package/lib/task/platform-operation-recovery.ts +1 -2
- package/lib/task/resolve-ref.ts +18 -12
- package/lib/task/review-finalization.ts +2 -52
- package/lib/task/review-identity.ts +3 -1
- package/lib/task/short-id.ts +10 -8
- package/lib/task/verification-engine.ts +20 -62
- package/lib/task/workspace-root.ts +78 -0
- package/lib/task/workspace-snapshot.ts +4 -3
- package/package.json +1 -1
- package/templates/.agents/QUICKSTART.en.md +19 -8
- package/templates/.agents/QUICKSTART.zh-CN.md +19 -8
- package/templates/.agents/README.en.md +10 -15
- package/templates/.agents/README.zh-CN.md +9 -13
- package/templates/.agents/rules/issue-sync.en.md +1 -1
- package/templates/.agents/rules/issue-sync.zh-CN.md +1 -1
- package/templates/.agents/rules/lifecycle-orchestration.en.md +1 -1
- package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +1 -1
- package/templates/.agents/rules/next-step-output.en.md +2 -2
- package/templates/.agents/rules/next-step-output.zh-CN.md +2 -2
- package/templates/.agents/rules/pr-sync.en.md +1 -1
- package/templates/.agents/rules/pr-sync.zh-CN.md +1 -1
- package/templates/.agents/rules/release-commands.en.md +3 -0
- package/templates/.agents/rules/release-commands.zh-CN.md +3 -0
- package/templates/.agents/rules/task-management.en.md +0 -2
- package/templates/.agents/rules/task-management.zh-CN.md +0 -2
- package/templates/.agents/rules/task-short-id.en.md +2 -2
- package/templates/.agents/rules/task-short-id.zh-CN.md +2 -2
- package/templates/.agents/scripts/task-short-id.js +2 -8
- package/templates/.agents/skills/analyze-task/SKILL.en.md +6 -6
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +6 -6
- package/templates/.agents/skills/analyze-task/config/verify.en.json +0 -1
- package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/archive-tasks/SKILL.en.md +5 -5
- package/templates/.agents/skills/archive-tasks/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/archive-tasks/scripts/archive-tasks.sh +10 -2
- package/templates/.agents/skills/block-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/block-task/config/verify.json +0 -1
- package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -6
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -6
- package/templates/.agents/skills/cancel-task/config/verify.json +0 -1
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/code-task/config/verify.en.json +0 -1
- package/templates/.agents/skills/code-task/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/code-task/reference/output-template.en.md +1 -1
- package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/SKILL.en.md +1 -1
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/commit/config/verify.json +0 -1
- package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +2 -2
- package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +2 -2
- package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
- package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +2 -2
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +0 -1
- package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +1 -1
- package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-task/SKILL.en.md +7 -7
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +8 -8
- package/templates/.agents/skills/complete-task/config/verify.en.json +0 -1
- package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/create-pr/SKILL.en.md +3 -3
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/create-pr/config/verify.json +0 -1
- package/templates/.agents/skills/create-pr/reference/change-report.en.md +1 -1
- package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +1 -1
- package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +1 -1
- package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +1 -1
- package/templates/.agents/skills/create-release-note/SKILL.en.md +2 -2
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/create-task/SKILL.en.md +4 -4
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/create-task/config/verify.json +0 -1
- package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-codescan/config/verify.json +0 -1
- package/templates/.agents/skills/import-dependabot/SKILL.en.md +3 -3
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/import-dependabot/config/verify.json +0 -1
- package/templates/.agents/skills/import-issue/SKILL.en.md +5 -5
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/import-issue/config/verify.json +0 -1
- package/templates/.agents/skills/plan-task/SKILL.en.md +5 -5
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/plan-task/config/verify.en.json +0 -1
- package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/restore-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/restore-task/config/verify.json +0 -1
- package/templates/.agents/skills/review-analysis/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-analysis/config/verify.en.json +0 -1
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +5 -5
- package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +5 -5
- 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 +4 -4
- package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +4 -4
- package/templates/.agents/skills/review-plan/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-plan/config/verify.en.json +0 -1
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/review-plan/reference/output-templates.en.md +5 -5
- package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +5 -5
- package/templates/.agents/skills/review-pr/SKILL.en.md +2 -2
- package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/review-pr/config/verify.en.json +0 -1
- package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +1 -1
- package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +1 -1
- package/templates/.agents/skills/run-manual-validation/config/verify.en.json +0 -1
- package/templates/.agents/skills/run-manual-validation/config/verify.zh-CN.json +0 -1
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/test/SKILL.en.md +0 -3
- package/templates/.agents/skills/test/SKILL.zh-CN.md +0 -3
- package/templates/.agents/skills/test-integration/SKILL.en.md +0 -3
- package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +0 -3
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +13 -6
- package/templates/.agents/skills/upgrade-dependency/SKILL.en.md +0 -3
- package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +0 -3
- package/templates/.agents/skills/watch-pr/SKILL.en.md +3 -3
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/watch-pr/config/verify.json +0 -1
- package/templates/.agents/templates/handoff.en.md +1 -1
- package/templates/.agents/templates/handoff.zh-CN.md +1 -1
- package/templates/.agents/workflows/bug-fix.en.yaml +1 -1
- package/templates/.agents/workflows/feature-development.en.yaml +1 -1
- package/templates/.agents/workflows/refactoring.en.yaml +1 -1
- package/dist/lib/task/task-execution-lock.js +0 -250
- package/lib/task/task-execution-lock.ts +0 -320
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { isSandbox } from '../sandbox/environment.js';
|
|
5
|
+
/**
|
|
6
|
+
* Resolve the physical task-workspace boundary from the verified process
|
|
7
|
+
* execution context. Sandbox mode (task-bound / branch-only) does not affect
|
|
8
|
+
* the task workspace mount location.
|
|
9
|
+
*/
|
|
10
|
+
export function resolveTaskWorkspaceExecutionBoundary(env = process.env) {
|
|
11
|
+
if (env.AGENT_INFRA_SANDBOX !== '1')
|
|
12
|
+
return 'host';
|
|
13
|
+
const statusMountPath = env.AGENT_INFRA_CONTROL_STATUS_DIR;
|
|
14
|
+
if (!statusMountPath || !isSandbox(env, { statusMountPath })) {
|
|
15
|
+
throw new Error('task workspace boundary requires a verified sandbox execution context');
|
|
16
|
+
}
|
|
17
|
+
return 'container';
|
|
18
|
+
}
|
|
19
|
+
export function resolveTaskWorkspaceLayout(input) {
|
|
20
|
+
const { project, boundary } = input;
|
|
21
|
+
if (!project || project === '.' || project === '..' || /[\\/\u0000-\u001f\u007f]/u.test(project)) {
|
|
22
|
+
throw new TypeError('project must be a safe single path segment');
|
|
23
|
+
}
|
|
24
|
+
let root;
|
|
25
|
+
if (boundary === 'container') {
|
|
26
|
+
root = '/task-workspace';
|
|
27
|
+
}
|
|
28
|
+
else if (boundary === 'host') {
|
|
29
|
+
if (!input.home)
|
|
30
|
+
throw new TypeError('home is required for host task workspace resolution');
|
|
31
|
+
if (!path.isAbsolute(input.home))
|
|
32
|
+
throw new TypeError('home must be an absolute path for host task workspace resolution');
|
|
33
|
+
root = path.join(input.home, '.agent-infra', 'task-workspaces', project);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
throw new TypeError(`unsupported task workspace boundary: ${String(boundary)}`);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
projectKey: project,
|
|
40
|
+
boundary,
|
|
41
|
+
root,
|
|
42
|
+
active: path.join(root, 'active'),
|
|
43
|
+
blocked: path.join(root, 'blocked'),
|
|
44
|
+
completed: path.join(root, 'completed'),
|
|
45
|
+
archive: path.join(root, 'archive'),
|
|
46
|
+
shortIds: path.join(root, 'active', '.short-ids.json')
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function resolveProjectTaskWorkspaceLayout(repoRoot, boundary = resolveTaskWorkspaceExecutionBoundary()) {
|
|
50
|
+
const configPath = path.join(repoRoot, '.agents', '.airc.json');
|
|
51
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
52
|
+
if (typeof config.project !== 'string')
|
|
53
|
+
throw new TypeError(`project is missing from ${configPath}`);
|
|
54
|
+
return resolveTaskWorkspaceLayout({ project: config.project, boundary, home: process.env.HOME || os.homedir() });
|
|
55
|
+
}
|
|
56
|
+
export function resolveProjectTaskWorkspaceRoot(repoRoot) {
|
|
57
|
+
return resolveProjectTaskWorkspaceLayout(repoRoot).root;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=workspace-root.js.map
|
|
@@ -3,6 +3,7 @@ import fs from 'node:fs';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
|
|
6
7
|
function git(repoRoot, indexFile, args) {
|
|
7
8
|
const env = indexFile ? { ...process.env, GIT_INDEX_FILE: indexFile } : process.env;
|
|
8
9
|
const result = spawnSync('git', args, { cwd: repoRoot, env, encoding: 'utf8' });
|
|
@@ -32,7 +33,7 @@ function captureWorktreeTree(repoRoot, forcedPath) {
|
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
function taskFileFingerprints(stateRoot, taskId) {
|
|
35
|
-
const activeRoot = path.join(stateRoot, '
|
|
36
|
+
const activeRoot = path.join(resolveProjectTaskWorkspaceRoot(stateRoot), 'active');
|
|
36
37
|
const roots = taskId ? [path.join(activeRoot, taskId)] : [activeRoot];
|
|
37
38
|
const records = [];
|
|
38
39
|
const visit = (absolute, relative) => {
|
|
@@ -45,7 +46,7 @@ function taskFileFingerprints(stateRoot, taskId) {
|
|
|
45
46
|
}
|
|
46
47
|
if (!stat.isFile() && !stat.isSymbolicLink())
|
|
47
48
|
return;
|
|
48
|
-
if (
|
|
49
|
+
if (/^task-workspace\/(?:active|blocked|completed)\/TASK-[0-9]{8}-[0-9]{6}\/\.runtime\/orchestration\.json$/u.test(relative))
|
|
49
50
|
return;
|
|
50
51
|
const content = stat.isSymbolicLink()
|
|
51
52
|
? Buffer.from(fs.readlinkSync(absolute))
|
|
@@ -60,7 +61,7 @@ function taskFileFingerprints(stateRoot, taskId) {
|
|
|
60
61
|
for (const root of roots) {
|
|
61
62
|
if (!fs.existsSync(root))
|
|
62
63
|
continue;
|
|
63
|
-
const relative = path.posix.join('
|
|
64
|
+
const relative = path.posix.join('task-workspace/active', path.relative(activeRoot, root).split(path.sep).join('/'));
|
|
64
65
|
visit(root, relative.replace(/\/$/, ''));
|
|
65
66
|
}
|
|
66
67
|
return records.sort((left, right) => left.path.localeCompare(right.path));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"protocolVersion": 3,
|
|
3
|
-
"packageVersion": "0.
|
|
4
|
-
"sourceInputHash": "
|
|
5
|
-
"internalExecutableBuildHash": "
|
|
3
|
+
"packageVersion": "0.12.0",
|
|
4
|
+
"sourceInputHash": "c0a3da802ab0d992591d4ddd191550627992e7f76fea444bab99f342bd59ec18",
|
|
5
|
+
"internalExecutableBuildHash": "536ccdede573b4204982cb184b9b0f5ad8c3f943f3d1e749b42ed05bbcca9ead"
|
|
6
6
|
}
|
|
@@ -11,7 +11,7 @@ import { captureTaskWriteMetadata, writeTask } from '../../../task/write.ts';
|
|
|
11
11
|
import { parseTypedTaskFrontmatter } from '../../../task/frontmatter.ts';
|
|
12
12
|
import { resolveTaskRef } from '../../../task/resolve-ref.ts';
|
|
13
13
|
import {
|
|
14
|
-
|
|
14
|
+
recoverActivatedOrchestrationDelegation,
|
|
15
15
|
readRun
|
|
16
16
|
} from '../../../task/orchestration.ts';
|
|
17
17
|
import type { OrchestrationOptions, OrchestrationRun } from '../../../task/orchestration.ts';
|
|
@@ -265,7 +265,7 @@ function appendRecoveryLog(
|
|
|
265
265
|
});
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
-
function
|
|
268
|
+
function recoverStartedLifecycle(
|
|
269
269
|
request: LifecycleRecoveryRequest,
|
|
270
270
|
options: LifecycleRecoveryOptions = {}
|
|
271
271
|
): LifecycleRecoveryResult {
|
|
@@ -372,7 +372,7 @@ function consumeRecoveryEvidence(
|
|
|
372
372
|
let consumed = stored;
|
|
373
373
|
if (stored.consumer === null) {
|
|
374
374
|
try {
|
|
375
|
-
consumed = store.
|
|
375
|
+
consumed = store.consume(pending.childId!, pending.id, stored.state.startEvidence?.hookDefinitionHash, {
|
|
376
376
|
taskId: pending.taskId, runId: pending.runId, receiptId: pending.id
|
|
377
377
|
});
|
|
378
378
|
} catch (error) {
|
|
@@ -393,7 +393,7 @@ function finishActiveRecovery(
|
|
|
393
393
|
row: StepRow,
|
|
394
394
|
options: LifecycleRecoveryOptions
|
|
395
395
|
): LifecycleRecoveryResult {
|
|
396
|
-
const recovered =
|
|
396
|
+
const recovered = recoverActivatedOrchestrationDelegation(taskId, {
|
|
397
397
|
receiptId: pending.id,
|
|
398
398
|
stage: pending.stage,
|
|
399
399
|
round: pending.round,
|
|
@@ -411,8 +411,8 @@ function recoverStartedLifecycleFromAdapter(
|
|
|
411
411
|
request: LifecycleRecoveryRequest,
|
|
412
412
|
options: LifecycleRecoveryOptions = {}
|
|
413
413
|
): LifecycleRecoveryResult {
|
|
414
|
-
return
|
|
414
|
+
return recoverStartedLifecycle(request, options);
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
-
export {
|
|
417
|
+
export { recoverStartedLifecycle, recoverStartedLifecycleFromAdapter };
|
|
418
418
|
export type { LifecycleRecoveryOptions, LifecycleRecoveryRequest, LifecycleRecoveryResult };
|
|
@@ -3,7 +3,6 @@ import path from 'node:path';
|
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
mutateDelegationAdapterEvidence,
|
|
6
|
-
mutateDelegationAdapterEvidenceWithinTaskLock,
|
|
7
6
|
readRun
|
|
8
7
|
} from '../../../task/orchestration.ts';
|
|
9
8
|
import type { DelegationReceipt } from '../../../task/delegation-receipts.ts';
|
|
@@ -195,12 +194,10 @@ function createCodexLifecycleStore(options: CodexLifecycleStoreOptions) {
|
|
|
195
194
|
function update(
|
|
196
195
|
binding: CodexLifecycleTaskBinding,
|
|
197
196
|
key: string,
|
|
198
|
-
mutate: (current: StoredCodexLifecycle | null) => StoredCodexLifecycle
|
|
199
|
-
taskLockHeld = false
|
|
197
|
+
mutate: (current: StoredCodexLifecycle | null) => StoredCodexLifecycle
|
|
200
198
|
): StoredCodexLifecycle {
|
|
201
199
|
let result: StoredCodexLifecycle | null = null;
|
|
202
|
-
|
|
203
|
-
updateState(options.taskId, binding.receiptId, 'codex', (value) => {
|
|
200
|
+
mutateDelegationAdapterEvidence(options.taskId, binding.receiptId, 'codex', (value) => {
|
|
204
201
|
const currentState = storedEvidence(value);
|
|
205
202
|
const current = currentState.records[key] ?? null;
|
|
206
203
|
result = mutate(current);
|
|
@@ -304,23 +301,18 @@ function createCodexLifecycleStore(options: CodexLifecycleStoreOptions) {
|
|
|
304
301
|
return matches[0]!;
|
|
305
302
|
}
|
|
306
303
|
|
|
307
|
-
function
|
|
304
|
+
function consume(
|
|
308
305
|
childThreadId: string,
|
|
309
306
|
consumer: string,
|
|
310
|
-
expectedHookDefinitionHash
|
|
311
|
-
expectedTaskBinding
|
|
312
|
-
taskLockHeld: boolean
|
|
307
|
+
expectedHookDefinitionHash?: string,
|
|
308
|
+
expectedTaskBinding?: CodexLifecycleTaskBinding
|
|
313
309
|
): StoredCodexLifecycle {
|
|
314
310
|
if (!consumer.trim()) throw new Error('Codex lifecycle consumer is required');
|
|
315
311
|
const current = read(childThreadId);
|
|
316
312
|
const binding = expectedTaskBinding ?? current.taskBinding;
|
|
317
313
|
if (!binding) throw new Error('Codex lifecycle task receipt binding is missing');
|
|
318
314
|
const spawn = current.state.spawn;
|
|
319
|
-
if (!spawn)
|
|
320
|
-
throw new Error(taskLockHeld
|
|
321
|
-
? 'Codex lifecycle task receipt binding is missing'
|
|
322
|
-
: 'Codex lifecycle spawn evidence is missing');
|
|
323
|
-
}
|
|
315
|
+
if (!spawn) throw new Error('Codex lifecycle spawn evidence is missing');
|
|
324
316
|
const key = recordKey(spawn.sessionId, spawn.turnId, spawn.toolUseId);
|
|
325
317
|
return update(binding, key, (latest) => {
|
|
326
318
|
if (!latest || expectedTaskBinding && JSON.stringify(latest.taskBinding) !== JSON.stringify(expectedTaskBinding)) {
|
|
@@ -335,25 +327,7 @@ function createCodexLifecycleStore(options: CodexLifecycleStoreOptions) {
|
|
|
335
327
|
}
|
|
336
328
|
if (latest.consumer) return latest;
|
|
337
329
|
return Object.freeze({ ...latest, revision: latest.revision + 1, consumer, consumedAt: now(), updatedAt: now() });
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
function consume(
|
|
342
|
-
childThreadId: string,
|
|
343
|
-
consumer: string,
|
|
344
|
-
expectedHookDefinitionHash?: string,
|
|
345
|
-
expectedTaskBinding?: CodexLifecycleTaskBinding
|
|
346
|
-
): StoredCodexLifecycle {
|
|
347
|
-
return consumeWithLockMode(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding, false);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
function consumeWithinTaskLock(
|
|
351
|
-
childThreadId: string,
|
|
352
|
-
consumer: string,
|
|
353
|
-
expectedHookDefinitionHash?: string,
|
|
354
|
-
expectedTaskBinding?: CodexLifecycleTaskBinding
|
|
355
|
-
): StoredCodexLifecycle {
|
|
356
|
-
return consumeWithLockMode(childThreadId, consumer, expectedHookDefinitionHash, expectedTaskBinding, true);
|
|
330
|
+
});
|
|
357
331
|
}
|
|
358
332
|
|
|
359
333
|
function expireBefore(cutoff: string): number {
|
|
@@ -373,7 +347,7 @@ function createCodexLifecycleStore(options: CodexLifecycleStoreOptions) {
|
|
|
373
347
|
return changed;
|
|
374
348
|
}
|
|
375
349
|
|
|
376
|
-
return Object.freeze({ taskId: options.taskId, root: path.join(taskDir, '.runtime'), apply, applyToSpawn, consume,
|
|
350
|
+
return Object.freeze({ taskId: options.taskId, root: path.join(taskDir, '.runtime'), apply, applyToSpawn, consume, expireBefore, findByParent, findByTaskBinding, read });
|
|
377
351
|
}
|
|
378
352
|
|
|
379
353
|
export { createCodexLifecycleStore, hasActiveCodexLifecycleEvidence, readCodexLifecycleActivationEvidence };
|
|
@@ -481,7 +481,7 @@ async function sealCodexOrchestrationDelegation(
|
|
|
481
481
|
coreOptions(options),
|
|
482
482
|
() => {
|
|
483
483
|
try {
|
|
484
|
-
const consumed = store.
|
|
484
|
+
const consumed = store.consume(
|
|
485
485
|
childThreadId,
|
|
486
486
|
current.receipt.id,
|
|
487
487
|
existing.state.spawn?.hookDefinitionHash,
|
package/lib/decide.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { parseTaskScope } from './task/command-options.ts';
|
|
|
3
3
|
import { applyHumanDecision } from './task/decision-intents.ts';
|
|
4
4
|
import { canonicalTimestamp } from './task/write.ts';
|
|
5
5
|
import { resolveTaskContext } from './task/resolve-ref.ts';
|
|
6
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from './task/task-execution-lock.ts';
|
|
7
6
|
|
|
8
7
|
type DecideOptions = {
|
|
9
8
|
repoRoot?: string;
|
|
@@ -70,15 +69,11 @@ export async function decide(args: string[], options: DecideOptions = {}): Promi
|
|
|
70
69
|
repoRoot: resolved.repoRoot,
|
|
71
70
|
metadataProvider: () => ({ timestamp: now, agentInfraVersion: options.version ?? VERSION })
|
|
72
71
|
};
|
|
73
|
-
|
|
74
|
-
const execute = async () => applyHumanDecision(request, writeOptions);
|
|
75
|
-
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-decision', execute);
|
|
72
|
+
const result = await applyHumanDecision(request, writeOptions);
|
|
76
73
|
if (result.error) throw new Error(result.error.message);
|
|
77
74
|
return 0;
|
|
78
75
|
} catch (error) {
|
|
79
|
-
const message = error instanceof
|
|
80
|
-
? `${error.code}: ${error.message}`
|
|
81
|
-
: error instanceof Error ? error.message : String(error);
|
|
76
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
82
77
|
process.stderr.write(`Error: ${message}\n`);
|
|
83
78
|
return 1;
|
|
84
79
|
}
|
|
@@ -52,6 +52,7 @@ export const INTERNAL_HANDLER_ROUTE_SELECTORS = Object.freeze({
|
|
|
52
52
|
'pr-review-grade': ['decide', 'resolve-host', 'verify-artifact'],
|
|
53
53
|
'platform-checks': ['inspect', 'watch', 'resolve-run', 'logs'],
|
|
54
54
|
'task-context': ['resolve'],
|
|
55
|
+
'task-workspace': ['resolve'],
|
|
55
56
|
'task-ledger': ['decision-next-id', 'stage-status', 'finding-upsert', 'finding-respond', 'finding-review', 'decision-upsert', 'rework-intent-upsert', 'rework-intent-rebuild'],
|
|
56
57
|
'task-warning': ['list', 'add', 'set-status'],
|
|
57
58
|
'task-activity': ['pr-review-inspect', 'pr-review-start', 'pr-review-complete', 'pr-review-terminate'],
|
|
@@ -104,6 +105,7 @@ export function internalRouteSelector(command: string, args: readonly string[]):
|
|
|
104
105
|
if (['task-ledger', 'task-warning', 'task-activity'].includes(command)) return args[1] ?? '';
|
|
105
106
|
if (command === 'task-delivery') return args[1] ?? '';
|
|
106
107
|
if (command === 'task-context') return first(args);
|
|
108
|
+
if (command === 'task-workspace') return first(args);
|
|
107
109
|
return first(args);
|
|
108
110
|
}
|
|
109
111
|
|
|
@@ -4,7 +4,6 @@ import path from 'node:path';
|
|
|
4
4
|
import { locateActivityLog, pairEntries } from '../task/activity-log.ts';
|
|
5
5
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
6
6
|
import { applyTaskEvent } from '../task/events.ts';
|
|
7
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
8
7
|
import { normalizeAgentToken } from '../agent-clients/tokens.ts';
|
|
9
8
|
import { MANUAL_VALIDATION_RECEIPT_PLACEHOLDER, createManualValidationReceipt, manualValidationFinalSummaryDigest, manualValidationFinalSummaryProjectionMatches, readManualValidationReceipt, writeManualValidationReceiptAtomic } from '../task/manual-validation-receipt.ts';
|
|
10
9
|
import { archiveManualValidationGeneration, createManualValidationTransaction, readManualValidationTransaction, retryManualValidationTransaction, summaryPreimageDigest, transitionManualValidationTransaction, validateManualValidationGenerationArchive, writeManualValidationTransactionAtomic } from '../task/manual-validation-transaction.ts';
|
|
@@ -91,20 +90,10 @@ async function executeManualValidationTransaction(taskRef: string, values: Recor
|
|
|
91
90
|
if (!['pr_created', 'pr_reused', 'no_op'].includes(primaryResult)) return result('failed', { code: 'MANUAL_VALIDATION_TRANSACTION_ARGS_INVALID', message: '--result must be pr_created, pr_reused, or no_op' });
|
|
92
91
|
const resolved = resolveTaskRef(taskRef, { repoRoot: cwd });
|
|
93
92
|
if (!resolved.ok) return result('failed', { code: resolved.code, message: resolved.message });
|
|
94
|
-
|
|
95
|
-
return await withTaskExecutionLock(
|
|
96
|
-
resolved.repoRoot,
|
|
97
|
-
resolved.taskId,
|
|
98
|
-
`manual-validation:${taskRef}`,
|
|
99
|
-
() => executeManualValidationTransactionLocked(taskRef, values, cwd, resolved, agent, primaryResult as 'pr_created' | 'pr_reused' | 'no_op', prepareOnly, options)
|
|
100
|
-
);
|
|
101
|
-
} catch (error) {
|
|
102
|
-
if (error instanceof TaskExecutionLockError) return result('failed', { code: error.code, message: error.message });
|
|
103
|
-
throw error;
|
|
104
|
-
}
|
|
93
|
+
return executeManualValidationTransactionAtResolvedTask(taskRef, values, cwd, resolved, agent, primaryResult as 'pr_created' | 'pr_reused' | 'no_op', prepareOnly, options);
|
|
105
94
|
}
|
|
106
95
|
|
|
107
|
-
async function
|
|
96
|
+
async function executeManualValidationTransactionAtResolvedTask(
|
|
108
97
|
taskRef: string,
|
|
109
98
|
values: Record<string, string>,
|
|
110
99
|
cwd: string,
|
|
@@ -168,7 +157,7 @@ async function executeManualValidationTransactionLocked(
|
|
|
168
157
|
let startedEventApplied = false;
|
|
169
158
|
if (!transactionResult.ok) {
|
|
170
159
|
transaction = createTransaction();
|
|
171
|
-
const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transactionId, reasonCode: 'user-request', transactionId }, {
|
|
160
|
+
const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transactionId, reasonCode: 'user-request', transactionId }, { repoRoot: cwd });
|
|
172
161
|
if (started.status === 'failed') return result('failed', started.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation started event failed' });
|
|
173
162
|
startedEventApplied = true;
|
|
174
163
|
if (previousTransaction) {
|
|
@@ -186,7 +175,7 @@ async function executeManualValidationTransactionLocked(
|
|
|
186
175
|
}
|
|
187
176
|
}
|
|
188
177
|
if (transaction.phase === 'prepared' && !startedEventApplied) {
|
|
189
|
-
const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', transactionId: transaction.transactionId }, {
|
|
178
|
+
const started = applyTaskEvent({ taskRef, event: 'manual-validation.started', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', transactionId: transaction.transactionId }, { repoRoot: cwd });
|
|
190
179
|
if (started.status === 'failed') return result('failed', started.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation started event failed' });
|
|
191
180
|
}
|
|
192
181
|
if (prepareOnly) return result('applied', null, { transaction, prepared: true, idempotent });
|
|
@@ -206,7 +195,7 @@ async function executeManualValidationTransactionLocked(
|
|
|
206
195
|
if (transaction.phase === 'prepared') {
|
|
207
196
|
const staged = await syncPullRequestSummary(taskRef, {
|
|
208
197
|
cwd, client: options.client, agent, body: pendingBody, changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', strict: true,
|
|
209
|
-
manualValidation: { phase: 'pending', transactionId: transaction.transactionId }
|
|
198
|
+
manualValidation: { phase: 'pending', transactionId: transaction.transactionId }
|
|
210
199
|
});
|
|
211
200
|
if (!['applied', 'no-op'].includes(staged.status)) transactionFailure(staged.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'pending summary staging failed' });
|
|
212
201
|
transitionAndPersist('summary-staged');
|
|
@@ -242,7 +231,7 @@ async function executeManualValidationTransactionLocked(
|
|
|
242
231
|
transitionAndPersist('receipt-committed', { committedReceipt: receipt.receiptDigest });
|
|
243
232
|
}
|
|
244
233
|
if (transaction.phase === 'receipt-committed' && !transaction.eventAppended) {
|
|
245
|
-
const completed = applyTaskEvent({ taskRef, event: 'manual-validation.completed', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', artifact: values.artifact, summaryResult: 'human-confirmed validation and committed receipt', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha }, {
|
|
234
|
+
const completed = applyTaskEvent({ taskRef, event: 'manual-validation.completed', agent, initiator: 'model', requestId: transaction.transactionId, reasonCode: 'user-request', artifact: values.artifact, summaryResult: 'human-confirmed validation and committed receipt', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha }, { repoRoot: cwd });
|
|
246
235
|
if (completed.status === 'failed') transactionFailure(completed.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_FAILED', message: 'manual-validation completion event failed' });
|
|
247
236
|
transitionAndPersist('receipt-committed', { eventAppended: true });
|
|
248
237
|
}
|
|
@@ -251,7 +240,7 @@ async function executeManualValidationTransactionLocked(
|
|
|
251
240
|
}
|
|
252
241
|
const promoted = await syncPullRequestSummary(taskRef, {
|
|
253
242
|
cwd, client: options.client, agent, body: manualSummaryBody(finalBodyWithoutReceipt, 'final'), changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult, strict: true,
|
|
254
|
-
manualValidation: { phase: 'final', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha, authority: 'coordinator' }
|
|
243
|
+
manualValidation: { phase: 'final', transactionId: transaction.transactionId, receiptDigest: receipt.receiptDigest, prHeadSha: receipt.prHeadSha, authority: 'coordinator' }
|
|
255
244
|
});
|
|
256
245
|
if (!['applied', 'no-op'].includes(promoted.status)) transactionFailure(promoted.error ?? { code: 'MANUAL_VALIDATION_TRANSACTION_RECOVERY_REQUIRED', message: 'final summary promotion failed' });
|
|
257
246
|
const postWrite = await summaryCommentState(taskRef, { cwd, client: options.client });
|
|
@@ -264,7 +253,7 @@ async function executeManualValidationTransactionLocked(
|
|
|
264
253
|
try {
|
|
265
254
|
await syncPullRequestSummary(taskRef, {
|
|
266
255
|
cwd, client: options.client, agent, body: pendingBody, changeReportFile: path.resolve(cwd, values.changeReportFile!), primaryResult: primaryResult as 'pr_created' | 'pr_reused' | 'no_op', strict: true,
|
|
267
|
-
manualValidation: { phase: 'pending', transactionId: transaction.transactionId }
|
|
256
|
+
manualValidation: { phase: 'pending', transactionId: transaction.transactionId }
|
|
268
257
|
});
|
|
269
258
|
} catch {
|
|
270
259
|
// Preserve recovery-required when pending compensation cannot be confirmed.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.ts';
|
|
3
4
|
import { createHash, randomUUID } from 'node:crypto';
|
|
4
5
|
|
|
5
6
|
import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.ts';
|
|
@@ -98,14 +99,14 @@ async function platformComment(args: string[] = []): Promise<void> {
|
|
|
98
99
|
const unexpected = Object.keys(parsed.values).find((key) => !['issue', 'taskId', 'output', 'cwd'].includes(key));
|
|
99
100
|
if (unexpected) { fail(`recover does not accept '--${unexpected}'`); return; }
|
|
100
101
|
const outputPath = path.resolve(cwd, output);
|
|
101
|
-
const workspaceDir =
|
|
102
|
+
const workspaceDir = resolveProjectTaskWorkspaceRoot(cwd);
|
|
102
103
|
const stagingDir = path.dirname(outputPath);
|
|
103
104
|
const stagingParent = fs.existsSync(stagingDir) ? path.dirname(fs.realpathSync(stagingDir)) : '';
|
|
104
105
|
const realWorkspace = fs.existsSync(workspaceDir) ? fs.realpathSync(workspaceDir) : '';
|
|
105
106
|
if (path.basename(outputPath) !== 'task.md' || stagingParent !== realWorkspace
|
|
106
107
|
|| !path.basename(stagingDir).startsWith('.restore-staging-') || !fs.existsSync(stagingDir)
|
|
107
108
|
|| !fs.lstatSync(stagingDir).isDirectory() || fs.existsSync(outputPath)) {
|
|
108
|
-
fail('recover output must be a new task.md inside an existing
|
|
109
|
+
fail('recover output must be a new task.md inside an existing task-workspace/.restore-staging-* directory');
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
111
112
|
const listed = await listPlatformComments(issue, cwd);
|
|
@@ -7,7 +7,6 @@ import type {
|
|
|
7
7
|
PrReviewInspectIntent
|
|
8
8
|
} from '../task/activity-intent.ts';
|
|
9
9
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
10
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
11
10
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
12
11
|
|
|
13
12
|
const USAGE = `Usage: agent-infra-internal task-activity <task-ref> pr-review-inspect
|
|
@@ -95,15 +94,7 @@ async function taskActivity(args: string[] = []): Promise<void> {
|
|
|
95
94
|
}
|
|
96
95
|
const resolved = resolveTaskRef(taskRef);
|
|
97
96
|
if (!resolved.ok) { usageFailure(resolved.message); return; }
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-activity.${kind}`, async () => applyPrReviewActivityIntent(values as PrReviewActivityIntent, { lockAlreadyHeld: true }));
|
|
101
|
-
} catch (error) {
|
|
102
|
-
if (!(error instanceof TaskExecutionLockError)) throw error;
|
|
103
|
-
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
|
|
104
|
-
process.exitCode = 1;
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
97
|
+
const result = await applyPrReviewActivityIntent(values as PrReviewActivityIntent);
|
|
107
98
|
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
108
99
|
if (result.status === 'failed') process.exitCode = 1;
|
|
109
100
|
}
|
|
@@ -2,7 +2,6 @@ import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.t
|
|
|
2
2
|
import { applyTaskEvent, eventCatalog } from '../task/events.ts';
|
|
3
3
|
import type { TaskEventRequest, Verdict } from '../task/events.ts';
|
|
4
4
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
5
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
6
5
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
7
6
|
|
|
8
7
|
const USAGE = `Usage: agent-infra-internal task-event <N | TASK-id> <event> --agent <agent> [event options] [--orchestrated] [--dry-run]
|
|
@@ -73,15 +72,7 @@ async function taskEvent(args: string[] = []): Promise<void> {
|
|
|
73
72
|
process.exitCode = 1;
|
|
74
73
|
return;
|
|
75
74
|
}
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, async () => applyTaskEvent(request, { lockAlreadyHeld: true }));
|
|
79
|
-
} catch (error) {
|
|
80
|
-
if (!(error instanceof TaskExecutionLockError)) throw error;
|
|
81
|
-
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
|
|
82
|
-
process.exitCode = 1;
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
75
|
+
const result = await applyTaskEvent(request);
|
|
85
76
|
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
86
77
|
if (result.status === 'failed') process.exitCode = 1;
|
|
87
78
|
}
|
|
@@ -4,7 +4,6 @@ import { applyLedgerIntent } from '../task/ledger-intents.ts';
|
|
|
4
4
|
import type { LedgerIntent } from '../task/ledger-intents.ts';
|
|
5
5
|
import { LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, isReviewStage, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from '../task/ledger.ts';
|
|
6
6
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
7
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
8
7
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
9
8
|
|
|
10
9
|
const USAGE = `Usage: agent-infra-internal task-ledger <task-ref> <intent> [intent flags] [--dry-run]\n\nIntents: finding-upsert, finding-respond, finding-review, decision-next-id, decision-upsert, rework-intent-upsert, rework-intent-rebuild, stage-status\n`;
|
|
@@ -116,15 +115,7 @@ async function taskLedger(args: string[] = []): Promise<void> {
|
|
|
116
115
|
}
|
|
117
116
|
const lockResolved = resolveTaskRef(taskRef);
|
|
118
117
|
if (!lockResolved.ok) { usageFailure(lockResolved.message); return; }
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
result = await withTaskExecutionLock(lockResolved.repoRoot, lockResolved.taskId, `task-ledger.${kind}`, async () => applyLedgerIntent(values as LedgerIntent));
|
|
122
|
-
} catch (error) {
|
|
123
|
-
if (!(error instanceof TaskExecutionLockError)) throw error;
|
|
124
|
-
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
|
|
125
|
-
process.exitCode = 1;
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
118
|
+
const result = await applyLedgerIntent(values as LedgerIntent);
|
|
128
119
|
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
129
120
|
if (result.status === 'failed') process.exitCode = 1;
|
|
130
121
|
}
|
|
@@ -112,6 +112,7 @@ function internalTaskRoutes(): TaskOperationDescriptor[] {
|
|
|
112
112
|
descriptor('internal', 'platform-checks', 'resolve-run', 'conditional', 'diagnostic'),
|
|
113
113
|
descriptor('internal', 'platform-checks', 'logs', 'conditional', 'diagnostic'),
|
|
114
114
|
descriptor('internal', 'task-context', 'resolve', 'task-bound', 'diagnostic'),
|
|
115
|
+
descriptor('internal', 'task-workspace', 'resolve', 'non-task', 'diagnostic', 'none'),
|
|
115
116
|
descriptor('internal', 'task-ledger', 'decision-next-id', 'task-bound', 'diagnostic'),
|
|
116
117
|
descriptor('internal', 'task-ledger', 'stage-status', 'task-bound', 'diagnostic'),
|
|
117
118
|
descriptor('internal', 'task-ledger', 'finding-upsert', 'task-bound', 'progress'),
|
|
@@ -214,7 +215,7 @@ export const INTERNAL_DISPATCHER_ROUTES = Object.freeze([
|
|
|
214
215
|
'task-create', 'task-qualification', 'sandbox-control', 'agent-client', 'codex-lifecycle',
|
|
215
216
|
'git-workflow', 'task-delivery', 'release-workflow', 'platform-release-notes', 'platform-security', 'platform-metadata', 'platform-context',
|
|
216
217
|
'platform-comment', 'platform-issue', 'platform-pr', 'platform-pr-review', 'pr-review-grade',
|
|
217
|
-
'platform-checks', 'task-context', 'task-ledger', 'task-warning', 'task-activity', 'task-artifact',
|
|
218
|
+
'platform-checks', 'task-context', 'task-workspace', 'task-ledger', 'task-warning', 'task-activity', 'task-artifact',
|
|
218
219
|
'task-orchestration', 'task-review', 'task-event', 'task-lifecycle',
|
|
219
220
|
'task-finalization', 'task-platform-recovery', 'task-short-id', 'task-snapshot', 'task-verify', 'task-validate', 'manual-validation'
|
|
220
221
|
]);
|
|
@@ -5,7 +5,6 @@ import type { QualificationConfirmationRequest } from '../task/qualification-con
|
|
|
5
5
|
import { applyQualificationProposal } from '../task/qualification-intents.ts';
|
|
6
6
|
import type { QualificationProposalRequest } from '../task/qualification-intents.ts';
|
|
7
7
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
8
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
9
8
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
10
9
|
|
|
11
10
|
const USAGE = `Usage: agent-infra-internal task-qualification <task-ref> <proposal|confirm|supersede|revoke> --input <json-file> [--dry-run]\n`;
|
|
@@ -46,16 +45,11 @@ async function taskQualification(args: string[] = []): Promise<void> {
|
|
|
46
45
|
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) { fail('qualification input must be an object'); return; }
|
|
47
46
|
const resolved = resolveTaskRef(taskRef);
|
|
48
47
|
if (!resolved.ok) { fail(resolved.message, resolved.code); return; }
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (result.status === 'failed') process.exitCode = 1;
|
|
55
|
-
} catch (error) {
|
|
56
|
-
if (error instanceof TaskExecutionLockError) fail(`${error.code}: ${error.message}`, error.code);
|
|
57
|
-
else throw error;
|
|
58
|
-
}
|
|
48
|
+
const result = await (operation === 'proposal'
|
|
49
|
+
? applyQualificationProposal({ ...(payload as Record<string, unknown>), taskRef: resolved.taskId, dryRun } as QualificationProposalRequest, { repoRoot: resolved.repoRoot })
|
|
50
|
+
: applyQualificationConfirmation({ ...(payload as Record<string, unknown>), taskRef: resolved.taskId, operation, dryRun } as QualificationConfirmationRequest, { repoRoot: resolved.repoRoot }));
|
|
51
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
52
|
+
if (result.status === 'failed') process.exitCode = 1;
|
|
59
53
|
}
|
|
60
54
|
|
|
61
55
|
export { taskQualification };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { parseReviewCommand } from '../task/review-command.ts';
|
|
2
2
|
import { finalizeReviewSummary, preflightReviewSummary } from '../task/review-finalization.ts';
|
|
3
3
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
4
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
5
4
|
import { ensureInternalHandlerRoute } from './cli-route-inventory.ts';
|
|
6
5
|
|
|
7
6
|
const USAGE = 'Usage: agent-infra-internal task-review <task-ref> <preflight|finalize-summary> --stage <analysis|plan|code> --artifact <review-*.md> [--orchestrated] [--dry-run]\n';
|
|
@@ -30,19 +29,9 @@ async function taskReview(args: string[] = []): Promise<void> {
|
|
|
30
29
|
const operation = args[1]!;
|
|
31
30
|
const resolved = resolveTaskRef(args[0]!);
|
|
32
31
|
if (!resolved.ok) { failUsage(resolved.message); return; }
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return operation === 'preflight'
|
|
37
|
-
? preflightReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true })
|
|
38
|
-
: finalizeReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun }, { lockAlreadyHeld: true });
|
|
39
|
-
});
|
|
40
|
-
} catch (error) {
|
|
41
|
-
if (!(error instanceof TaskExecutionLockError)) throw error;
|
|
42
|
-
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
|
|
43
|
-
process.exitCode = 1;
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
32
|
+
const result = operation === 'preflight'
|
|
33
|
+
? preflightReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun })
|
|
34
|
+
: finalizeReviewSummary({ taskRef: args[0]!, stage, artifact, orchestrated, dryRun });
|
|
46
35
|
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
47
36
|
if (result.status === 'failed') process.exitCode = 1;
|
|
48
37
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
|
|
3
3
|
import { detectRepoRoot } from '../task/resolve-ref.ts';
|
|
4
|
+
import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.ts';
|
|
4
5
|
import { configuredShortIdLength, executeShortIdCommand } from '../task/short-id.ts';
|
|
5
6
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
6
7
|
|
|
@@ -50,7 +51,7 @@ function taskShortId(args: string[] = []): void {
|
|
|
50
51
|
if (positional.length > (operation === 'list' ? 0 : 1)) { failure('too many positional arguments'); return; }
|
|
51
52
|
let repoRoot: string | null = null;
|
|
52
53
|
try { repoRoot = detectRepoRoot(); } catch { /* custom active-dir mode */ }
|
|
53
|
-
const resolvedActiveDir = activeDir ?? (repoRoot ? path.join(repoRoot, '
|
|
54
|
+
const resolvedActiveDir = activeDir ?? (repoRoot ? path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active') : null);
|
|
54
55
|
if (!resolvedActiveDir) { failure('cannot determine active task directory'); return; }
|
|
55
56
|
const width = shortIdLength ?? (repoRoot ? configuredShortIdLength(repoRoot) : 2);
|
|
56
57
|
const result = executeShortIdCommand({
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { renderTaskVerification, verifyTaskEvent } from '../task/verification.ts';
|
|
2
2
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
3
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
4
3
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
5
4
|
|
|
6
5
|
const USAGE = 'Usage: agent-infra-internal task-verify <N | TASK-id> <verification-event> [--artifact <canonical.md>] [--format json|text]\n';
|
|
@@ -34,14 +33,7 @@ async function taskVerify(args: string[] = []): Promise<void> {
|
|
|
34
33
|
}
|
|
35
34
|
const resolved = resolveTaskRef(taskRef);
|
|
36
35
|
if (!resolved.ok) { fail(resolved.message); return; }
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-verify.${event}`, async () => verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) }));
|
|
40
|
-
} catch (error) {
|
|
41
|
-
if (!(error instanceof TaskExecutionLockError)) throw error;
|
|
42
|
-
fail(`${error.code}: ${error.message}`);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
36
|
+
const result = await verifyTaskEvent({ taskRef, event, ...(artifact ? { artifact } : {}) });
|
|
45
37
|
process.stdout.write(format === 'text' ? renderTaskVerification(result) : `${JSON.stringify(result)}\n`);
|
|
46
38
|
process.exitCode = result.status === 'pass' ? 0 : result.status === 'blocked' ? 2 : 1;
|
|
47
39
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { applyWorkflowWarningIntent } from '../task/workflow-warning-intents.ts';
|
|
2
2
|
import type { WorkflowWarningIntent } from '../task/workflow-warning-intents.ts';
|
|
3
3
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
4
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
5
4
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
6
5
|
|
|
7
6
|
const USAGE = `Usage: agent-infra-internal task-warning <task-ref> <add|set-status|list> [intent flags] [--dry-run]\n`;
|
|
@@ -52,15 +51,7 @@ async function taskWarning(args: string[] = []): Promise<void> {
|
|
|
52
51
|
if (missing) { usageFailure(`${kind} requires '${missing}'`); return; }
|
|
53
52
|
const resolved = resolveTaskRef(taskRef);
|
|
54
53
|
if (!resolved.ok) { usageFailure(resolved.message); return; }
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-warning.${kind}`, async () => applyWorkflowWarningIntent(values as WorkflowWarningIntent));
|
|
58
|
-
} catch (error) {
|
|
59
|
-
if (!(error instanceof TaskExecutionLockError)) throw error;
|
|
60
|
-
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: error.code, message: error.message } })}\n`);
|
|
61
|
-
process.exitCode = 1;
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
54
|
+
const result = await applyWorkflowWarningIntent(values as WorkflowWarningIntent);
|
|
64
55
|
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
65
56
|
if (result.status === 'failed') process.exitCode = 1;
|
|
66
57
|
}
|