@fitlab-ai/agent-infra 0.11.14 → 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-finalization.js +2 -2
- 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-change-report.js +10 -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 +18 -6
- 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/lifecycle.js +2 -21
- 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 +36 -20
- 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 +38 -49
- 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 +12 -10
- 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-finalization.ts +2 -2
- 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-change-report.ts +9 -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 +17 -5
- 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/lifecycle.ts +4 -21
- 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 +42 -18
- 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 +40 -51
- 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 +15 -10
- 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 +17 -9
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +18 -10
- 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 +13 -3
- package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +13 -3
- 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/SKILL.en.md +5 -5
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -5
- 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-manual-validation/reference/discovery-and-execution.en.md +13 -2
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +13 -2
- package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -0
- package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -0
- 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 +21 -4
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +22 -5
- package/templates/.agents/skills/watch-pr/config/verify.json +0 -1
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +14 -0
- package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +15 -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/runtime/agent-runtime.js +0 -33
- package/dist/lib/task/runtime-paths.js +0 -10
- package/dist/lib/task/task-execution-lock.js +0 -250
- package/lib/runtime/agent-runtime.ts +0 -41
- package/lib/task/runtime-paths.ts +0 -12
- package/lib/task/task-execution-lock.ts +0 -320
|
@@ -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
|
}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import { applyTaskFinalization } from '../task/finalization.ts';
|
|
8
8
|
import { detectRepoRoot, resolveTaskRef } from '../task/resolve-ref.ts';
|
|
9
9
|
import { resolveSandboxControlTransport } from './task-operation-registry.ts';
|
|
10
|
-
import {
|
|
10
|
+
import { validateSandboxControlTaskIdentity } from '../sandbox/control/lifecycle.ts';
|
|
11
11
|
import { loadSandboxControlLocation } from '../sandbox/config.ts';
|
|
12
12
|
import { serializeTaskFinalizationEnvelope } from '../task/finalization-envelope.ts';
|
|
13
13
|
import { verifyTaskEvent } from '../task/verification.ts';
|
|
@@ -97,7 +97,7 @@ async function taskFinalization(args: string[] = []): Promise<void> {
|
|
|
97
97
|
repoRoot,
|
|
98
98
|
beforeLifecycle: async (currentTaskId) => {
|
|
99
99
|
if (currentTaskId !== taskId) throw new Error('SANDBOX_CONTROL_IDENTITY_MISMATCH');
|
|
100
|
-
|
|
100
|
+
validateSandboxControlTaskIdentity(
|
|
101
101
|
controlRoot,
|
|
102
102
|
{ taskId, generation, controlRootId, statusDir }
|
|
103
103
|
);
|
|
@@ -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
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { detectRepoRoot } from '../task/resolve-ref.ts';
|
|
2
|
+
import { resolveProjectTaskWorkspaceLayout, type ExecutionBoundary } from '../task/workspace-root.ts';
|
|
3
|
+
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
4
|
+
|
|
5
|
+
const USAGE = `Usage: agent-infra-internal task-workspace resolve [--boundary host|container]\n`;
|
|
6
|
+
|
|
7
|
+
function fail(code: string, message: string): void {
|
|
8
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code, message } })}\n`);
|
|
9
|
+
process.exitCode = 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function taskWorkspace(args: string[] = []): void {
|
|
13
|
+
if (!ensureInternalHandlerRoute('task-workspace', args)) return;
|
|
14
|
+
const operation = args[0] ?? '';
|
|
15
|
+
if (operation === '--help' || operation === '-h') { process.stdout.write(USAGE); return; }
|
|
16
|
+
if (!internalHandlerRoute('task-workspace', 'resolve', operation)) {
|
|
17
|
+
fail('TASK_WORKSPACE_PAYLOAD_INVALID', "operation must be 'resolve'");
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
let boundary: ExecutionBoundary = 'host';
|
|
21
|
+
const options = args.slice(1);
|
|
22
|
+
if (options.length !== 0) {
|
|
23
|
+
if (options.length !== 2 || options[0] !== '--boundary') {
|
|
24
|
+
fail('TASK_WORKSPACE_PAYLOAD_INVALID', 'invalid or duplicate task-workspace option');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
boundary = options[1] as ExecutionBoundary;
|
|
28
|
+
}
|
|
29
|
+
if (boundary !== 'host' && boundary !== 'container') {
|
|
30
|
+
fail('TASK_WORKSPACE_PAYLOAD_INVALID', 'resolve accepts only --boundary host|container');
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const layout = resolveProjectTaskWorkspaceLayout(detectRepoRoot(), boundary);
|
|
35
|
+
process.stdout.write(`${JSON.stringify({ status: 'resolved', changed: false, projectKey: layout.projectKey, boundary: layout.boundary, root: layout.root, error: null })}\n`);
|
|
36
|
+
} catch (error) { fail('TASK_WORKSPACE_OPERATION_FAILED', error instanceof Error ? error.message : String(error)); }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { taskWorkspace };
|
package/lib/merge.ts
CHANGED
|
@@ -4,6 +4,7 @@ import path from 'node:path';
|
|
|
4
4
|
import crypto from 'node:crypto';
|
|
5
5
|
import { removeDirRecursive } from './remove-dir.ts';
|
|
6
6
|
import { validateCurrentTaskContract } from './task/current-contract.ts';
|
|
7
|
+
import { resolveProjectTaskWorkspaceRoot } from './task/workspace-root.ts';
|
|
7
8
|
|
|
8
9
|
const TASK_ID_RE = /^TASK-\d{8}-\d{6}$/;
|
|
9
10
|
const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;
|
|
@@ -988,7 +989,7 @@ function mergeArchiveSection(sourceArchive: string, localArchive: string, report
|
|
|
988
989
|
}
|
|
989
990
|
|
|
990
991
|
function printSection(lines: string[], name: MutableSection, counts: MutableCounts): void {
|
|
991
|
-
const title = `${SECTION_LABELS[name].padEnd(9, ' ')} (
|
|
992
|
+
const title = `${SECTION_LABELS[name].padEnd(9, ' ')} (task workspace/${name}/):`;
|
|
992
993
|
lines.push(title);
|
|
993
994
|
|
|
994
995
|
const allEntries: Array<[MutableAction, string]> = [
|
|
@@ -1013,7 +1014,7 @@ function printSection(lines: string[], name: MutableSection, counts: MutableCoun
|
|
|
1013
1014
|
}
|
|
1014
1015
|
|
|
1015
1016
|
function printArchiveSection(lines: string[], counts: ArchiveCounts): void {
|
|
1016
|
-
const title = `${SECTION_LABELS.archive.padEnd(9, ' ')} (
|
|
1017
|
+
const title = `${SECTION_LABELS.archive.padEnd(9, ' ')} (task workspace/archive/):`;
|
|
1017
1018
|
lines.push(title);
|
|
1018
1019
|
|
|
1019
1020
|
if (counts.copied.length === 0 && counts.skipped.length === 0) {
|
|
@@ -1105,7 +1106,7 @@ async function cmdMerge(args: string[]): Promise<void> {
|
|
|
1105
1106
|
}
|
|
1106
1107
|
|
|
1107
1108
|
const repoRoot = process.cwd();
|
|
1108
|
-
const workspaceDir =
|
|
1109
|
+
const workspaceDir = resolveProjectTaskWorkspaceRoot(repoRoot);
|
|
1109
1110
|
const archiveDir = path.join(workspaceDir, 'archive');
|
|
1110
1111
|
const backupStamp = formatBackupTimestamp(new Date());
|
|
1111
1112
|
const projectKey = resolveRecoveryProjectKey(repoRoot);
|
|
@@ -429,12 +429,15 @@ function runMechanicalChangeReport(repoRoot: string, baseSha: string, headSha: s
|
|
|
429
429
|
return validated.value;
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
const DOCUMENTATION_CATEGORY = { label: '文档', prefixes: ['docs/'] } as const;
|
|
433
|
+
|
|
432
434
|
const CHANGE_CATEGORIES = [
|
|
433
435
|
{ label: '运行时代码', prefixes: ['bin/', 'lib/', 'src/', 'scripts/'] },
|
|
434
436
|
{ label: '测试与校验', prefixes: ['test/', 'tests/'] },
|
|
435
437
|
{ label: '模板与生成内容', prefixes: ['templates/'] },
|
|
436
438
|
{ label: '技能与协作配置', prefixes: ['.agents/'] },
|
|
437
|
-
|
|
439
|
+
DOCUMENTATION_CATEGORY,
|
|
440
|
+
{ label: '其他', prefixes: [] }
|
|
438
441
|
] as const;
|
|
439
442
|
|
|
440
443
|
function emptyChangeTotals(): ChangeTotals {
|
|
@@ -443,7 +446,10 @@ function emptyChangeTotals(): ChangeTotals {
|
|
|
443
446
|
|
|
444
447
|
function categoryForChangeFile(file: ChangeFile): (typeof CHANGE_CATEGORIES)[number] {
|
|
445
448
|
const filePath = file.newPath || file.oldPath || '';
|
|
446
|
-
|
|
449
|
+
const category = CHANGE_CATEGORIES.find((entry) => entry.prefixes.some((prefix) => prefix && filePath.startsWith(prefix)));
|
|
450
|
+
if (category) return category;
|
|
451
|
+
if (/\.(?:md|mdx|markdown|rst)$/i.test(filePath)) return DOCUMENTATION_CATEGORY;
|
|
452
|
+
return CHANGE_CATEGORIES[CHANGE_CATEGORIES.length - 1]!;
|
|
447
453
|
}
|
|
448
454
|
|
|
449
455
|
function summarizeChangeCategories(files: ChangeFile[]): Array<{ label: string; totals: ChangeTotals }> {
|
|
@@ -553,7 +559,7 @@ function renderEvidence(evidence: Evidence): string {
|
|
|
553
559
|
function renderPrechecks(checks: Precheck[]): string[] {
|
|
554
560
|
return checks.flatMap((check) => [
|
|
555
561
|
`- **${PRECHECK_LABELS[check.id]}(${check.id})**:${check.verdict === 'pass' ? '通过' : '需复核'}。${escapeReportText(check.rationale)}`,
|
|
556
|
-
...check.evidence.
|
|
562
|
+
...check.evidence.map(renderEvidence)
|
|
557
563
|
]);
|
|
558
564
|
}
|
|
559
565
|
|
|
@@ -5,7 +5,6 @@ import { createHash } from 'node:crypto';
|
|
|
5
5
|
import { enumerateArtifacts } from '../task/artifacts.ts';
|
|
6
6
|
import { parseTypedTaskFrontmatter } from '../task/frontmatter.ts';
|
|
7
7
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
8
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
9
8
|
import { readPrDeliveryFact } from '../task/pr-delivery-fact.ts';
|
|
10
9
|
import type { PrDeliveryFact } from '../task/pr-delivery-fact.ts';
|
|
11
10
|
import { resolvePlatformProviderContext } from './context.ts';
|
|
@@ -433,7 +432,7 @@ async function reportWrite(taskRef: string, options: ReportWriteOptions): Promis
|
|
|
433
432
|
if (!loaded.ok || !context.platform.repository || !['no-op', 'degraded'].includes(context.status)) return { ...context, report: null };
|
|
434
433
|
let knownPrNumber: number | null = null;
|
|
435
434
|
try {
|
|
436
|
-
return await
|
|
435
|
+
return await (async () => {
|
|
437
436
|
const { taskContent, boundFact, factError } = readBoundTaskSnapshot(resolved.taskMdPath);
|
|
438
437
|
if (factError) return {
|
|
439
438
|
...basePlatformResult('failed', context, resolved.taskId, null, { code: factError.code, message: factError.message, retryable: false }),
|
|
@@ -502,18 +501,15 @@ async function reportWrite(taskRef: string, options: ReportWriteOptions): Promis
|
|
|
502
501
|
operations: [{ name: 'change-report:write', status: 'applied', reasonCode: null }],
|
|
503
502
|
report: { ...reportInfo, status: 'written' }
|
|
504
503
|
};
|
|
505
|
-
});
|
|
504
|
+
})();
|
|
506
505
|
} catch (error) {
|
|
507
|
-
|
|
508
|
-
? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
|
|
509
|
-
: { code: 'PR_CHANGE_REPORT_FAILED', message: error instanceof Error ? error.message : String(error), retryable: false };
|
|
510
|
-
return { ...basePlatformResult(lockError.retryable ? 'blocked' : 'failed', context, resolved.taskId, knownPrNumber, lockError), report: null };
|
|
506
|
+
return { ...basePlatformResult('failed', context, resolved.taskId, knownPrNumber, { code: 'PR_CHANGE_REPORT_FAILED', message: error instanceof Error ? error.message : String(error), retryable: false }), report: null };
|
|
511
507
|
}
|
|
512
508
|
}
|
|
513
509
|
|
|
514
510
|
async function syncPullRequestSummary(
|
|
515
511
|
taskRef: string,
|
|
516
|
-
options: { agent: string; body: string; changeReportFile?: string; cwd?: string; client?: PlatformClient; dryRun?: boolean; strict?: boolean; primaryResult: PullRequestPrimaryResult; runtimeVersion?: string; manualValidation?: ManualValidationSummaryOptions;
|
|
512
|
+
options: { agent: string; body: string; changeReportFile?: string; cwd?: string; client?: PlatformClient; dryRun?: boolean; strict?: boolean; primaryResult: PullRequestPrimaryResult; runtimeVersion?: string; manualValidation?: ManualValidationSummaryOptions; skipQueue?: boolean }
|
|
517
513
|
): Promise<PullRequestSummaryResult> {
|
|
518
514
|
const warningResult = warningResultForPrimary(options.primaryResult);
|
|
519
515
|
let knownPrNumber: number | null = null;
|
|
@@ -561,7 +557,7 @@ async function syncPullRequestSummary(
|
|
|
561
557
|
const loaded = await resolvePlatformProviderContext({ cwd: resolved.repoRoot, client: options.client });
|
|
562
558
|
const context = loaded.ok ? loaded.value.context : loaded.context;
|
|
563
559
|
if (!loaded.ok || !context.platform.repository || !['no-op', 'degraded'].includes(context.status)) {
|
|
564
|
-
//
|
|
560
|
+
// Preserve the known PR target for diagnostics when provider context resolution fails.
|
|
565
561
|
knownPrNumber = boundPrNumberForWarning(resolved.taskMdPath);
|
|
566
562
|
return preserveFailure(context);
|
|
567
563
|
}
|
|
@@ -780,14 +776,9 @@ async function syncPullRequestSummary(
|
|
|
780
776
|
persistenceFailure: (error) => fail('failed', context, error, prNumber)
|
|
781
777
|
});
|
|
782
778
|
};
|
|
783
|
-
return await (
|
|
784
|
-
? execute()
|
|
785
|
-
: withTaskExecutionLock(resolved.repoRoot, resolved.taskId, options.agent, execute));
|
|
779
|
+
return await execute();
|
|
786
780
|
} catch (error) {
|
|
787
|
-
|
|
788
|
-
? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
|
|
789
|
-
: { code: 'PR_SUMMARY_FAILED', message: error instanceof Error ? error.message : String(error), retryable: false };
|
|
790
|
-
return fail(lockError.retryable ? 'blocked' : 'failed', context, lockError);
|
|
781
|
+
return fail('failed', context, { code: 'PR_SUMMARY_FAILED', message: error instanceof Error ? error.message : String(error), retryable: false });
|
|
791
782
|
}
|
|
792
783
|
}
|
|
793
784
|
|
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
import { platformResult } from './types.ts';
|
|
22
22
|
import type { PlatformOperation, PlatformResult } from './types.ts';
|
|
23
23
|
import { inspectCompletionArtifacts } from '../task/finalization-artifacts.ts';
|
|
24
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
25
24
|
import { resolveDeliveryTarget } from '../task/delivery-target.ts';
|
|
26
25
|
import { mergeOperationWarnings, type OperationWarning } from '../task/operation-outcome.ts';
|
|
27
26
|
import {
|
|
@@ -1174,20 +1173,8 @@ async function createPlatformPullRequestImpl(taskRef: string, options: CreateOpt
|
|
|
1174
1173
|
}), PRECONDITION_NOT_CREATED);
|
|
1175
1174
|
}
|
|
1176
1175
|
try {
|
|
1177
|
-
return
|
|
1178
|
-
base.resolved.repoRoot,
|
|
1179
|
-
base.resolved.taskId,
|
|
1180
|
-
'platform-pr.create',
|
|
1181
|
-
() => createExternalPullRequest(taskRef, options, base)
|
|
1182
|
-
);
|
|
1176
|
+
return await createExternalPullRequest(taskRef, options, base);
|
|
1183
1177
|
} catch (error) {
|
|
1184
|
-
if (error instanceof TaskExecutionLockError) {
|
|
1185
|
-
return withCreation(result('blocked', base.resolved.taskId, base.issueNumber, null, {
|
|
1186
|
-
platform: base.context.platform,
|
|
1187
|
-
capabilities: base.context.capabilities,
|
|
1188
|
-
error: { code: error.code, message: error.message, retryable: true }
|
|
1189
|
-
}), PRECONDITION_NOT_CREATED);
|
|
1190
|
-
}
|
|
1191
1178
|
return withCreation(result('failed', base.resolved.taskId, base.issueNumber, null, {
|
|
1192
1179
|
platform: base.context.platform,
|
|
1193
1180
|
capabilities: base.context.capabilities,
|
|
@@ -1602,7 +1589,7 @@ function readProjectPrFlow(repoRoot: string): 'required' | 'disabled' | undefine
|
|
|
1602
1589
|
}
|
|
1603
1590
|
}
|
|
1604
1591
|
|
|
1605
|
-
function
|
|
1592
|
+
function applySkippedPullRequestFact(
|
|
1606
1593
|
resolved: Extract<ReturnType<typeof resolveTaskRef>, { ok: true }>,
|
|
1607
1594
|
options: SkipFactOptions
|
|
1608
1595
|
): PullRequestResult {
|
|
@@ -1674,16 +1661,8 @@ async function skipPlatformPullRequestFact(taskRef: string, options: SkipFactOpt
|
|
|
1674
1661
|
error: { code: 'TASK_STATE_INVALID', message: 'platform-pr skip requires an active task', retryable: false }
|
|
1675
1662
|
});
|
|
1676
1663
|
try {
|
|
1677
|
-
return
|
|
1678
|
-
resolved.repoRoot,
|
|
1679
|
-
resolved.taskId,
|
|
1680
|
-
'platform-pr.skip',
|
|
1681
|
-
() => skipPlatformPullRequestFactUnlocked(resolved, options)
|
|
1682
|
-
);
|
|
1664
|
+
return await applySkippedPullRequestFact(resolved, options);
|
|
1683
1665
|
} catch (error) {
|
|
1684
|
-
if (error instanceof TaskExecutionLockError) return result('blocked', resolved.taskId, null, null, {
|
|
1685
|
-
error: { code: error.code, message: error.message, retryable: true }
|
|
1686
|
-
});
|
|
1687
1666
|
return result('failed', resolved.taskId, null, null, {
|
|
1688
1667
|
error: { code: 'PR_SKIP_FAILED', message: error instanceof Error ? error.message : String(error), retryable: false }
|
|
1689
1668
|
});
|
|
@@ -5,6 +5,7 @@ import { parseTypedTaskFrontmatter } from '../task/frontmatter.ts';
|
|
|
5
5
|
import { readPrDeliveryFact } from '../task/pr-delivery-fact.ts';
|
|
6
6
|
import { resourceIdentityEquals, resourceIdentityNumber } from '../platform/resource-identity.ts';
|
|
7
7
|
import type { ResourceIdentity } from '../platform/resource-identity.ts';
|
|
8
|
+
import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.ts';
|
|
8
9
|
import { taskIssueIdentity } from '../platform/task-identities.ts';
|
|
9
10
|
|
|
10
11
|
// ---------------------------------------------------------------------------
|
|
@@ -61,7 +62,7 @@ export function extractClosingIssueNumbers(body: string): number[] {
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
/**
|
|
64
|
-
* Scan
|
|
65
|
+
* Scan active project task workspace task.md files for tasks bound to the
|
|
65
66
|
* PR number or to one of the PR's closing issues. A task is emitted at most once;
|
|
66
67
|
* a verified fact identity hit takes priority over the issue-identity reverse lookup.
|
|
67
68
|
*/
|
|
@@ -71,7 +72,7 @@ export function collectHostCandidates(input: {
|
|
|
71
72
|
closingIssues: number[];
|
|
72
73
|
workspaceRoot: string;
|
|
73
74
|
}): HostCandidate[] {
|
|
74
|
-
const activeRoot = path.join(input.workspaceRoot, '
|
|
75
|
+
const activeRoot = path.join(resolveProjectTaskWorkspaceRoot(input.workspaceRoot), 'active');
|
|
75
76
|
const candidates: HostCandidate[] = [];
|
|
76
77
|
let entries: fs.Dirent[];
|
|
77
78
|
try {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
+
import os from 'node:os';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
|
|
4
5
|
import { detectRepoRoot } from '../task/resolve-ref.ts';
|
|
6
|
+
import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.ts';
|
|
5
7
|
import { acquireGitHubCheckpoint, commitGitHubCheckpoint, readGitHubCheckpoint, releaseGitHubCheckpoint } from './checkpoint.ts';
|
|
6
8
|
import { materializeJson, materializeSnapshot } from './materialize.ts';
|
|
7
9
|
import { normalizeResources } from './normalize.ts';
|
|
@@ -52,16 +54,26 @@ function parseArgs(args: string[], valueOptions: Set<string>, booleanOptions: Se
|
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
function dataRoot(repoRoot: string, requested?: string): string {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
let boundary = repoRoot;
|
|
58
|
+
let input = requested;
|
|
59
|
+
if (input === undefined) {
|
|
60
|
+
const config = JSON.parse(fs.readFileSync(path.join(repoRoot, '.agents', '.airc.json'), 'utf8')) as { project?: unknown };
|
|
61
|
+
if (typeof config.project !== 'string' || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(config.project)) {
|
|
62
|
+
throw new Error('.agents/.airc.json must contain a valid project name in its project field');
|
|
63
|
+
}
|
|
64
|
+
boundary = path.resolve(os.homedir());
|
|
65
|
+
input = path.join(boundary, '.agent-infra', 'data-store', config.project);
|
|
66
|
+
}
|
|
67
|
+
const resolved = path.resolve(repoRoot, input);
|
|
68
|
+
const workspace = resolveProjectTaskWorkspaceRoot(repoRoot);
|
|
59
69
|
const taskRoots = ['active', 'blocked', 'completed', 'archive'].map((state) => path.join(workspace, state));
|
|
60
70
|
if (resolved === workspace || taskRoots.some((taskRoot) => resolved === taskRoot || resolved.startsWith(`${taskRoot}${path.sep}`))) {
|
|
61
71
|
throw new Error('data root cannot be the workspace root or a task directory');
|
|
62
72
|
}
|
|
73
|
+
const relative = path.relative(repoRoot, resolved);
|
|
74
|
+
if (requested !== undefined && (!relative || relative.startsWith('..') || path.isAbsolute(relative))) throw new Error('data root must be inside the repository');
|
|
63
75
|
let current = resolved;
|
|
64
|
-
while (current !==
|
|
76
|
+
while (current !== boundary) {
|
|
65
77
|
if (fs.existsSync(current) && fs.lstatSync(current).isSymbolicLink()) throw new Error('data root cannot traverse a symlink');
|
|
66
78
|
current = path.dirname(current);
|
|
67
79
|
}
|
|
@@ -3,6 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
|
|
4
4
|
import { createGitHubClient } from '../platform/github-client.ts';
|
|
5
5
|
import { enumerateAllTaskDirs } from '../task/resolve-ref.ts';
|
|
6
|
+
import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.ts';
|
|
6
7
|
import { captureText, inspectPrivacy, redactExcerpt } from './privacy.ts';
|
|
7
8
|
import { canonicalJsonBytes, sha256 } from './store.ts';
|
|
8
9
|
|
|
@@ -157,6 +158,11 @@ function fetchRestCollection<T>(options: FetchRestCollectionOptions<T>): Process
|
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
function relativeIdentity(repoRoot: string, filePath: string): string {
|
|
161
|
+
const workspaceRoot = resolveProjectTaskWorkspaceRoot(repoRoot);
|
|
162
|
+
const taskRelative = path.relative(workspaceRoot, filePath);
|
|
163
|
+
if (taskRelative && !taskRelative.startsWith('..') && !path.isAbsolute(taskRelative)) {
|
|
164
|
+
return path.posix.join('task-workspace', taskRelative.split(path.sep).join('/'));
|
|
165
|
+
}
|
|
160
166
|
const relative = path.relative(repoRoot, filePath);
|
|
161
167
|
if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) throw new Error(`path escapes repository: ${filePath}`);
|
|
162
168
|
return relative.split(path.sep).join('/');
|
package/lib/run/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { loadServerConfig } from '../server/config.ts';
|
|
|
4
4
|
import { resolveSandboxTarget, type SandboxWorkspaceIdentity } from '../sandbox/workspace-identity.ts';
|
|
5
5
|
import { createRunId, runInSandbox, type SandboxRunMetadata } from '../sandbox/capture.ts';
|
|
6
6
|
import { loadShortIdByTaskId, normalizeShortIdInput } from '../task/short-id.ts';
|
|
7
|
+
import { resolveProjectTaskWorkspaceRoot } from '../task/workspace-root.ts';
|
|
7
8
|
import { buildTuiCommand, renderPrompt, selectTui } from './tui.ts';
|
|
8
9
|
import { getSkillRunSpec } from './skills.ts';
|
|
9
10
|
import { runHostCommand, type RunProcessResult } from './host.ts';
|
|
@@ -157,7 +158,7 @@ function readShortIdLength(repoRoot: string): number {
|
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
function readActiveShortIdRegistry(repoRoot: string): Record<string, string> {
|
|
160
|
-
const registryPath = path.join(repoRoot, '
|
|
161
|
+
const registryPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', '.short-ids.json');
|
|
161
162
|
try {
|
|
162
163
|
const data = JSON.parse(fs.readFileSync(registryPath, 'utf8'));
|
|
163
164
|
return data && typeof data === 'object' && data.ids && typeof data.ids === 'object' ? data.ids : {};
|
|
@@ -186,7 +187,7 @@ function resolveActiveTaskIdentity(taskRef: string, repoRoot: string): ActiveTas
|
|
|
186
187
|
}
|
|
187
188
|
|
|
188
189
|
if (!taskId) return null;
|
|
189
|
-
const taskDir = path.join(repoRoot, '
|
|
190
|
+
const taskDir = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', taskId);
|
|
190
191
|
if (!fs.existsSync(path.join(taskDir, 'task.md'))) return null;
|
|
191
192
|
return { taskId, taskDir, taskRef: resolvedTaskRef };
|
|
192
193
|
}
|
|
@@ -1454,7 +1454,7 @@ export async function create(
|
|
|
1454
1454
|
const completedTaskSource = target.workspace.mode === 'task-bound'
|
|
1455
1455
|
? prepareSandboxCompletedTaskMountSource(effectiveConfig.repoRoot, target.workspace.taskId)
|
|
1456
1456
|
: null;
|
|
1457
|
-
prepareSandboxWorkspaceMountTargets(
|
|
1457
|
+
prepareSandboxWorkspaceMountTargets(effectiveConfig.repoRoot);
|
|
1458
1458
|
if (previousCutoverSnapshot) {
|
|
1459
1459
|
assertSandboxControlCutoverSnapshot(previousCutoverSnapshot);
|
|
1460
1460
|
if (previousManifest) {
|
|
@@ -1603,6 +1603,10 @@ export async function create(
|
|
|
1603
1603
|
: []),
|
|
1604
1604
|
'--label',
|
|
1605
1605
|
`${sandboxRuntimeCapabilityLabel(effectiveConfig)}=${capabilityPlan.runtimeSignature}`,
|
|
1606
|
+
// Every task sandbox runs without seccomp and AppArmor filtering;
|
|
1607
|
+
// capabilities and namespace isolation remain unchanged.
|
|
1608
|
+
'--security-opt', 'seccomp=unconfined',
|
|
1609
|
+
'--security-opt', 'apparmor=unconfined',
|
|
1606
1610
|
...coreVolumes,
|
|
1607
1611
|
...buildClipboardVolumeArgs(engine, effectiveConfig.home),
|
|
1608
1612
|
...dotfilesMount,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
const USAGE = `Usage: ai sandbox exec [--recreate] <branch | TASK-id | N> [cmd...]
|
|
32
32
|
|
|
33
33
|
N references an active task short id from
|
|
34
|
-
|
|
34
|
+
the read-only task-workspace mount at /task-workspace/active/.short-ids.json. They resolve only via that
|
|
35
35
|
registry — they do not reference a container's row position in
|
|
36
36
|
'ai sandbox ls' output. --recreate rebuilds the matched container while
|
|
37
37
|
preserving its task or branch identity. The same token after the target is
|