@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
package/dist/lib/task/create.js
CHANGED
|
@@ -4,13 +4,13 @@ import os from 'node:os';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { isValidAgentInfraVersion, VERSION } from '../version.js';
|
|
6
6
|
import { loadShortIdByTaskId, mutateShortIdRegistry } from './short-id.js';
|
|
7
|
-
import { TaskExecutionLockError, withRepositoryMutationLock, withTaskExecutionLock } from './task-execution-lock.js';
|
|
8
7
|
import { readDeliveryDefaults, validateBaseRef, validateRemote } from './delivery-target.js';
|
|
9
8
|
import { buildUnboundFact, encodePrDeliveryFact } from './pr-delivery-fact.js';
|
|
10
9
|
import { CANDIDATE_COLUMNS, CONSTRAINT_COLUMNS, parseTaskQualification } from './qualification-audit.js';
|
|
11
10
|
import { enumerateAllTaskDirs } from './resolve-ref.js';
|
|
12
11
|
import { parseTaskFrontmatter } from './frontmatter.js';
|
|
13
12
|
import { AGENT_TOKEN_VALUES } from '../agent-clients/tokens.js';
|
|
13
|
+
import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
|
|
14
14
|
const TYPES = ['feature', 'bugfix', 'refactor', 'docs', 'chore'];
|
|
15
15
|
const PRIORITIES = ['Urgent', 'High', 'Medium', 'Low'];
|
|
16
16
|
const EFFORTS = ['High', 'Medium', 'Low'];
|
|
@@ -295,49 +295,6 @@ function ensureRealDirectory(directory, code) {
|
|
|
295
295
|
}
|
|
296
296
|
fs.mkdirSync(directory, { mode: 0o700 });
|
|
297
297
|
}
|
|
298
|
-
function createLockRoot(project) {
|
|
299
|
-
const root = path.join(os.homedir(), '.agent-infra');
|
|
300
|
-
const directories = [root, path.join(root, 'run'), path.join(root, 'run', project), path.join(root, 'run', project, 'task-create-locks')];
|
|
301
|
-
for (const directory of directories) {
|
|
302
|
-
if (fs.existsSync(directory)) {
|
|
303
|
-
assertRealDirectory(directory, 'TASK_CREATE_LOCK_FAILED');
|
|
304
|
-
continue;
|
|
305
|
-
}
|
|
306
|
-
try {
|
|
307
|
-
fs.mkdirSync(directory, { mode: 0o700 });
|
|
308
|
-
}
|
|
309
|
-
catch (error) {
|
|
310
|
-
if (error.code !== 'EEXIST')
|
|
311
|
-
throw error;
|
|
312
|
-
assertRealDirectory(directory, 'TASK_CREATE_LOCK_FAILED');
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
return directories.at(-1);
|
|
316
|
-
}
|
|
317
|
-
function withCreateLock(repoRoot, project, operation) {
|
|
318
|
-
const lockRoot = createLockRoot(project);
|
|
319
|
-
let callbackError;
|
|
320
|
-
try {
|
|
321
|
-
return withTaskExecutionLock(repoRoot, 'task-create', 'task-create', () => {
|
|
322
|
-
try {
|
|
323
|
-
return operation();
|
|
324
|
-
}
|
|
325
|
-
catch (error) {
|
|
326
|
-
callbackError = error;
|
|
327
|
-
throw error;
|
|
328
|
-
}
|
|
329
|
-
}, { lockRoot, identityScope: `task-create\0${project}` });
|
|
330
|
-
}
|
|
331
|
-
catch (error) {
|
|
332
|
-
if (callbackError !== undefined)
|
|
333
|
-
throw callbackError;
|
|
334
|
-
if (error instanceof TaskExecutionLockError && error.code === 'ORCHESTRATION_LOCK_BUSY') {
|
|
335
|
-
throw new Error('TASK_CREATE_LOCK_TIMEOUT');
|
|
336
|
-
}
|
|
337
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
338
|
-
throw new Error(`TASK_CREATE_LOCK_FAILED: ${message}`);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
298
|
function recoverPublishedTask(repoRoot, keyDigest, candidateDigest) {
|
|
342
299
|
for (const task of enumerateAllTaskDirs(repoRoot)) {
|
|
343
300
|
const taskMd = path.join(task.taskDir, 'task.md');
|
|
@@ -366,16 +323,24 @@ function createLocalTask(value, options) {
|
|
|
366
323
|
throw new Error('TASK_CREATE_VERSION_INVALID: agentInfraVersion must be a valid v-prefixed semver');
|
|
367
324
|
}
|
|
368
325
|
const repoRoot = fs.realpathSync.native(options.repoRoot);
|
|
369
|
-
const workspaceRoot =
|
|
326
|
+
const workspaceRoot = resolveProjectTaskWorkspaceRoot(repoRoot);
|
|
370
327
|
const activeRoot = path.join(workspaceRoot, 'active');
|
|
371
328
|
ensureRealDirectory(path.join(repoRoot, '.agents'), 'TASK_CREATE_WORKSPACE_INVALID');
|
|
329
|
+
const home = path.resolve(process.env.HOME || os.homedir());
|
|
330
|
+
const managedRoots = [path.join(home, '.agent-infra'), path.join(home, '.agent-infra', 'task-workspaces')];
|
|
331
|
+
for (const root of managedRoots) {
|
|
332
|
+
if (fs.existsSync(root))
|
|
333
|
+
assertRealDirectory(root, 'TASK_CREATE_WORKSPACE_INVALID');
|
|
334
|
+
else
|
|
335
|
+
fs.mkdirSync(root, { mode: 0o700 });
|
|
336
|
+
}
|
|
372
337
|
ensureRealDirectory(workspaceRoot, 'TASK_CREATE_WORKSPACE_INVALID');
|
|
373
338
|
ensureRealDirectory(activeRoot, 'TASK_CREATE_WORKSPACE_INVALID');
|
|
374
339
|
const projectConfig = readProject(repoRoot);
|
|
375
340
|
const canonical = canonicalTaskCreateCandidate(candidate);
|
|
376
341
|
const candidateDigest = sha256(canonical);
|
|
377
342
|
const keyDigest = sha256(candidate.idempotencyKey);
|
|
378
|
-
function
|
|
343
|
+
function createOnce() {
|
|
379
344
|
const recovered = recoverPublishedTask(repoRoot, keyDigest, candidateDigest);
|
|
380
345
|
if (recovered) {
|
|
381
346
|
return { status: 'no-op', changed: false, task: { id: recovered.taskId, shortId: recovered.shortId, state: recovered.state } };
|
|
@@ -407,25 +372,7 @@ function createLocalTask(value, options) {
|
|
|
407
372
|
throw new Error('TASK_CREATE_SHORT_ID_FAILED');
|
|
408
373
|
return { status: 'applied', changed: true, task: { id: taskId, shortId: allocated.shortId, state: 'active' } };
|
|
409
374
|
}
|
|
410
|
-
return
|
|
411
|
-
let callbackError;
|
|
412
|
-
try {
|
|
413
|
-
return withRepositoryMutationLock(repoRoot, () => {
|
|
414
|
-
try {
|
|
415
|
-
return createUnderRepositoryLock();
|
|
416
|
-
}
|
|
417
|
-
catch (error) {
|
|
418
|
-
callbackError = error;
|
|
419
|
-
throw error;
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
|
-
}
|
|
423
|
-
catch (error) {
|
|
424
|
-
if (callbackError !== undefined)
|
|
425
|
-
throw callbackError;
|
|
426
|
-
throw error;
|
|
427
|
-
}
|
|
428
|
-
});
|
|
375
|
+
return createOnce();
|
|
429
376
|
}
|
|
430
377
|
export { canonicalTaskCreateCandidate, createLocalTask, validateTaskCreateCandidate };
|
|
431
378
|
//# sourceMappingURL=create.js.map
|
|
@@ -195,7 +195,7 @@ function validateSealRequest(receipt, event) {
|
|
|
195
195
|
function validateReviewerSealPaths(receipt, changedPaths) {
|
|
196
196
|
if (receipt.role !== 'reviewer')
|
|
197
197
|
return null;
|
|
198
|
-
const taskRoot =
|
|
198
|
+
const taskRoot = `task-workspace/active/${receipt.taskId}/`;
|
|
199
199
|
const allowed = new Set([
|
|
200
200
|
`${taskRoot}${receipt.artifact}`,
|
|
201
201
|
`${taskRoot}task.md`,
|
|
@@ -5,7 +5,6 @@ import { parseTaskFrontmatter } from './frontmatter.js';
|
|
|
5
5
|
import { resolveTaskRef } from './resolve-ref.js';
|
|
6
6
|
import { resolveDeliveryTarget, validateBaseRef, validateRemote } from './delivery-target.js';
|
|
7
7
|
import { captureTaskWriteMetadata, writeTask } from './write.js';
|
|
8
|
-
import { withRepositoryMutationLock, withTaskExecutionLock } from './task-execution-lock.js';
|
|
9
8
|
function classifyDeliveryState(localHead, remoteHead, lastDelivered) {
|
|
10
9
|
if (remoteHead === null)
|
|
11
10
|
return { state: 'absent', shouldPush: true };
|
|
@@ -29,7 +28,7 @@ function validateBranch(cwd, branch) {
|
|
|
29
28
|
function failure(taskId, code, message, retryable = false, status = retryable ? 'blocked' : 'failed') {
|
|
30
29
|
return { status, changed: false, taskId, remoteHead: null, localHead: null, state: null, error: { code, message, retryable } };
|
|
31
30
|
}
|
|
32
|
-
function
|
|
31
|
+
function deliverTaskBranchCore(taskId, taskDir, repoRoot, options) {
|
|
33
32
|
let frontmatter;
|
|
34
33
|
try {
|
|
35
34
|
frontmatter = parseTaskFrontmatter(fs.readFileSync(path.join(taskDir, 'task.md'), 'utf8'));
|
|
@@ -100,12 +99,7 @@ function deliverTaskBranch(taskRef, options) {
|
|
|
100
99
|
const resolved = resolveTaskRef(taskRef, { repoRoot: options.repoRoot });
|
|
101
100
|
if (!resolved.ok)
|
|
102
101
|
return failure(resolved.taskId, resolved.code, resolved.message);
|
|
103
|
-
|
|
104
|
-
return withRepositoryMutationLock(resolved.repoRoot, () => withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-delivery', () => deliverUnlocked(resolved.taskId, resolved.taskDir, resolved.repoRoot, options)));
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
return failure(resolved.taskId, 'DELIVERY_LOCK_FAILED', error instanceof Error ? error.message : String(error), true, 'blocked');
|
|
108
|
-
}
|
|
102
|
+
return deliverTaskBranchCore(resolved.taskId, resolved.taskDir, resolved.repoRoot, options);
|
|
109
103
|
}
|
|
110
104
|
export { classifyDeliveryState, deliverTaskBranch };
|
|
111
105
|
//# sourceMappingURL=delivery.js.map
|
package/dist/lib/task/events.js
CHANGED
|
@@ -15,7 +15,6 @@ import { resolveTaskRef } from './resolve-ref.js';
|
|
|
15
15
|
import { findSectionHeading } from './sections.js';
|
|
16
16
|
import { validateLifecycleExecution } from './lifecycle-execution.js';
|
|
17
17
|
import { commitOrchestrationStageCompletion } from './orchestration.js';
|
|
18
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
|
|
19
18
|
import { captureTaskWriteMetadata, writeTask } from './write.js';
|
|
20
19
|
import { validateLocalArtifact } from './local-artifact-finalization.js';
|
|
21
20
|
import { buildLifecycleFacts, canStart, effectiveReworkTarget } from './capabilities.js';
|
|
@@ -456,11 +455,11 @@ function reworkIntentMutationForCompletion(content, taskDir, family, artifact, t
|
|
|
456
455
|
}
|
|
457
456
|
return { mutation: JSON.stringify(next) === JSON.stringify(parsed.intents) ? null : reworkIntentMutation(content, next) };
|
|
458
457
|
}
|
|
459
|
-
function buildCompletionReceipt(content, taskDir, family, artifact, completedAt, frontmatter, request) {
|
|
458
|
+
function buildCompletionReceipt(content, taskDir, repositoryRoot, family, artifact, completedAt, frontmatter, request) {
|
|
460
459
|
if (!['analyze', 'plan', 'code'].includes(family) && !family.startsWith('review-'))
|
|
461
460
|
return null;
|
|
462
461
|
if (family === 'review-code') {
|
|
463
|
-
const identity = inspectReviewIdentity(taskDir, fs.readFileSync(artifact.path, 'utf8'));
|
|
462
|
+
const identity = inspectReviewIdentity(taskDir, fs.readFileSync(artifact.path, 'utf8'), repositoryRoot);
|
|
464
463
|
if (identity.status !== 'matched')
|
|
465
464
|
return { ok: false, message: `review-code identity is ${identity.status}: ${identity.message}` };
|
|
466
465
|
}
|
|
@@ -566,7 +565,7 @@ function sameCompletionFact(left, right) {
|
|
|
566
565
|
function replaceCompletionFact(facts, next) {
|
|
567
566
|
return [...facts.filter((fact) => !(fact.event === next.event && fact.output === next.output)), next];
|
|
568
567
|
}
|
|
569
|
-
function
|
|
568
|
+
function applyTaskEvent(request, options = {}) {
|
|
570
569
|
const invalid = validateTaskEventRequest(request);
|
|
571
570
|
if (invalid)
|
|
572
571
|
return failed(request, invalid);
|
|
@@ -718,7 +717,7 @@ function applyTaskEventUnlocked(request, options = {}) {
|
|
|
718
717
|
}
|
|
719
718
|
if (eventIdentity.phase === 'started') {
|
|
720
719
|
const trigger = eventTrigger(normalized, eventIdentity.family);
|
|
721
|
-
const facts = buildLifecycleFacts(resolved.taskDir, content, resolved.state);
|
|
720
|
+
const facts = buildLifecycleFacts(resolved.taskDir, content, resolved.state, false, resolved.repoRoot);
|
|
722
721
|
if (!facts.ok)
|
|
723
722
|
return failed(normalized, { code: 'EVENT_TRANSITION_INVALID', message: `${facts.code}: ${facts.message}` }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
|
|
724
723
|
const capability = canStart(lifecycleAction(eventIdentity.family), facts.facts, trigger);
|
|
@@ -766,7 +765,7 @@ function applyTaskEventUnlocked(request, options = {}) {
|
|
|
766
765
|
let currentFact = null;
|
|
767
766
|
let completionRework = null;
|
|
768
767
|
if (eventIdentity.phase === 'completed' && completedArtifact) {
|
|
769
|
-
const receipt = buildCompletionReceipt(content, resolved.taskDir, eventIdentity.family, completedArtifact, metadata.timestamp, frontmatter, normalized);
|
|
768
|
+
const receipt = buildCompletionReceipt(content, resolved.taskDir, resolved.repoRoot, eventIdentity.family, completedArtifact, metadata.timestamp, frontmatter, normalized);
|
|
770
769
|
if (receipt && !receipt.ok) {
|
|
771
770
|
return failed(normalized, { code: 'EVENT_ARTIFACT_CONFLICT', message: receipt.message }, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath, fromStep: currentStep, toStep: currentStep, action: eventIdentity.action, phase: eventIdentity.phase });
|
|
772
771
|
}
|
|
@@ -938,31 +937,6 @@ function applyTaskEventUnlocked(request, options = {}) {
|
|
|
938
937
|
agentInfraVersion: result.agentInfraVersion, operations: result.operations, error: null
|
|
939
938
|
};
|
|
940
939
|
}
|
|
941
|
-
function applyTaskEvent(request, options = {}) {
|
|
942
|
-
const invalid = validateTaskEventRequest(request);
|
|
943
|
-
if (invalid)
|
|
944
|
-
return failed(request, invalid);
|
|
945
|
-
const parts = eventParts(request.event);
|
|
946
|
-
if (options.lockAlreadyHeld)
|
|
947
|
-
return applyTaskEventUnlocked(request, options);
|
|
948
|
-
if (request.dryRun || !['started', 'completed'].includes(parts.phase)) {
|
|
949
|
-
return applyTaskEventUnlocked(request, options);
|
|
950
|
-
}
|
|
951
|
-
const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
|
|
952
|
-
if (!resolved.ok)
|
|
953
|
-
return applyTaskEventUnlocked(request, options);
|
|
954
|
-
try {
|
|
955
|
-
return withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, () => applyTaskEventUnlocked(request, { ...options, lockAlreadyHeld: true }));
|
|
956
|
-
}
|
|
957
|
-
catch (error) {
|
|
958
|
-
if (!(error instanceof TaskExecutionLockError))
|
|
959
|
-
throw error;
|
|
960
|
-
return failed(request, {
|
|
961
|
-
code: 'EVENT_TRANSITION_INVALID',
|
|
962
|
-
message: `${error.code}: ${error.message}`
|
|
963
|
-
}, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
940
|
function successNoOp(request, taskId, taskMdPath, currentStep, eventIdentity, timestamp, frontmatter, artifactContext) {
|
|
967
941
|
return {
|
|
968
942
|
...failed(request, { code: 'EVENT_LOG_CONFLICT', message: '' }), status: 'no-op', error: null,
|
|
@@ -9,10 +9,9 @@ import { inspectPlatformIssue, syncPlatformIssue } from '../platform/issues.js';
|
|
|
9
9
|
import { resourceIdentityEquals } from '../platform/resource-identity.js';
|
|
10
10
|
import { parseTaskFrontmatter } from './frontmatter.js';
|
|
11
11
|
import { recoverPlatformOperations } from './platform-operation-recovery.js';
|
|
12
|
-
import { applyTaskLifecycle,
|
|
12
|
+
import { applyTaskLifecycle, inspectTaskLifecycleProgress, previewTaskCompletion } from './lifecycle.js';
|
|
13
13
|
import { enumerateAllTaskDirs, resolveTaskRef } from './resolve-ref.js';
|
|
14
14
|
import { inspectShortIdRegistry } from './short-id.js';
|
|
15
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
|
|
16
15
|
import { verifyTaskEvent } from './verification.js';
|
|
17
16
|
import { projectFinalizationWarning } from './workflow-warning-intents.js';
|
|
18
17
|
import { mergeOperationWarnings } from './operation-outcome.js';
|
|
@@ -442,7 +441,7 @@ function mutationPatch(current, mutation) {
|
|
|
442
441
|
? { warningProjection: 'done', lastError: null }
|
|
443
442
|
: { warningProjection: 'pending', lastError: mutation.error };
|
|
444
443
|
}
|
|
445
|
-
function
|
|
444
|
+
function mutateFinalizationReceipt(repoRoot, receipt, capability, mutation, consumed) {
|
|
446
445
|
if (!hasFinalizationTaskDocument(repoRoot, receipt.taskId)) {
|
|
447
446
|
throw capabilityError('FINALIZATION_SCOPE_INVALID', 'finalization capability requires an active task or a completed task');
|
|
448
447
|
}
|
|
@@ -459,7 +458,7 @@ function applyFinalizationReceiptMutation(repoRoot, receipt, capability, mutatio
|
|
|
459
458
|
if (!hasFinalizationTaskDocument(repoRoot, receipt.taskId)) {
|
|
460
459
|
throw capabilityError('FINALIZATION_SCOPE_INVALID', 'finalization capability requires an active task or a completed task');
|
|
461
460
|
}
|
|
462
|
-
return
|
|
461
|
+
return mutateFinalizationReceipt(repoRoot, receipt, capability, mutation, new Set());
|
|
463
462
|
}
|
|
464
463
|
function warningKey(warning) {
|
|
465
464
|
return `${warning.step}\0${warning.code}\0${warning.target}`;
|
|
@@ -479,14 +478,14 @@ function reconcileWarningProjection(repoRoot, taskId, receipt, consumed) {
|
|
|
479
478
|
retryable: true
|
|
480
479
|
};
|
|
481
480
|
const capability = issueCapability(receipt, 'warning-projection');
|
|
482
|
-
return
|
|
481
|
+
return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'failed', error: detail }, consumed);
|
|
483
482
|
}
|
|
484
483
|
}
|
|
485
484
|
catch (error) {
|
|
486
485
|
const detail = errorOf(error, 'FINALIZATION_WARNING_PROJECTION_FAILED', true);
|
|
487
486
|
try {
|
|
488
487
|
const capability = issueCapability(receipt, 'warning-projection');
|
|
489
|
-
return
|
|
488
|
+
return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'failed', error: detail }, consumed);
|
|
490
489
|
}
|
|
491
490
|
catch {
|
|
492
491
|
return receipt;
|
|
@@ -495,7 +494,7 @@ function reconcileWarningProjection(repoRoot, taskId, receipt, consumed) {
|
|
|
495
494
|
}
|
|
496
495
|
try {
|
|
497
496
|
const capability = issueCapability(receipt, 'warning-projection');
|
|
498
|
-
return
|
|
497
|
+
return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'succeeded' }, consumed);
|
|
499
498
|
}
|
|
500
499
|
catch {
|
|
501
500
|
return receipt;
|
|
@@ -526,7 +525,7 @@ async function syncPendingTaskComment(input) {
|
|
|
526
525
|
if (result.status === 'applied' || result.status === 'no-op') {
|
|
527
526
|
const skipped = result.error?.code === 'ISSUE_NOT_LINKED';
|
|
528
527
|
const capability = issueCapability(receipt, 'task-comment');
|
|
529
|
-
receipt =
|
|
528
|
+
receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
|
|
530
529
|
scope: 'task-comment', operation: 'succeeded', state: skipped ? 'skipped' : 'done'
|
|
531
530
|
}, consumedCapabilities);
|
|
532
531
|
receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
|
|
@@ -542,7 +541,7 @@ async function syncPendingTaskComment(input) {
|
|
|
542
541
|
}
|
|
543
542
|
const detail = step.error ?? { code: 'COMMENT_SYNC_FAILED', message: 'task comment synchronization failed', retryable: true };
|
|
544
543
|
const capability = issueCapability(receipt, 'task-comment');
|
|
545
|
-
receipt =
|
|
544
|
+
receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
|
|
546
545
|
scope: 'task-comment', operation: 'failed', error: detail
|
|
547
546
|
}, consumedCapabilities);
|
|
548
547
|
receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
|
|
@@ -552,7 +551,7 @@ async function syncPendingTaskComment(input) {
|
|
|
552
551
|
const detail = errorOf(error, 'COMMENT_SYNC_FAILED', true);
|
|
553
552
|
try {
|
|
554
553
|
const capability = issueCapability(receipt, 'task-comment');
|
|
555
|
-
receipt =
|
|
554
|
+
receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
|
|
556
555
|
scope: 'task-comment', operation: 'failed', error: detail
|
|
557
556
|
}, consumedCapabilities);
|
|
558
557
|
receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
|
|
@@ -682,9 +681,9 @@ function preparedResult(taskId, receipt, steps, changed) {
|
|
|
682
681
|
result: 'prepared', warnings: openWarnings(receipt), error: null
|
|
683
682
|
};
|
|
684
683
|
}
|
|
685
|
-
async function
|
|
684
|
+
async function prepareTaskFinalizationCore(request, taskId, options) {
|
|
686
685
|
const repoRoot = path.resolve(options.repoRoot);
|
|
687
|
-
const lifecycle = options.lifecycle ?? ((lifecycleRequest, lifecycleOptions) => (
|
|
686
|
+
const lifecycle = options.lifecycle ?? ((lifecycleRequest, lifecycleOptions) => (applyTaskLifecycle(lifecycleRequest, lifecycleOptions ?? { repoRoot })));
|
|
688
687
|
const backfill = options.backfill ?? backfillCompletionComments;
|
|
689
688
|
const commentSync = options.commentSync ?? syncPlatformComment;
|
|
690
689
|
const issueSync = options.issueSync ?? syncPlatformIssue;
|
|
@@ -966,12 +965,10 @@ async function prepareTaskFinalization(request, options) {
|
|
|
966
965
|
if (!resolved.ok)
|
|
967
966
|
return failed(resolved.taskId, { code: resolved.code, message: resolved.message, retryable: false });
|
|
968
967
|
try {
|
|
969
|
-
return await
|
|
968
|
+
return await prepareTaskFinalizationCore(request, resolved.taskId, options);
|
|
970
969
|
}
|
|
971
970
|
catch (error) {
|
|
972
|
-
const detail = error
|
|
973
|
-
? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
|
|
974
|
-
: errorOf(error, 'TASK_FINALIZATION_FAILED');
|
|
971
|
+
const detail = errorOf(error, 'TASK_FINALIZATION_FAILED');
|
|
975
972
|
return failed(resolved.taskId, detail);
|
|
976
973
|
}
|
|
977
974
|
}
|
|
@@ -984,7 +981,7 @@ async function commitPreparedTaskFinalization(request, options) {
|
|
|
984
981
|
if (!resolved.ok)
|
|
985
982
|
return failed(resolved.taskId, { code: resolved.code, message: resolved.message, retryable: false });
|
|
986
983
|
try {
|
|
987
|
-
return await
|
|
984
|
+
return await (async () => {
|
|
988
985
|
if (options.controlBinding && options.manifestPath) {
|
|
989
986
|
try {
|
|
990
987
|
const manifest = readSandboxControlManifest(options.manifestPath);
|
|
@@ -1051,7 +1048,7 @@ async function commitPreparedTaskFinalization(request, options) {
|
|
|
1051
1048
|
};
|
|
1052
1049
|
const result = options.lifecycle
|
|
1053
1050
|
? options.lifecycle(lifecycleRequest, lifecycleOptions)
|
|
1054
|
-
:
|
|
1051
|
+
: applyTaskLifecycle(lifecycleRequest, lifecycleOptions);
|
|
1055
1052
|
const step = lifecycleStep(result);
|
|
1056
1053
|
if (result.status !== 'applied' && result.status !== 'no-op') {
|
|
1057
1054
|
const updated = updateReceipt(repoRoot, receipt, { lifecycle: 'pending', lastError: step.error });
|
|
@@ -1131,12 +1128,10 @@ async function commitPreparedTaskFinalization(request, options) {
|
|
|
1131
1128
|
});
|
|
1132
1129
|
}
|
|
1133
1130
|
return terminalResult(resolved.taskId, updated, { lifecycle: step, verification }, result.changed, detail);
|
|
1134
|
-
});
|
|
1131
|
+
})();
|
|
1135
1132
|
}
|
|
1136
1133
|
catch (error) {
|
|
1137
|
-
const detail = error
|
|
1138
|
-
? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
|
|
1139
|
-
: errorOf(error, 'TASK_FINALIZATION_FAILED');
|
|
1134
|
+
const detail = errorOf(error, 'TASK_FINALIZATION_FAILED');
|
|
1140
1135
|
return failed(resolved.taskId, detail);
|
|
1141
1136
|
}
|
|
1142
1137
|
}
|
|
@@ -13,7 +13,7 @@ import { validateCurrentTaskContract } from './current-contract.js';
|
|
|
13
13
|
import { isValidAgentInfraVersion } from '../version.js';
|
|
14
14
|
import { taskIssueIdentity } from '../platform/task-identities.js';
|
|
15
15
|
import { resourceIdentityEquals } from '../platform/resource-identity.js';
|
|
16
|
-
import {
|
|
16
|
+
import { resolveProjectTaskWorkspaceRoot } from './workspace-root.js';
|
|
17
17
|
const lifecycleIntentCatalog = [
|
|
18
18
|
'block', 'activate', 'cancel', 'complete', 'close-codescan', 'close-dependabot', 'restore', 'recover-started'
|
|
19
19
|
];
|
|
@@ -61,7 +61,7 @@ const DEFAULT_IO = {
|
|
|
61
61
|
};
|
|
62
62
|
function isVirtiofsMountPoint(directory, mountInfo) {
|
|
63
63
|
const decodeMountInfoPath = (value) => value.replace(/\\([0-7]{3})/gu, (_match, octal) => String.fromCharCode(Number.parseInt(octal, 8)));
|
|
64
|
-
const expected =
|
|
64
|
+
const expected = fs.realpathSync.native(directory);
|
|
65
65
|
return mountInfo.split('\n').some((line) => {
|
|
66
66
|
if (!line)
|
|
67
67
|
return false;
|
|
@@ -371,7 +371,7 @@ function validateRestoreStaging(request, repoRoot, taskId) {
|
|
|
371
371
|
let workspace;
|
|
372
372
|
let stagingDir;
|
|
373
373
|
try {
|
|
374
|
-
workspace = fs.realpathSync.native(
|
|
374
|
+
workspace = fs.realpathSync.native(resolveProjectTaskWorkspaceRoot(repoRoot));
|
|
375
375
|
stagingDir = fs.realpathSync.native(path.resolve(request.stagingDir));
|
|
376
376
|
}
|
|
377
377
|
catch (error) {
|
|
@@ -379,7 +379,7 @@ function validateRestoreStaging(request, repoRoot, taskId) {
|
|
|
379
379
|
}
|
|
380
380
|
const relative = path.relative(workspace, stagingDir);
|
|
381
381
|
if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative) || path.basename(stagingDir) === taskId) {
|
|
382
|
-
return { code: 'LIFECYCLE_STAGING_INVALID', message: 'restore staging must be a non-final directory inside
|
|
382
|
+
return { code: 'LIFECYCLE_STAGING_INVALID', message: 'restore staging must be a non-final directory inside the project task workspace' };
|
|
383
383
|
}
|
|
384
384
|
let entries;
|
|
385
385
|
try {
|
|
@@ -594,7 +594,7 @@ export function inspectTaskLifecycleProgress(repoRoot, taskId, agent) {
|
|
|
594
594
|
return 'unknown';
|
|
595
595
|
}
|
|
596
596
|
}
|
|
597
|
-
function
|
|
597
|
+
function applyTaskLifecycle(requestInput, options = {}) {
|
|
598
598
|
if (requestInput.intent === 'recover-started') {
|
|
599
599
|
return failed(requestInput, { code: 'LIFECYCLE_RECOVERY_REQUIRES_AUTHORITY', message: 'recover-started must be dispatched through task control authority' });
|
|
600
600
|
}
|
|
@@ -649,7 +649,7 @@ function applyTaskLifecycleUnlocked(requestInput, options = {}) {
|
|
|
649
649
|
else {
|
|
650
650
|
return failed(request, { code: 'LIFECYCLE_TASK_NOT_FOUND', message: `task ${taskId} has no lifecycle source` }, { taskId });
|
|
651
651
|
}
|
|
652
|
-
const targetPath = path.join(repoRoot,
|
|
652
|
+
const targetPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), spec.target, taskId);
|
|
653
653
|
const requiredSteps = stepsForIntent(request.intent);
|
|
654
654
|
const movingTaskDirectory = sourcePath !== targetPath;
|
|
655
655
|
const currentTaskFile = path.join(sourcePath, 'task.md');
|
|
@@ -695,7 +695,7 @@ function applyTaskLifecycleUnlocked(requestInput, options = {}) {
|
|
|
695
695
|
return failed(request, { code: 'LIFECYCLE_DOCUMENT_INVALID', message: contract.message }, { taskId, sourceState, targetState: spec.target, sourcePath, targetPath });
|
|
696
696
|
}
|
|
697
697
|
const registryRequest = executeShortIdCommand({
|
|
698
|
-
operation: 'list', activeDir: path.join(repoRoot, '
|
|
698
|
+
operation: 'list', activeDir: path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active'),
|
|
699
699
|
shortIdLength: configuredShortIdLength(repoRoot)
|
|
700
700
|
});
|
|
701
701
|
if (registryRequest.status === 'failed') {
|
|
@@ -905,7 +905,7 @@ function applyTaskLifecycleUnlocked(requestInput, options = {}) {
|
|
|
905
905
|
}
|
|
906
906
|
}
|
|
907
907
|
}
|
|
908
|
-
const activeTaskPath = path.join(repoRoot, '
|
|
908
|
+
const activeTaskPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', taskId);
|
|
909
909
|
if (request.intent === 'complete' && fs.existsSync(activeTaskPath)) {
|
|
910
910
|
try {
|
|
911
911
|
let sourceIsVirtiofsMount = false;
|
|
@@ -967,44 +967,5 @@ function applyTaskLifecycleUnlocked(requestInput, options = {}) {
|
|
|
967
967
|
journalPath, completedSteps: [...completed], pendingSteps: []
|
|
968
968
|
};
|
|
969
969
|
}
|
|
970
|
-
|
|
971
|
-
const normalized = normalizedRequest(request);
|
|
972
|
-
if ('code' in normalized)
|
|
973
|
-
return applyTaskLifecycleUnlocked(request, options);
|
|
974
|
-
const repoRoot = path.resolve(options.repoRoot ?? process.cwd());
|
|
975
|
-
const taskId = normalized.intent === 'restore'
|
|
976
|
-
? normalized.taskRef
|
|
977
|
-
: (() => {
|
|
978
|
-
const resolved = resolveTaskRef(normalized.taskRef, { repoRoot });
|
|
979
|
-
return resolved.ok ? resolved.taskId : null;
|
|
980
|
-
})();
|
|
981
|
-
if (!taskId)
|
|
982
|
-
return applyTaskLifecycleUnlocked(request, options);
|
|
983
|
-
try {
|
|
984
|
-
return withTaskExecutionLock(repoRoot, taskId, 'task-lifecycle.move', () => applyTaskLifecycleUnlocked(request, options));
|
|
985
|
-
}
|
|
986
|
-
catch (error) {
|
|
987
|
-
if (error instanceof TaskExecutionLockError) {
|
|
988
|
-
return failed(request, { code: error.code, message: error.message }, { taskId });
|
|
989
|
-
}
|
|
990
|
-
throw error;
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
function applyTaskLifecycleWithinTaskLock(request, options, lockedTaskId) {
|
|
994
|
-
const normalized = normalizedRequest(request);
|
|
995
|
-
if ('code' in normalized)
|
|
996
|
-
return failed(request, normalized);
|
|
997
|
-
const repoRoot = path.resolve(options.repoRoot ?? process.cwd());
|
|
998
|
-
const resolved = normalized.intent === 'restore'
|
|
999
|
-
? { ok: true, taskId: normalized.taskRef }
|
|
1000
|
-
: resolveTaskRef(normalized.taskRef, { repoRoot });
|
|
1001
|
-
if (!resolved.ok || resolved.taskId !== lockedTaskId) {
|
|
1002
|
-
return failed(request, {
|
|
1003
|
-
code: 'LIFECYCLE_LOCK_SCOPE_MISMATCH',
|
|
1004
|
-
message: 'task lifecycle request does not match the held task lock'
|
|
1005
|
-
}, { taskId: resolved.ok ? resolved.taskId : resolved.taskId });
|
|
1006
|
-
}
|
|
1007
|
-
return applyTaskLifecycleUnlocked(request, options);
|
|
1008
|
-
}
|
|
1009
|
-
export { lifecycleIntentCatalog, lifecycleFailureCatalog, lifecycleProducerCatalog, applyTaskLifecycle, applyTaskLifecycleWithinTaskLock, previewTaskCompletion };
|
|
970
|
+
export { lifecycleIntentCatalog, lifecycleFailureCatalog, lifecycleProducerCatalog, applyTaskLifecycle, previewTaskCompletion };
|
|
1010
971
|
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -110,8 +110,7 @@ function prepareLocalArtifact(request, candidate) {
|
|
|
110
110
|
return {
|
|
111
111
|
result: validation.ok && !qualificationError ? { ...result, status: 'passed', error: null } : result,
|
|
112
112
|
content,
|
|
113
|
-
repoRoot: resolved.repoRoot
|
|
114
|
-
lockAlreadyHeld: request.lockAlreadyHeld
|
|
113
|
+
repoRoot: resolved.repoRoot
|
|
115
114
|
};
|
|
116
115
|
}
|
|
117
116
|
function commitLocalArtifactProvenance(prepared) {
|