@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
package/lib/task/events.ts
CHANGED
|
@@ -31,7 +31,6 @@ import { findSectionHeading } from './sections.ts';
|
|
|
31
31
|
import { validateLifecycleExecution } from './lifecycle-execution.ts';
|
|
32
32
|
import { commitOrchestrationStageCompletion } from './orchestration.ts';
|
|
33
33
|
import type { OrchestrationStageCompletion } from './orchestration.ts';
|
|
34
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.ts';
|
|
35
34
|
import { captureTaskWriteMetadata, writeTask } from './write.ts';
|
|
36
35
|
import type { TaskOperationSummary, TaskWriteErrorCode, TaskWriteOptions } from './write.ts';
|
|
37
36
|
import { validateLocalArtifact } from './local-artifact-finalization.ts';
|
|
@@ -86,7 +85,6 @@ type TaskEventRequest = {
|
|
|
86
85
|
type TaskEventError = { code: TaskEventErrorCode; message: string };
|
|
87
86
|
type TaskEventOptions = TaskWriteOptions & {
|
|
88
87
|
commitOrchestrationCompletion?: (plan: OrchestrationStageCompletion) => void;
|
|
89
|
-
lockAlreadyHeld?: boolean;
|
|
90
88
|
};
|
|
91
89
|
type TaskEventResult = {
|
|
92
90
|
status: 'planned' | 'applied' | 'no-op' | 'failed'; changed: boolean;
|
|
@@ -519,6 +517,7 @@ function reworkIntentMutationForCompletion(
|
|
|
519
517
|
function buildCompletionReceipt(
|
|
520
518
|
content: string,
|
|
521
519
|
taskDir: string,
|
|
520
|
+
repositoryRoot: string | undefined,
|
|
522
521
|
family: EventFamily,
|
|
523
522
|
artifact: ArtifactIdentity,
|
|
524
523
|
completedAt: string,
|
|
@@ -527,7 +526,7 @@ function buildCompletionReceipt(
|
|
|
527
526
|
): { ok: true; receipts: readonly ArtifactReceipt[] } | { ok: false; message: string } | null {
|
|
528
527
|
if (!['analyze', 'plan', 'code'].includes(family) && !family.startsWith('review-')) return null;
|
|
529
528
|
if (family === 'review-code') {
|
|
530
|
-
const identity = inspectReviewIdentity(taskDir, fs.readFileSync(artifact.path, 'utf8'));
|
|
529
|
+
const identity = inspectReviewIdentity(taskDir, fs.readFileSync(artifact.path, 'utf8'), repositoryRoot);
|
|
531
530
|
if (identity.status !== 'matched') return { ok: false, message: `review-code identity is ${identity.status}: ${identity.message}` };
|
|
532
531
|
}
|
|
533
532
|
const event = family === 'analyze' ? 'analysis.completed'
|
|
@@ -627,7 +626,7 @@ function replaceCompletionFact(facts: readonly CompletionFact[], next: Completio
|
|
|
627
626
|
return [...facts.filter((fact) => !(fact.event === next.event && fact.output === next.output)), next];
|
|
628
627
|
}
|
|
629
628
|
|
|
630
|
-
function
|
|
629
|
+
function applyTaskEvent(request: TaskEventRequest, options: TaskEventOptions = {}): TaskEventResult {
|
|
631
630
|
const invalid = validateTaskEventRequest(request);
|
|
632
631
|
if (invalid) return failed(request, invalid);
|
|
633
632
|
const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
|
|
@@ -757,7 +756,7 @@ function applyTaskEventUnlocked(request: TaskEventRequest, options: TaskEventOpt
|
|
|
757
756
|
}
|
|
758
757
|
if (eventIdentity.phase === 'started') {
|
|
759
758
|
const trigger = eventTrigger(normalized, eventIdentity.family);
|
|
760
|
-
const facts = buildLifecycleFacts(resolved.taskDir, content, resolved.state);
|
|
759
|
+
const facts = buildLifecycleFacts(resolved.taskDir, content, resolved.state, false, resolved.repoRoot);
|
|
761
760
|
if (!facts.ok) 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 });
|
|
762
761
|
const capability = canStart(lifecycleAction(eventIdentity.family), facts.facts, trigger);
|
|
763
762
|
const safetyFailure = capability.reasonCode === 'TASK_NOT_ACTIVE'
|
|
@@ -804,7 +803,7 @@ function applyTaskEventUnlocked(request: TaskEventRequest, options: TaskEventOpt
|
|
|
804
803
|
let currentFact: CompletionFact | null = null;
|
|
805
804
|
let completionRework: ReturnType<typeof reworkIntentMutation> | null = null;
|
|
806
805
|
if (eventIdentity.phase === 'completed' && completedArtifact) {
|
|
807
|
-
const receipt = buildCompletionReceipt(content, resolved.taskDir, eventIdentity.family, completedArtifact, metadata.timestamp, frontmatter, normalized);
|
|
806
|
+
const receipt = buildCompletionReceipt(content, resolved.taskDir, resolved.repoRoot, eventIdentity.family, completedArtifact, metadata.timestamp, frontmatter, normalized);
|
|
808
807
|
if (receipt && !receipt.ok) {
|
|
809
808
|
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 });
|
|
810
809
|
}
|
|
@@ -978,32 +977,6 @@ function applyTaskEventUnlocked(request: TaskEventRequest, options: TaskEventOpt
|
|
|
978
977
|
};
|
|
979
978
|
}
|
|
980
979
|
|
|
981
|
-
function applyTaskEvent(request: TaskEventRequest, options: TaskEventOptions = {}): TaskEventResult {
|
|
982
|
-
const invalid = validateTaskEventRequest(request);
|
|
983
|
-
if (invalid) return failed(request, invalid);
|
|
984
|
-
const parts = eventParts(request.event);
|
|
985
|
-
if (options.lockAlreadyHeld) return applyTaskEventUnlocked(request, options);
|
|
986
|
-
if (request.dryRun || !['started', 'completed'].includes(parts.phase)) {
|
|
987
|
-
return applyTaskEventUnlocked(request, options);
|
|
988
|
-
}
|
|
989
|
-
const resolved = resolveTaskRef(request.taskRef, { repoRoot: options.repoRoot });
|
|
990
|
-
if (!resolved.ok) return applyTaskEventUnlocked(request, options);
|
|
991
|
-
try {
|
|
992
|
-
return withTaskExecutionLock(
|
|
993
|
-
resolved.repoRoot,
|
|
994
|
-
resolved.taskId,
|
|
995
|
-
`task-event.${request.event}`,
|
|
996
|
-
() => applyTaskEventUnlocked(request, { ...options, lockAlreadyHeld: true })
|
|
997
|
-
);
|
|
998
|
-
} catch (error) {
|
|
999
|
-
if (!(error instanceof TaskExecutionLockError)) throw error;
|
|
1000
|
-
return failed(request, {
|
|
1001
|
-
code: 'EVENT_TRANSITION_INVALID',
|
|
1002
|
-
message: `${error.code}: ${error.message}`
|
|
1003
|
-
}, { taskId: resolved.taskId, taskMdPath: resolved.taskMdPath });
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
980
|
function successNoOp(
|
|
1008
981
|
request: TaskEventRequest, taskId: string, taskMdPath: string, currentStep: string,
|
|
1009
982
|
eventIdentity: ReturnType<typeof identity>, timestamp: string,
|
package/lib/task/finalization.ts
CHANGED
|
@@ -14,7 +14,6 @@ import { parseTaskFrontmatter } from './frontmatter.ts';
|
|
|
14
14
|
import { recoverPlatformOperations } from './platform-operation-recovery.ts';
|
|
15
15
|
import {
|
|
16
16
|
applyTaskLifecycle,
|
|
17
|
-
applyTaskLifecycleWithinTaskLock,
|
|
18
17
|
inspectTaskLifecycleProgress,
|
|
19
18
|
type TaskLifecycleOptions,
|
|
20
19
|
type TaskLifecycleRequest,
|
|
@@ -24,7 +23,6 @@ import {
|
|
|
24
23
|
} from './lifecycle.ts';
|
|
25
24
|
import { enumerateAllTaskDirs, resolveTaskRef } from './resolve-ref.ts';
|
|
26
25
|
import { inspectShortIdRegistry } from './short-id.ts';
|
|
27
|
-
import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.ts';
|
|
28
26
|
import { verifyTaskEvent } from './verification.ts';
|
|
29
27
|
import type { TaskVerificationResult } from './verification.ts';
|
|
30
28
|
import { projectFinalizationWarning } from './workflow-warning-intents.ts';
|
|
@@ -586,7 +584,7 @@ function mutationPatch(current: TaskFinalizationReceipt, mutation: FinalizationM
|
|
|
586
584
|
: { warningProjection: 'pending', lastError: mutation.error };
|
|
587
585
|
}
|
|
588
586
|
|
|
589
|
-
function
|
|
587
|
+
function mutateFinalizationReceipt(
|
|
590
588
|
repoRoot: string,
|
|
591
589
|
receipt: TaskFinalizationReceipt,
|
|
592
590
|
capability: FinalizationCapability,
|
|
@@ -615,9 +613,7 @@ function applyFinalizationReceiptMutation(
|
|
|
615
613
|
if (!hasFinalizationTaskDocument(repoRoot, receipt.taskId)) {
|
|
616
614
|
throw capabilityError('FINALIZATION_SCOPE_INVALID', 'finalization capability requires an active task or a completed task');
|
|
617
615
|
}
|
|
618
|
-
return
|
|
619
|
-
applyFinalizationReceiptMutationUnderLock(repoRoot, receipt, capability, mutation, new Set<string>())
|
|
620
|
-
);
|
|
616
|
+
return mutateFinalizationReceipt(repoRoot, receipt, capability, mutation, new Set<string>());
|
|
621
617
|
}
|
|
622
618
|
|
|
623
619
|
function warningKey(warning: Pick<FinalizationWarning, 'step' | 'code' | 'target'>): string {
|
|
@@ -640,20 +636,20 @@ function reconcileWarningProjection(repoRoot: string, taskId: string, receipt: T
|
|
|
640
636
|
retryable: true
|
|
641
637
|
};
|
|
642
638
|
const capability = issueCapability(receipt, 'warning-projection');
|
|
643
|
-
return
|
|
639
|
+
return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'failed', error: detail }, consumed);
|
|
644
640
|
}
|
|
645
641
|
} catch (error) {
|
|
646
642
|
const detail = errorOf(error, 'FINALIZATION_WARNING_PROJECTION_FAILED', true);
|
|
647
643
|
try {
|
|
648
644
|
const capability = issueCapability(receipt, 'warning-projection');
|
|
649
|
-
return
|
|
645
|
+
return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'failed', error: detail }, consumed);
|
|
650
646
|
}
|
|
651
647
|
catch { return receipt; }
|
|
652
648
|
}
|
|
653
649
|
}
|
|
654
650
|
try {
|
|
655
651
|
const capability = issueCapability(receipt, 'warning-projection');
|
|
656
|
-
return
|
|
652
|
+
return mutateFinalizationReceipt(repoRoot, receipt, capability, { scope: 'warning-projection', operation: 'succeeded' }, consumed);
|
|
657
653
|
}
|
|
658
654
|
catch { return receipt; }
|
|
659
655
|
}
|
|
@@ -692,7 +688,7 @@ async function syncPendingTaskComment(input: {
|
|
|
692
688
|
if (result.status === 'applied' || result.status === 'no-op') {
|
|
693
689
|
const skipped = result.error?.code === 'ISSUE_NOT_LINKED';
|
|
694
690
|
const capability = issueCapability(receipt, 'task-comment');
|
|
695
|
-
receipt =
|
|
691
|
+
receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
|
|
696
692
|
scope: 'task-comment', operation: 'succeeded', state: skipped ? 'skipped' : 'done'
|
|
697
693
|
}, consumedCapabilities);
|
|
698
694
|
receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
|
|
@@ -708,7 +704,7 @@ async function syncPendingTaskComment(input: {
|
|
|
708
704
|
}
|
|
709
705
|
const detail = step.error ?? { code: 'COMMENT_SYNC_FAILED', message: 'task comment synchronization failed', retryable: true };
|
|
710
706
|
const capability = issueCapability(receipt, 'task-comment');
|
|
711
|
-
receipt =
|
|
707
|
+
receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
|
|
712
708
|
scope: 'task-comment', operation: 'failed', error: detail
|
|
713
709
|
}, consumedCapabilities);
|
|
714
710
|
receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
|
|
@@ -717,7 +713,7 @@ async function syncPendingTaskComment(input: {
|
|
|
717
713
|
const detail = errorOf(error, 'COMMENT_SYNC_FAILED', true);
|
|
718
714
|
try {
|
|
719
715
|
const capability = issueCapability(receipt, 'task-comment');
|
|
720
|
-
receipt =
|
|
716
|
+
receipt = mutateFinalizationReceipt(repoRoot, receipt, capability, {
|
|
721
717
|
scope: 'task-comment', operation: 'failed', error: detail
|
|
722
718
|
}, consumedCapabilities);
|
|
723
719
|
receipt = reconcileWarningProjection(repoRoot, taskId, receipt, consumedCapabilities);
|
|
@@ -863,14 +859,14 @@ function preparedResult(
|
|
|
863
859
|
};
|
|
864
860
|
}
|
|
865
861
|
|
|
866
|
-
async function
|
|
862
|
+
async function prepareTaskFinalizationCore(
|
|
867
863
|
request: TaskFinalizationRequest,
|
|
868
864
|
taskId: string,
|
|
869
865
|
options: TaskFinalizationOptions
|
|
870
866
|
): Promise<TaskFinalizationResult> {
|
|
871
867
|
const repoRoot = path.resolve(options.repoRoot);
|
|
872
868
|
const lifecycle = options.lifecycle ?? ((lifecycleRequest, lifecycleOptions) => (
|
|
873
|
-
|
|
869
|
+
applyTaskLifecycle(lifecycleRequest, lifecycleOptions ?? { repoRoot })
|
|
874
870
|
));
|
|
875
871
|
const backfill = options.backfill ?? backfillCompletionComments;
|
|
876
872
|
const commentSync = options.commentSync ?? syncPlatformComment;
|
|
@@ -1142,11 +1138,9 @@ async function prepareTaskFinalization(request: TaskFinalizationRequest, options
|
|
|
1142
1138
|
const resolved = resolveTaskRef(request.taskRef, { repoRoot });
|
|
1143
1139
|
if (!resolved.ok) return failed(resolved.taskId, { code: resolved.code, message: resolved.message, retryable: false });
|
|
1144
1140
|
try {
|
|
1145
|
-
return await
|
|
1141
|
+
return await prepareTaskFinalizationCore(request, resolved.taskId, options);
|
|
1146
1142
|
} catch (error) {
|
|
1147
|
-
const detail = error
|
|
1148
|
-
? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
|
|
1149
|
-
: errorOf(error, 'TASK_FINALIZATION_FAILED');
|
|
1143
|
+
const detail = errorOf(error, 'TASK_FINALIZATION_FAILED');
|
|
1150
1144
|
return failed(resolved.taskId, detail);
|
|
1151
1145
|
}
|
|
1152
1146
|
}
|
|
@@ -1159,7 +1153,7 @@ async function commitPreparedTaskFinalization(request: TaskFinalizationRequest,
|
|
|
1159
1153
|
const resolved = resolveTaskRef(request.taskRef, { repoRoot });
|
|
1160
1154
|
if (!resolved.ok) return failed(resolved.taskId, { code: resolved.code, message: resolved.message, retryable: false });
|
|
1161
1155
|
try {
|
|
1162
|
-
return await
|
|
1156
|
+
return await (async () => {
|
|
1163
1157
|
if (options.controlBinding && options.manifestPath) {
|
|
1164
1158
|
try {
|
|
1165
1159
|
const manifest = readSandboxControlManifest(options.manifestPath);
|
|
@@ -1223,7 +1217,7 @@ async function commitPreparedTaskFinalization(request: TaskFinalizationRequest,
|
|
|
1223
1217
|
};
|
|
1224
1218
|
const result = options.lifecycle
|
|
1225
1219
|
? options.lifecycle(lifecycleRequest, lifecycleOptions)
|
|
1226
|
-
:
|
|
1220
|
+
: applyTaskLifecycle(lifecycleRequest, lifecycleOptions);
|
|
1227
1221
|
const step = lifecycleStep(result);
|
|
1228
1222
|
if (result.status !== 'applied' && result.status !== 'no-op') {
|
|
1229
1223
|
const updated = updateReceipt(repoRoot, receipt, { lifecycle: 'pending', lastError: step.error });
|
|
@@ -1305,11 +1299,9 @@ async function commitPreparedTaskFinalization(request: TaskFinalizationRequest,
|
|
|
1305
1299
|
});
|
|
1306
1300
|
}
|
|
1307
1301
|
return terminalResult(resolved.taskId, updated, { lifecycle: step, verification }, result.changed, detail);
|
|
1308
|
-
});
|
|
1302
|
+
})();
|
|
1309
1303
|
} catch (error) {
|
|
1310
|
-
const detail = error
|
|
1311
|
-
? { code: error.code, message: error.message, retryable: error.code === 'ORCHESTRATION_LOCK_BUSY' }
|
|
1312
|
-
: errorOf(error, 'TASK_FINALIZATION_FAILED');
|
|
1304
|
+
const detail = errorOf(error, 'TASK_FINALIZATION_FAILED');
|
|
1313
1305
|
return failed(resolved.taskId, detail);
|
|
1314
1306
|
}
|
|
1315
1307
|
}
|
package/lib/task/lifecycle.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { validateCurrentTaskContract } from './current-contract.ts';
|
|
|
18
18
|
import { isValidAgentInfraVersion } from '../version.ts';
|
|
19
19
|
import { taskIssueIdentity } from '../platform/task-identities.ts';
|
|
20
20
|
import { resourceIdentityEquals } from '../platform/resource-identity.ts';
|
|
21
|
-
import {
|
|
21
|
+
import { resolveProjectTaskWorkspaceRoot } from './workspace-root.ts';
|
|
22
22
|
|
|
23
23
|
const lifecycleIntentCatalog = [
|
|
24
24
|
'block', 'activate', 'cancel', 'complete', 'close-codescan', 'close-dependabot', 'restore', 'recover-started'
|
|
@@ -103,6 +103,9 @@ type LifecycleFileSystem = {
|
|
|
103
103
|
readFileSync: (file: string) => string;
|
|
104
104
|
writeFileSync: (file: string, content: string, flag?: string) => void;
|
|
105
105
|
unlinkSync: (file: string) => void;
|
|
106
|
+
rmdirSync: (directory: string) => void;
|
|
107
|
+
readdirSync: (directory: string) => string[];
|
|
108
|
+
readMountInfoSync: () => string;
|
|
106
109
|
};
|
|
107
110
|
type TaskLifecycleOptions = {
|
|
108
111
|
repoRoot?: string;
|
|
@@ -127,9 +130,25 @@ const DEFAULT_IO: LifecycleFileSystem = {
|
|
|
127
130
|
renameSync: (source, target) => fs.renameSync(source, target),
|
|
128
131
|
readFileSync: (file) => fs.readFileSync(file, 'utf8'),
|
|
129
132
|
writeFileSync: (file, content, flag) => fs.writeFileSync(file, content, { encoding: 'utf8', flag: flag ?? 'w' }),
|
|
130
|
-
unlinkSync: (file) => fs.unlinkSync(file)
|
|
133
|
+
unlinkSync: (file) => fs.unlinkSync(file),
|
|
134
|
+
rmdirSync: (directory) => fs.rmdirSync(directory),
|
|
135
|
+
readdirSync: (directory) => fs.readdirSync(directory),
|
|
136
|
+
readMountInfoSync: () => fs.readFileSync('/proc/self/mountinfo', 'utf8')
|
|
131
137
|
};
|
|
132
138
|
|
|
139
|
+
function isVirtiofsMountPoint(directory: string, mountInfo: string): boolean {
|
|
140
|
+
const decodeMountInfoPath = (value: string): string => value.replace(/\\([0-7]{3})/gu, (_match, octal: string) => String.fromCharCode(Number.parseInt(octal, 8)));
|
|
141
|
+
const expected = fs.realpathSync.native(directory);
|
|
142
|
+
return mountInfo.split('\n').some((line) => {
|
|
143
|
+
if (!line) return false;
|
|
144
|
+
const fields = line.split(' ');
|
|
145
|
+
const separator = fields.indexOf('-');
|
|
146
|
+
return separator >= 0
|
|
147
|
+
&& fields[separator + 1] === 'virtiofs'
|
|
148
|
+
&& path.resolve(decodeMountInfoPath(fields[4] ?? '')) === expected;
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
133
152
|
function failed(request: Pick<TaskLifecycleRequest, 'taskRef' | 'intent'>, error: LifecycleError, extra: Partial<TaskLifecycleResult> = {}): TaskLifecycleResult {
|
|
134
153
|
return {
|
|
135
154
|
status: 'failed', changed: false, requestRef: request.taskRef, taskId: null,
|
|
@@ -418,14 +437,14 @@ function validateRestoreStaging(request: Extract<TaskLifecycleRequest, { intent:
|
|
|
418
437
|
let workspace: string;
|
|
419
438
|
let stagingDir: string;
|
|
420
439
|
try {
|
|
421
|
-
workspace = fs.realpathSync.native(
|
|
440
|
+
workspace = fs.realpathSync.native(resolveProjectTaskWorkspaceRoot(repoRoot));
|
|
422
441
|
stagingDir = fs.realpathSync.native(path.resolve(request.stagingDir));
|
|
423
442
|
} catch (error) {
|
|
424
443
|
return { code: 'LIFECYCLE_STAGING_INVALID', message: String(error) };
|
|
425
444
|
}
|
|
426
445
|
const relative = path.relative(workspace, stagingDir);
|
|
427
446
|
if (!relative || relative === '..' || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative) || path.basename(stagingDir) === taskId) {
|
|
428
|
-
return { code: 'LIFECYCLE_STAGING_INVALID', message: 'restore staging must be a non-final directory inside
|
|
447
|
+
return { code: 'LIFECYCLE_STAGING_INVALID', message: 'restore staging must be a non-final directory inside the project task workspace' };
|
|
429
448
|
}
|
|
430
449
|
let entries: fs.Dirent[];
|
|
431
450
|
try { entries = fs.readdirSync(stagingDir, { withFileTypes: true }); }
|
|
@@ -610,7 +629,7 @@ export function inspectTaskLifecycleProgress(
|
|
|
610
629
|
}
|
|
611
630
|
}
|
|
612
631
|
|
|
613
|
-
function
|
|
632
|
+
function applyTaskLifecycle(requestInput: TaskLifecycleRequest, options: TaskLifecycleOptions = {}): TaskLifecycleResult {
|
|
614
633
|
if (requestInput.intent === 'recover-started') {
|
|
615
634
|
return failed(requestInput, { code: 'LIFECYCLE_RECOVERY_REQUIRES_AUTHORITY', message: 'recover-started must be dispatched through task control authority' });
|
|
616
635
|
}
|
|
@@ -652,7 +671,7 @@ function applyTaskLifecycleUnlocked(requestInput: TaskLifecycleRequest, options:
|
|
|
652
671
|
} else {
|
|
653
672
|
return failed(request, { code: 'LIFECYCLE_TASK_NOT_FOUND', message: `task ${taskId} has no lifecycle source` }, { taskId });
|
|
654
673
|
}
|
|
655
|
-
const targetPath = path.join(repoRoot,
|
|
674
|
+
const targetPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), spec.target, taskId);
|
|
656
675
|
const requiredSteps = stepsForIntent(request.intent);
|
|
657
676
|
const movingTaskDirectory = sourcePath !== targetPath;
|
|
658
677
|
const currentTaskFile = path.join(sourcePath, 'task.md');
|
|
@@ -690,7 +709,7 @@ function applyTaskLifecycleUnlocked(requestInput: TaskLifecycleRequest, options:
|
|
|
690
709
|
if (!contract.ok) return failed(request, { code: 'LIFECYCLE_DOCUMENT_INVALID', message: contract.message }, { taskId, sourceState, targetState: spec.target, sourcePath, targetPath });
|
|
691
710
|
}
|
|
692
711
|
const registryRequest = executeShortIdCommand({
|
|
693
|
-
operation: 'list', activeDir: path.join(repoRoot, '
|
|
712
|
+
operation: 'list', activeDir: path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active'),
|
|
694
713
|
shortIdLength: configuredShortIdLength(repoRoot)
|
|
695
714
|
});
|
|
696
715
|
if (registryRequest.status === 'failed') {
|
|
@@ -861,9 +880,20 @@ function applyTaskLifecycleUnlocked(requestInput: TaskLifecycleRequest, options:
|
|
|
861
880
|
}
|
|
862
881
|
}
|
|
863
882
|
}
|
|
864
|
-
const activeTaskPath = path.join(repoRoot, '
|
|
883
|
+
const activeTaskPath = path.join(resolveProjectTaskWorkspaceRoot(repoRoot), 'active', taskId);
|
|
865
884
|
if (request.intent === 'complete' && fs.existsSync(activeTaskPath)) {
|
|
866
|
-
try {
|
|
885
|
+
try {
|
|
886
|
+
let sourceIsVirtiofsMount = false;
|
|
887
|
+
try { sourceIsVirtiofsMount = isVirtiofsMountPoint(activeTaskPath, io.readMountInfoSync()); }
|
|
888
|
+
catch { /* Platforms without mountinfo retain the ordinary directory cleanup path. */ }
|
|
889
|
+
if (sourceIsVirtiofsMount) {
|
|
890
|
+
if (io.readdirSync(activeTaskPath).length > 0) {
|
|
891
|
+
throw new Error('virtiofs source directory is not empty after task contents were transferred');
|
|
892
|
+
}
|
|
893
|
+
} else {
|
|
894
|
+
io.rmdirSync(activeTaskPath);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
867
897
|
catch (error) {
|
|
868
898
|
return failed(request, { code: 'LIFECYCLE_SOURCE_DIRECTORY_CLEANUP_FAILED', message: String(error) }, {
|
|
869
899
|
taskId, sourceState, targetState: spec.target, sourcePath: activeTaskPath, targetPath, journalPath,
|
|
@@ -895,50 +925,9 @@ function applyTaskLifecycleUnlocked(requestInput: TaskLifecycleRequest, options:
|
|
|
895
925
|
};
|
|
896
926
|
}
|
|
897
927
|
|
|
898
|
-
function applyTaskLifecycle(request: TaskLifecycleRequest, options: TaskLifecycleOptions = {}): TaskLifecycleResult {
|
|
899
|
-
const normalized = normalizedRequest(request);
|
|
900
|
-
if ('code' in normalized) return applyTaskLifecycleUnlocked(request, options);
|
|
901
|
-
const repoRoot = path.resolve(options.repoRoot ?? process.cwd());
|
|
902
|
-
const taskId = normalized.intent === 'restore'
|
|
903
|
-
? normalized.taskRef
|
|
904
|
-
: (() => {
|
|
905
|
-
const resolved = resolveTaskRef(normalized.taskRef, { repoRoot });
|
|
906
|
-
return resolved.ok ? resolved.taskId : null;
|
|
907
|
-
})();
|
|
908
|
-
if (!taskId) return applyTaskLifecycleUnlocked(request, options);
|
|
909
|
-
try {
|
|
910
|
-
return withTaskExecutionLock(repoRoot, taskId, 'task-lifecycle.move', () => applyTaskLifecycleUnlocked(request, options));
|
|
911
|
-
} catch (error) {
|
|
912
|
-
if (error instanceof TaskExecutionLockError) {
|
|
913
|
-
return failed(request, { code: error.code, message: error.message }, { taskId });
|
|
914
|
-
}
|
|
915
|
-
throw error;
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
function applyTaskLifecycleWithinTaskLock(
|
|
920
|
-
request: TaskLifecycleRequest,
|
|
921
|
-
options: TaskLifecycleOptions,
|
|
922
|
-
lockedTaskId: string
|
|
923
|
-
): TaskLifecycleResult {
|
|
924
|
-
const normalized = normalizedRequest(request);
|
|
925
|
-
if ('code' in normalized) return failed(request, normalized);
|
|
926
|
-
const repoRoot = path.resolve(options.repoRoot ?? process.cwd());
|
|
927
|
-
const resolved = normalized.intent === 'restore'
|
|
928
|
-
? { ok: true as const, taskId: normalized.taskRef }
|
|
929
|
-
: resolveTaskRef(normalized.taskRef, { repoRoot });
|
|
930
|
-
if (!resolved.ok || resolved.taskId !== lockedTaskId) {
|
|
931
|
-
return failed(request, {
|
|
932
|
-
code: 'LIFECYCLE_LOCK_SCOPE_MISMATCH',
|
|
933
|
-
message: 'task lifecycle request does not match the held task lock'
|
|
934
|
-
}, { taskId: resolved.ok ? resolved.taskId : resolved.taskId });
|
|
935
|
-
}
|
|
936
|
-
return applyTaskLifecycleUnlocked(request, options);
|
|
937
|
-
}
|
|
938
|
-
|
|
939
928
|
export {
|
|
940
929
|
lifecycleIntentCatalog, lifecycleFailureCatalog, lifecycleProducerCatalog,
|
|
941
|
-
applyTaskLifecycle,
|
|
930
|
+
applyTaskLifecycle, previewTaskCompletion
|
|
942
931
|
};
|
|
943
932
|
export type {
|
|
944
933
|
TaskLifecycleIntent, TaskLifecycleRequest, TaskLifecycleResult, TaskLifecycleOptions,
|
|
@@ -52,7 +52,6 @@ type LocalArtifactFinalizationRequest = {
|
|
|
52
52
|
artifact: string;
|
|
53
53
|
repoRoot?: string;
|
|
54
54
|
requiredSections?: readonly string[];
|
|
55
|
-
lockAlreadyHeld?: boolean;
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
type LocalArtifactFinalizationResult = {
|
|
@@ -129,7 +128,6 @@ type LocalArtifactPreparation = Readonly<{
|
|
|
129
128
|
result: LocalArtifactFinalizationResult;
|
|
130
129
|
content: string;
|
|
131
130
|
repoRoot?: string;
|
|
132
|
-
lockAlreadyHeld?: boolean;
|
|
133
131
|
}>;
|
|
134
132
|
|
|
135
133
|
function prepareLocalArtifact(
|
|
@@ -180,8 +178,7 @@ function prepareLocalArtifact(
|
|
|
180
178
|
return {
|
|
181
179
|
result: validation.ok && !qualificationError ? { ...result, status: 'passed', error: null } : result,
|
|
182
180
|
content,
|
|
183
|
-
repoRoot: resolved.repoRoot
|
|
184
|
-
lockAlreadyHeld: request.lockAlreadyHeld
|
|
181
|
+
repoRoot: resolved.repoRoot
|
|
185
182
|
};
|
|
186
183
|
|
|
187
184
|
}
|