@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
|
@@ -5,7 +5,7 @@ description: >
|
|
|
5
5
|
当需要持续监控 PR 直到门禁通过且明确可合入时使用。
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# 监控拉取请求
|
|
9
9
|
|
|
10
10
|
在 `create-pr` 之后持续监控同一 PR head 的全部 checks 与 mergeability。只有全部 checks 通过且平台明确可合入才进入成功出口;check 失败走既有修复,合并冲突走受限 rebase 自愈,未知或无法安全闭环时 fail-closed。
|
|
11
11
|
|
|
@@ -40,7 +40,7 @@ description: >
|
|
|
40
40
|
按以下确定性分支解析出目标 PR 号 `{pr#}` 与可选 `{task-id}`:
|
|
41
41
|
|
|
42
42
|
- 场景 A(省略入参):从当前分支反查 active task;定位后读取其 verified `pr_delivery_fact.identity.number`。
|
|
43
|
-
- 场景 B(省略 task ref 或 `--task/-t`,**任务锚定主路径**):按「任务上下文解析」取得完整 `{task-id}`。读
|
|
43
|
+
- 场景 B(省略 task ref 或 `--task/-t`,**任务锚定主路径**):按「任务上下文解析」取得完整 `{task-id}`。读 `<task-workspace>/active/{task-id}/task.md` 取 verified `pr_delivery_fact.identity.number` 作为 `{pr#}`;fact 未绑定时按「错误处理」提示先 `create-pr`,停止。
|
|
44
44
|
- 场景 C(`--pr <number>` 或 PR URL):直接取该 PR 号为 `{pr#}`;随后按「反查任务」确定 `{task-id}`。
|
|
45
45
|
- 反查任务(场景 A / C):通过任务上下文/任务查询取得与 `{pr#}` 唯一绑定的 active task。未命中时停止并提示先绑定 PR;typed checks intent 不建立第二套无任务状态机。
|
|
46
46
|
|
|
@@ -48,7 +48,22 @@ description: >
|
|
|
48
48
|
|
|
49
49
|
执行此步骤前,先读取 `reference/monitor-and-heal.md` 与 `.agents/rules/pr-checks-commands.md`。
|
|
50
50
|
|
|
51
|
-
进入本轮时初始化 `repairCommits=[]` 与 `rebaseAttempts=0
|
|
51
|
+
进入本轮时初始化 `repairCommits=[]` 与 `rebaseAttempts=0`。每次覆盖当前报告前,先用 core 导出的 reader 验证并暂存现有报告的身份与 head;文件不存在或验证失败即记为无上一 head:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
node --experimental-strip-types --input-type=module -e '
|
|
55
|
+
import { readPrChangeReport } from "./lib/platform/pr-change-report.ts";
|
|
56
|
+
const report = readPrChangeReport(`<task-workspace>/active/${process.argv[1]}/pr-change-report.json`);
|
|
57
|
+
const previous = report.ok
|
|
58
|
+
? { repository: report.value.identity.repository, resource: report.value.identity.resource, head: report.value.identity.head.sha }
|
|
59
|
+
: { status: "unavailable" };
|
|
60
|
+
process.stdout.write(`${JSON.stringify(previous)}\n`);
|
|
61
|
+
' {task-id}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
随后调用 `platform-pr summary-context`,比较暂存的 repository/resource identity 与当前权威 snapshot;不匹配时丢弃旧 head 并标记增量未确认。按共享 PR change-report contract 用当前权威 PR head 重建任务绑定的 `pr-change-report.json`,再用含唯一 `<!-- canonical-pr-change-report -->` 占位符的正文调用 `summary-sync --change-report-file ... --result no_op --strict` 刷新同一条摘要。完整 PR 仍使用当前 base/head/merge-base/patch 与现有 totals。只有在上一报告有效、PR identity 相同且两个 head 不同的情况下,才用 `git diff --find-renames --numstat {previous-head} {current-head}`、`--name-status`、`--summary` 描述独立的 head→head 树差异;不使用 merge-base 替代该范围,不把增量 totals 加入完整 PR。无有效上一 head 时写明未确认,不从完整 PR 推算或填零;head 相同只说明没有新的 head 转换。
|
|
65
|
+
|
|
66
|
+
`--strict` 将报告或摘要刷新失败保留为 `failed/blocked`,不得把 warning 当作成功;刷新失败时不得进入 ready/complete 出口,按步骤 4 记录阻塞。刷新成功后,消费 `summary-sync` 结构化结果的 `nextAction`:`review-code` 立即结束 readiness/self-heal 路径,按步骤 7 的代码审查分支退出;`watch-pr` 才继续调用 `agent-infra-internal platform-checks watch {task-id} --interval-seconds 30 --deadline-seconds 1800`。缺失或 invalid `nextAction` 按刷新失败处理,不推断为 `watch-pr`。readiness 只按结构化 `readiness.state` 分流:`ready` 进入步骤 7,`conflicting` 或 `checks-failed` 进入步骤 3,`pending|timed-out|cancelled` 进入步骤 4。
|
|
52
67
|
|
|
53
68
|
### 3. 自愈循环
|
|
54
69
|
|
|
@@ -70,14 +85,14 @@ description: >
|
|
|
70
85
|
date "+%Y-%m-%d %H:%M:%S%z" | sed 's/\([+-][0-9][0-9]\)\([0-9][0-9]\)$/\1:\2/'
|
|
71
86
|
```
|
|
72
87
|
|
|
73
|
-
更新
|
|
88
|
+
更新 `<task-workspace>/active/{task-id}/task.md`:
|
|
74
89
|
- `assigned_to`:{当前代理}
|
|
75
90
|
- `updated_at`:{当前时间}
|
|
76
91
|
- `agent_infra_version`:按 `.agents/rules/version-stamp.md` 取值
|
|
77
92
|
- **不改** `pr_delivery_fact` 与 `current_step`
|
|
78
93
|
- **追加**到 `## 活动日志`(不要覆盖之前的记录;`{N}` = 本任务已有 Watch PR 条目数 + 1):
|
|
79
94
|
```
|
|
80
|
-
- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Watch PR (Round {N})** by {agent} — {成功:PR ready, repair commits: {k} [{sha 摘要}] / 阻塞:blocked: {简述}}
|
|
95
|
+
- {YYYY-MM-DD HH:mm:ss±HH:MM} — **Watch PR (Round {N})** by {agent} — {成功:PR ready, repair commits: {k} [{sha 摘要}] / 需复核:nextAction=review-code / 阻塞:blocked: {简述}}
|
|
81
96
|
```
|
|
82
97
|
|
|
83
98
|
### 6. 完成校验
|
|
@@ -124,6 +139,8 @@ agent-infra-internal task-verify {task-id} watch-pr.completed --format text
|
|
|
124
139
|
{next-step-commands}
|
|
125
140
|
```
|
|
126
141
|
|
|
142
|
+
- `summary-sync.nextAction == review-code`:说明报告要求代码审查;这不表示 PR readiness 已通过。使用 `agent-infra-internal agent-client next-steps --skill review-code --task-ref {task-ref}` 生成唯一下一步,结束本轮。不得继续 readiness/self-heal 或自行修改代码。
|
|
143
|
+
|
|
127
144
|
- 「阻塞」:仅输出步骤 4 的阻塞说明,不推荐下一步命令。
|
|
128
145
|
|
|
129
146
|
## 完成检查清单
|
|
@@ -17,6 +17,20 @@ Before readiness in every round, and after an external push, self-heal commit, o
|
|
|
17
17
|
|
|
18
18
|
When rebuilding the precheck, each of the six `rationale` fields must state the corresponding high-level finding and include at least one path, line range, and concise `detail` as evidence. `change-composition` must describe where responsibilities are concentrated; compatibility, legacy-path, redundancy, and scope checks must state their actual results separately, without reused generic boilerplate. Use the deployed skill's language for rationales and evidence details; Chinese skill deployments must use Chinese.
|
|
19
19
|
|
|
20
|
+
Use the six existing `rationale` fields and `Evidence[]` to explain each logical change group: its goal and acceptance-criteria alignment, behavior added or removed, necessity, redundancy or duplication, scope, related tests, and test adequacy. Cite locatable code, test, or documentation evidence; mark unsupported points as unconfirmed. The renderer displays every evidence item. Source line counts, execution/call counts, and workflow unification are distinct claims: diff line counts cannot prove execution-count or workflow-behavior changes, and green CI cannot prove necessity. Analysis must not expand self-heal or refactoring authority.
|
|
21
|
+
|
|
22
|
+
Keep complete-PR scope bound to the current authoritative base/head/merge-base/patch and its full statistics. Report the increment separately as previous valid report head → current head. Before overwriting the prior sidecar, validate it with `readPrChangeReport`; use its `identity.head.sha` only when its repository/resource identity matches the current PR. Compare the two head trees directly and state both SHAs. Do not substitute a merge-base diff for these endpoints or add increment totals to complete-PR totals. If no prior report exists, it is invalid, or its identity differs, mark the previous head unconfirmed; do not infer values from the full PR or fill in zeroes. Identical SHAs mean the head did not change. After a rebase, compare the old and new head trees. An invalid sidecar makes only the increment unconfirmed; the existing full-PR report flow continues.
|
|
23
|
+
|
|
24
|
+
## Precheck Route
|
|
25
|
+
|
|
26
|
+
After `summary-sync --strict` succeeds, consume its structured `nextAction` result before entering readiness:
|
|
27
|
+
|
|
28
|
+
- `nextAction=review-code`: stop this Watch PR readiness/self-heal loop, recommend `review-code` through the unified helper, and end the round. Green CI does not clear necessity concerns, and Watch PR must not perform automatic redundancy cleanup or refactoring.
|
|
29
|
+
- `nextAction=watch-pr`: continue through the existing readiness classification and self-heal decision tree.
|
|
30
|
+
- Missing or invalid `nextAction`: use the strict-refresh help exit; do not infer `watch-pr`.
|
|
31
|
+
|
|
32
|
+
This route reuses the result already derived by the core from the six checks. It does not grant Watch PR authority to write a `review-code` report or perform automatic fixes.
|
|
33
|
+
|
|
20
34
|
## Self-Heal Decision Tree
|
|
21
35
|
|
|
22
36
|
```text
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`watch-pr` 步骤 2/3/4 的平台无关判定逻辑。具体平台命令(监控、解析失败 run、拉日志、读取 PR 号)见 `.agents/rules/pr-checks-commands.md`;本文件只描述与平台无关的分类与决策。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 就绪状态分类
|
|
6
6
|
|
|
7
7
|
按 `.agents/rules/pr-checks-commands.md` 的监控命令执行后,依其退出码归为三类:
|
|
8
8
|
|
|
@@ -17,6 +17,20 @@
|
|
|
17
17
|
|
|
18
18
|
每轮重建 precheck 时,六项 `rationale` 都必须是对应检查的实际高层结论,并各带至少一条路径、行号和简短 `detail` 证据;`change-composition` 要说明职责集中位置,兼容、旧路径、冗余和范围检查要分别说明实际结果,禁止复用泛化套话。理由和证据详情遵循当前已部署技能的语言,中文技能必须使用中文。
|
|
19
19
|
|
|
20
|
+
按逻辑变化组使用现有六项 `rationale` 和 `Evidence[]` 说明目标/验收对应、行为增减、必要性、冗余或重复、范围、相关测试及测试充分性。列出可定位的代码/测试/文档证据;缺证据时明确写未确认。renderer 会展示每项的全部 evidence。源码行数、执行/调用次数和流程统一是不同结论:diff 行数不能证明执行次数或流程行为变化;CI 全绿也不能证明必要性。不得由分析建议自行扩大自愈或重构权限。
|
|
21
|
+
|
|
22
|
+
完整 PR 的范围继续绑定当前权威 base/head/merge-base/patch 与完整统计。增量单独绑定上一有效报告 head → 当前 head:在覆盖旧 sidecar 前,用 `readPrChangeReport` 校验旧报告,只在 repository/resource identity 匹配当前 PR 时采用旧 `identity.head.sha`。对两个 head 做 tree-to-tree diff 并明确列出 SHA,不用 merge-base 替代端点差异,不把增量 totals 加到完整 PR totals。没有旧报告、报告无效或身份不符时标注上一 head 未确认,不从全量推算或填零。两个 SHA 相同只报告 head 未变化;rebase 后仍比较原 head 和新 head 的树差异。sidecar 无效只使增量不可确认,不改变现有 full-PR 报告流程。
|
|
23
|
+
|
|
24
|
+
## 预检分流
|
|
25
|
+
|
|
26
|
+
`summary-sync --strict` 成功后,消费其结构化结果中的 `nextAction`,再决定是否进入 readiness:
|
|
27
|
+
|
|
28
|
+
- `nextAction=review-code`:停止当前 Watch PR readiness 与自愈循环,按统一 helper 推荐 `review-code` 并结束本轮。不得把 CI 绿色当作清除必要性疑点,也不得自动实施冗余清理或重构。
|
|
29
|
+
- `nextAction=watch-pr`:继续现有 readiness 分类与自愈决策树。
|
|
30
|
+
- `nextAction` 缺失或 invalid:遵循严格刷新失败出口,进入求助流程,不推断为 `watch-pr`。
|
|
31
|
+
|
|
32
|
+
此 route 只复用 core 已由六项 checks 推导的结果;不会把 `review-code` 报告或自动修复权限授予 Watch PR。
|
|
33
|
+
|
|
20
34
|
## 自愈决策树
|
|
21
35
|
|
|
22
36
|
```text
|
|
@@ -200,4 +200,4 @@ steps:
|
|
|
200
200
|
- Task workspace
|
|
201
201
|
outputs:
|
|
202
202
|
- Pull request (only on the PR path)
|
|
203
|
-
- Completed task
|
|
203
|
+
- Completed task under `completed/{task-id}` in the host root returned by `task-workspace resolve`
|
|
@@ -200,4 +200,4 @@ steps:
|
|
|
200
200
|
- Task workspace
|
|
201
201
|
outputs:
|
|
202
202
|
- Pull request (only on the PR path)
|
|
203
|
-
- Completed task
|
|
203
|
+
- Completed task under `completed/{task-id}` in the host root returned by `task-workspace resolve`
|
|
@@ -204,4 +204,4 @@ steps:
|
|
|
204
204
|
- Task workspace
|
|
205
205
|
outputs:
|
|
206
206
|
- Pull request (only on the PR path)
|
|
207
|
-
- Completed task
|
|
207
|
+
- Completed task under `completed/{task-id}` in the host root returned by `task-workspace resolve`
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { resolveTaskRuntimeRoot } from '../task/runtime-paths.js';
|
|
3
|
-
function runtimeError(code, message) {
|
|
4
|
-
const error = new Error(`${code}: ${message}`);
|
|
5
|
-
error.name = code;
|
|
6
|
-
return error;
|
|
7
|
-
}
|
|
8
|
-
function boundControlContext(env) {
|
|
9
|
-
return [
|
|
10
|
-
'AGENT_INFRA_CONTROL_TOKEN',
|
|
11
|
-
'AGENT_INFRA_CONTROL_GENERATION',
|
|
12
|
-
'AGENT_INFRA_EXECUTOR_MANIFEST'
|
|
13
|
-
].some((key) => typeof env[key] === 'string' && env[key].length > 0);
|
|
14
|
-
}
|
|
15
|
-
export function resolveAgentRuntimeRoot(options = {}) {
|
|
16
|
-
const env = options.env ?? process.env;
|
|
17
|
-
const configured = env.AGENT_INFRA_RUNTIME_DIR;
|
|
18
|
-
if (configured !== undefined && configured.length > 0) {
|
|
19
|
-
if (!path.isAbsolute(configured)) {
|
|
20
|
-
throw runtimeError('AGENT_INFRA_RUNTIME_DIR_INVALID', 'runtime directory must be absolute');
|
|
21
|
-
}
|
|
22
|
-
return path.resolve(configured);
|
|
23
|
-
}
|
|
24
|
-
const taskId = env.AGENT_INFRA_TASK_ID;
|
|
25
|
-
if (taskId) {
|
|
26
|
-
return resolveTaskRuntimeRoot(taskId, { repoRoot: options.repoRoot });
|
|
27
|
-
}
|
|
28
|
-
if (boundControlContext(env)) {
|
|
29
|
-
throw runtimeError('AGENT_INFRA_RUNTIME_DIR_REQUIRED', 'task-bound control context requires AGENT_INFRA_RUNTIME_DIR');
|
|
30
|
-
}
|
|
31
|
-
return path.join(path.resolve(options.repoRoot ?? process.cwd()), '.agents', 'workspace', '.runtime');
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=agent-runtime.js.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { resolveTaskRef } from './resolve-ref.js';
|
|
4
|
-
export function resolveTaskRuntimeRoot(taskRef, options = {}) {
|
|
5
|
-
const resolved = resolveTaskRef(taskRef, options);
|
|
6
|
-
if (!resolved.ok)
|
|
7
|
-
throw new Error(`${resolved.code}: ${resolved.message}`);
|
|
8
|
-
return path.join(fs.realpathSync.native(resolved.taskDir), '.runtime');
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=runtime-paths.js.map
|
|
@@ -1,250 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import os from 'node:os';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { createHash, randomUUID } from 'node:crypto';
|
|
5
|
-
import { getProcessStartTime, processIdentityMatches } from '../server/process-state.js';
|
|
6
|
-
class TaskExecutionLockError extends Error {
|
|
7
|
-
code;
|
|
8
|
-
detail;
|
|
9
|
-
constructor(code, message, detail) {
|
|
10
|
-
super(message);
|
|
11
|
-
this.name = 'TaskExecutionLockError';
|
|
12
|
-
this.code = code;
|
|
13
|
-
this.detail = detail;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function errno(error) {
|
|
17
|
-
const value = error?.code;
|
|
18
|
-
return typeof value === 'string' ? value : null;
|
|
19
|
-
}
|
|
20
|
-
function mapLinkError(operation, error, key) {
|
|
21
|
-
const code = errno(error);
|
|
22
|
-
if (code === 'EEXIST')
|
|
23
|
-
return 'exists';
|
|
24
|
-
if (operation === 'quarantine' && code === 'ENOENT')
|
|
25
|
-
return 'missing';
|
|
26
|
-
const detail = { operation, errno: code, key };
|
|
27
|
-
if (['EPERM', 'EACCES', 'ENOSYS', 'ENOTSUP', 'EOPNOTSUPP', 'EXDEV'].includes(code ?? '')) {
|
|
28
|
-
return new TaskExecutionLockError('ORCHESTRATION_LOCK_UNSUPPORTED', `lifecycle lock hard-link operation '${operation}' is unsupported`, detail);
|
|
29
|
-
}
|
|
30
|
-
return new TaskExecutionLockError('ORCHESTRATION_LOCK_FAILED', `lifecycle lock hard-link operation '${operation}' failed`, detail);
|
|
31
|
-
}
|
|
32
|
-
function lockKey(repoRoot, taskId, identityScope) {
|
|
33
|
-
const canonicalRepoRoot = fs.realpathSync.native(repoRoot);
|
|
34
|
-
const identity = identityScope === undefined
|
|
35
|
-
? `${canonicalRepoRoot}\0${taskId}`
|
|
36
|
-
: `${identityScope}\0${taskId}`;
|
|
37
|
-
const key = createHash('sha256').update(identity).digest('hex');
|
|
38
|
-
return { canonicalRepoRoot, key };
|
|
39
|
-
}
|
|
40
|
-
function parseOwner(raw, key) {
|
|
41
|
-
try {
|
|
42
|
-
const value = JSON.parse(raw);
|
|
43
|
-
if (value !== null
|
|
44
|
-
&& value.version === 2
|
|
45
|
-
&& Number.isSafeInteger(value.pid)
|
|
46
|
-
&& (value.pid ?? 0) > 0
|
|
47
|
-
&& typeof value.startTime === 'number'
|
|
48
|
-
&& Number.isSafeInteger(value.startTime)
|
|
49
|
-
&& value.startTime >= 0
|
|
50
|
-
&& typeof value.token === 'string'
|
|
51
|
-
&& value.token.length > 0
|
|
52
|
-
&& typeof value.owner === 'string'
|
|
53
|
-
&& typeof value.canonicalRepoRoot === 'string'
|
|
54
|
-
&& typeof value.taskId === 'string'
|
|
55
|
-
&& typeof value.acquiredAt === 'string') {
|
|
56
|
-
return value;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
// Fall through to the stable lock failure below.
|
|
61
|
-
}
|
|
62
|
-
throw new TaskExecutionLockError('ORCHESTRATION_LOCK_FAILED', 'lifecycle lock owner record is invalid', { operation: 'read', errno: null, key });
|
|
63
|
-
}
|
|
64
|
-
function unlinkIfPresent(file) {
|
|
65
|
-
try {
|
|
66
|
-
fs.unlinkSync(file);
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
if (errno(error) !== 'ENOENT')
|
|
70
|
-
throw error;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
function sameInode(left, right) {
|
|
74
|
-
return left.dev === right.dev && left.ino === right.ino;
|
|
75
|
-
}
|
|
76
|
-
function reclaimStaleLock(fixed, quarantine, snapshot, key, link) {
|
|
77
|
-
let linked = false;
|
|
78
|
-
try {
|
|
79
|
-
link(fixed, quarantine);
|
|
80
|
-
linked = true;
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
const disposition = mapLinkError('quarantine', error, key);
|
|
84
|
-
if (disposition === 'missing')
|
|
85
|
-
return;
|
|
86
|
-
if (disposition === 'exists') {
|
|
87
|
-
try {
|
|
88
|
-
const quarantineSnapshot = fs.readFileSync(quarantine, 'utf8');
|
|
89
|
-
const fixedStat = fs.statSync(fixed);
|
|
90
|
-
const quarantineStat = fs.statSync(quarantine);
|
|
91
|
-
if (quarantineSnapshot === snapshot && sameInode(fixedStat, quarantineStat)) {
|
|
92
|
-
unlinkIfPresent(quarantine);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
catch (readError) {
|
|
96
|
-
if (errno(readError) !== 'ENOENT')
|
|
97
|
-
throw readError;
|
|
98
|
-
}
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
if (disposition instanceof TaskExecutionLockError)
|
|
102
|
-
throw disposition;
|
|
103
|
-
}
|
|
104
|
-
try {
|
|
105
|
-
const fixedSnapshot = fs.readFileSync(fixed, 'utf8');
|
|
106
|
-
const fixedStat = fs.statSync(fixed);
|
|
107
|
-
const quarantineStat = fs.statSync(quarantine);
|
|
108
|
-
if (fixedSnapshot === snapshot && sameInode(fixedStat, quarantineStat))
|
|
109
|
-
unlinkIfPresent(fixed);
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
if (errno(error) !== 'ENOENT')
|
|
113
|
-
throw error;
|
|
114
|
-
}
|
|
115
|
-
finally {
|
|
116
|
-
if (linked)
|
|
117
|
-
unlinkIfPresent(quarantine);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function cleanStaleCandidates(lockRoot, key, identityMatches) {
|
|
121
|
-
const prefix = `${key}.candidate.`;
|
|
122
|
-
for (const name of fs.readdirSync(lockRoot)) {
|
|
123
|
-
if (!name.startsWith(prefix))
|
|
124
|
-
continue;
|
|
125
|
-
const candidate = path.join(lockRoot, name);
|
|
126
|
-
try {
|
|
127
|
-
const owner = parseOwner(fs.readFileSync(candidate, 'utf8'), key);
|
|
128
|
-
if (!identityMatches(owner))
|
|
129
|
-
unlinkIfPresent(candidate);
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
// A malformed candidate never owns the fixed lock and is left for manual diagnosis.
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
function withTaskExecutionLock(repoRoot, taskId, ownerName, callback, options = {}) {
|
|
137
|
-
let identity;
|
|
138
|
-
try {
|
|
139
|
-
identity = lockKey(repoRoot, taskId, options.identityScope);
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
throw new TaskExecutionLockError('ORCHESTRATION_LOCK_FAILED', 'failed to canonicalize the repository for lifecycle locking', { operation: 'canonicalize', errno: errno(error), key: 'unresolved' });
|
|
143
|
-
}
|
|
144
|
-
const { canonicalRepoRoot, key } = identity;
|
|
145
|
-
const lockRoot = options.lockRoot ?? path.join(os.tmpdir(), 'agent-infra-lifecycle-locks');
|
|
146
|
-
const token = (options.token ?? randomUUID)();
|
|
147
|
-
const candidate = path.join(lockRoot, `${key}.candidate.${process.pid}.${token}`);
|
|
148
|
-
const fixed = path.join(lockRoot, `${key}.lock`);
|
|
149
|
-
const link = options.linkSync ?? fs.linkSync;
|
|
150
|
-
const startTime = (options.getStartTime ?? getProcessStartTime)(process.pid);
|
|
151
|
-
if (startTime === null) {
|
|
152
|
-
throw new TaskExecutionLockError('ORCHESTRATION_LOCK_FAILED', 'current process start time is unavailable', { operation: 'identity', errno: null, key });
|
|
153
|
-
}
|
|
154
|
-
const owner = {
|
|
155
|
-
version: 2,
|
|
156
|
-
pid: process.pid,
|
|
157
|
-
startTime,
|
|
158
|
-
token,
|
|
159
|
-
owner: ownerName,
|
|
160
|
-
canonicalRepoRoot,
|
|
161
|
-
taskId,
|
|
162
|
-
acquiredAt: (options.now ?? (() => new Date().toISOString()))()
|
|
163
|
-
};
|
|
164
|
-
const serialized = `${JSON.stringify(owner)}\n`;
|
|
165
|
-
let ownsFixed = false;
|
|
166
|
-
let deferRelease = false;
|
|
167
|
-
const release = () => {
|
|
168
|
-
try {
|
|
169
|
-
unlinkIfPresent(candidate);
|
|
170
|
-
}
|
|
171
|
-
catch {
|
|
172
|
-
// Candidate cleanup is best-effort and must not replace the primary result.
|
|
173
|
-
}
|
|
174
|
-
if (ownsFixed) {
|
|
175
|
-
try {
|
|
176
|
-
const current = parseOwner(fs.readFileSync(fixed, 'utf8'), key);
|
|
177
|
-
if (current.token === token)
|
|
178
|
-
unlinkIfPresent(fixed);
|
|
179
|
-
}
|
|
180
|
-
catch {
|
|
181
|
-
// A missing or replaced fixed lock is not owned by this invocation.
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
try {
|
|
186
|
-
fs.mkdirSync(lockRoot, { recursive: true });
|
|
187
|
-
cleanStaleCandidates(lockRoot, key, options.identityMatches ?? processIdentityMatches);
|
|
188
|
-
const descriptor = fs.openSync(candidate, 'wx', 0o600);
|
|
189
|
-
try {
|
|
190
|
-
fs.writeFileSync(descriptor, serialized);
|
|
191
|
-
fs.fsyncSync(descriptor);
|
|
192
|
-
}
|
|
193
|
-
finally {
|
|
194
|
-
fs.closeSync(descriptor);
|
|
195
|
-
}
|
|
196
|
-
for (let attempt = 0; attempt < 16; attempt += 1) {
|
|
197
|
-
try {
|
|
198
|
-
link(candidate, fixed);
|
|
199
|
-
ownsFixed = true;
|
|
200
|
-
break;
|
|
201
|
-
}
|
|
202
|
-
catch (error) {
|
|
203
|
-
const disposition = mapLinkError('acquire', error, key);
|
|
204
|
-
if (disposition instanceof TaskExecutionLockError)
|
|
205
|
-
throw disposition;
|
|
206
|
-
let snapshot;
|
|
207
|
-
let current;
|
|
208
|
-
try {
|
|
209
|
-
snapshot = fs.readFileSync(fixed, 'utf8');
|
|
210
|
-
current = parseOwner(snapshot, key);
|
|
211
|
-
}
|
|
212
|
-
catch (readError) {
|
|
213
|
-
if (errno(readError) === 'ENOENT')
|
|
214
|
-
continue;
|
|
215
|
-
throw readError;
|
|
216
|
-
}
|
|
217
|
-
if ((options.identityMatches ?? processIdentityMatches)(current)) {
|
|
218
|
-
throw new TaskExecutionLockError('ORCHESTRATION_LOCK_BUSY', 'another lifecycle operation holds the task lock', { operation: 'acquire', errno: 'EEXIST', key });
|
|
219
|
-
}
|
|
220
|
-
reclaimStaleLock(fixed, `${fixed}.quarantine.${current.token}`, snapshot, key, link);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
if (!ownsFixed) {
|
|
224
|
-
throw new TaskExecutionLockError('ORCHESTRATION_LOCK_BUSY', 'lifecycle task lock could not be acquired after stale recovery', { operation: 'acquire', errno: 'EEXIST', key });
|
|
225
|
-
}
|
|
226
|
-
unlinkIfPresent(candidate);
|
|
227
|
-
const value = callback();
|
|
228
|
-
if (value && typeof value.then === 'function') {
|
|
229
|
-
deferRelease = true;
|
|
230
|
-
return value.finally(release);
|
|
231
|
-
}
|
|
232
|
-
return value;
|
|
233
|
-
}
|
|
234
|
-
catch (error) {
|
|
235
|
-
if (error instanceof TaskExecutionLockError)
|
|
236
|
-
throw error;
|
|
237
|
-
if (error instanceof Error && ['OrchestrationStateError', 'ArtifactRecoveryError'].includes(error.name))
|
|
238
|
-
throw error;
|
|
239
|
-
throw new TaskExecutionLockError('ORCHESTRATION_LOCK_FAILED', 'lifecycle task lock operation failed', { operation: ownsFixed ? 'callback' : 'acquire', errno: errno(error), key });
|
|
240
|
-
}
|
|
241
|
-
finally {
|
|
242
|
-
if (!deferRelease)
|
|
243
|
-
release();
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
function withRepositoryMutationLock(repoRoot, callback, options = {}) {
|
|
247
|
-
return withTaskExecutionLock(repoRoot, '__repository_mutation__', 'repository-mutation', callback, options);
|
|
248
|
-
}
|
|
249
|
-
export { TaskExecutionLockError, lockKey, mapLinkError, withRepositoryMutationLock, withTaskExecutionLock };
|
|
250
|
-
//# sourceMappingURL=task-execution-lock.js.map
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { resolveTaskRuntimeRoot } from '../task/runtime-paths.ts';
|
|
3
|
-
|
|
4
|
-
function runtimeError(code: string, message: string): Error {
|
|
5
|
-
const error = new Error(`${code}: ${message}`);
|
|
6
|
-
error.name = code;
|
|
7
|
-
return error;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function boundControlContext(env: NodeJS.ProcessEnv): boolean {
|
|
11
|
-
return [
|
|
12
|
-
'AGENT_INFRA_CONTROL_TOKEN',
|
|
13
|
-
'AGENT_INFRA_CONTROL_GENERATION',
|
|
14
|
-
'AGENT_INFRA_EXECUTOR_MANIFEST'
|
|
15
|
-
].some((key) => typeof env[key] === 'string' && env[key]!.length > 0);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function resolveAgentRuntimeRoot(options: Readonly<{
|
|
19
|
-
repoRoot?: string;
|
|
20
|
-
env?: NodeJS.ProcessEnv;
|
|
21
|
-
}> = {}): string {
|
|
22
|
-
const env = options.env ?? process.env;
|
|
23
|
-
const configured = env.AGENT_INFRA_RUNTIME_DIR;
|
|
24
|
-
if (configured !== undefined && configured.length > 0) {
|
|
25
|
-
if (!path.isAbsolute(configured)) {
|
|
26
|
-
throw runtimeError('AGENT_INFRA_RUNTIME_DIR_INVALID', 'runtime directory must be absolute');
|
|
27
|
-
}
|
|
28
|
-
return path.resolve(configured);
|
|
29
|
-
}
|
|
30
|
-
const taskId = env.AGENT_INFRA_TASK_ID;
|
|
31
|
-
if (taskId) {
|
|
32
|
-
return resolveTaskRuntimeRoot(taskId, { repoRoot: options.repoRoot });
|
|
33
|
-
}
|
|
34
|
-
if (boundControlContext(env)) {
|
|
35
|
-
throw runtimeError(
|
|
36
|
-
'AGENT_INFRA_RUNTIME_DIR_REQUIRED',
|
|
37
|
-
'task-bound control context requires AGENT_INFRA_RUNTIME_DIR'
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
return path.join(path.resolve(options.repoRoot ?? process.cwd()), '.agents', 'workspace', '.runtime');
|
|
41
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { resolveTaskRef } from './resolve-ref.ts';
|
|
4
|
-
|
|
5
|
-
export function resolveTaskRuntimeRoot(
|
|
6
|
-
taskRef: string,
|
|
7
|
-
options: Readonly<{ repoRoot?: string }> = {}
|
|
8
|
-
): string {
|
|
9
|
-
const resolved = resolveTaskRef(taskRef, options);
|
|
10
|
-
if (!resolved.ok) throw new Error(`${resolved.code}: ${resolved.message}`);
|
|
11
|
-
return path.join(fs.realpathSync.native(resolved.taskDir), '.runtime');
|
|
12
|
-
}
|