@fitlab-ai/agent-infra 0.10.0 → 0.11.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/README.md +2 -6
- package/README.zh-CN.md +2 -6
- package/bin/internal-cli.sh +0 -13
- package/dist/bin/internal-cli.js +11 -49
- package/dist/lib/internal/cli-route-inventory.js +3 -4
- package/dist/lib/internal/platform-comment.js +60 -2
- package/dist/lib/internal/task-artifact.js +1 -1
- package/dist/lib/internal/task-finalization.js +2 -2
- package/dist/lib/internal/task-lifecycle.js +2 -2
- package/dist/lib/internal/task-operation-registry.js +22 -12
- package/dist/lib/internal/task-orchestration.js +2 -2
- package/dist/lib/internal/task-review.js +10 -5
- package/dist/lib/platform/activity-recovery.js +159 -0
- package/dist/lib/platform/issue-comments.js +84 -32
- package/dist/lib/platform/task-comment-projection.js +70 -0
- package/dist/lib/platform/task-recovery.js +55 -0
- package/dist/lib/platform/verification-sync.js +43 -9
- package/dist/lib/sandbox/control/executor.js +4 -2
- package/dist/lib/sandbox/control/task-workflow.js +1 -1
- package/dist/lib/sandbox/control/workflow-executor.js +83 -21
- package/dist/lib/server/process-state.js +17 -5
- package/dist/lib/task/artifact-command.js +6 -3
- package/dist/lib/task/artifact-operations.js +1 -1
- package/dist/lib/task/artifact-recovery.js +114 -68
- package/dist/lib/task/artifact-repair-intent.js +25 -8
- package/dist/lib/task/control-authority.js +1 -1
- package/dist/lib/task/events.js +6 -6
- package/dist/lib/task/intermediate-cleanup.js +28 -3
- package/dist/lib/task/local-artifact-finalization.js +78 -14
- package/dist/lib/task/review-command.js +2 -2
- package/dist/lib/task/review-finalization.js +203 -10
- package/dist/lib/{host-control → task}/secure-fs.js +8 -19
- package/dist/lib/task/workflow-command.js +2 -0
- package/dist/lib/task/workflow-dispatch.js +161 -0
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/internal/cli-route-inventory.ts +3 -4
- package/lib/internal/platform-comment.ts +53 -2
- package/lib/internal/task-artifact.ts +1 -1
- package/lib/internal/task-finalization.ts +1 -1
- package/lib/internal/task-lifecycle.ts +1 -1
- package/lib/internal/task-operation-registry.ts +22 -12
- package/lib/internal/task-orchestration.ts +1 -1
- package/lib/internal/task-review.ts +9 -5
- package/lib/platform/activity-recovery.ts +179 -0
- package/lib/platform/issue-comments.ts +98 -31
- package/lib/platform/task-comment-projection.ts +79 -0
- package/lib/platform/task-recovery.ts +54 -0
- package/lib/platform/verification-sync.ts +46 -13
- package/lib/sandbox/control/executor.ts +4 -2
- package/lib/sandbox/control/protocol.ts +1 -1
- package/lib/sandbox/control/task-workflow.ts +1 -1
- package/lib/sandbox/control/workflow-executor.ts +102 -21
- package/lib/server/process-state.ts +26 -5
- package/lib/task/artifact-command.ts +6 -4
- package/lib/task/artifact-operations.ts +1 -1
- package/lib/task/artifact-recovery.ts +120 -67
- package/lib/task/artifact-repair-intent.ts +38 -11
- package/lib/task/control-authority.ts +1 -1
- package/lib/task/events.ts +6 -6
- package/lib/task/intermediate-cleanup.ts +18 -2
- package/lib/task/local-artifact-finalization.ts +85 -11
- package/lib/task/review-command.ts +1 -1
- package/lib/task/review-finalization.ts +203 -8
- package/lib/{host-control → task}/secure-fs.ts +10 -32
- package/lib/task/workflow-command.ts +2 -0
- package/lib/task/workflow-dispatch.ts +171 -0
- package/package.json +1 -1
- package/templates/.agents/rules/issue-sync.en.md +9 -1
- package/templates/.agents/rules/issue-sync.zh-CN.md +10 -3
- package/templates/.agents/rules/local-artifact-repair.en.md +7 -6
- package/templates/.agents/rules/local-artifact-repair.zh-CN.md +10 -8
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/restore-task/SKILL.en.md +9 -4
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +9 -4
- package/templates/.agents/skills/review-analysis/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/review-code/SKILL.en.md +3 -2
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +3 -2
- package/templates/.agents/skills/review-plan/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +1 -1
- package/dist/lib/host-control/audit.js +0 -19
- package/dist/lib/host-control/client.js +0 -142
- package/dist/lib/host-control/command.js +0 -49
- package/dist/lib/host-control/path.js +0 -160
- package/dist/lib/host-control/server.js +0 -159
- package/dist/lib/host-control/service.js +0 -112
- package/dist/lib/internal/host-control.js +0 -28
- package/lib/host-control/audit.ts +0 -22
- package/lib/host-control/client.ts +0 -172
- package/lib/host-control/command.ts +0 -60
- package/lib/host-control/path.ts +0 -167
- package/lib/host-control/server.ts +0 -180
- package/lib/host-control/service.ts +0 -133
- package/lib/internal/host-control.ts +0 -28
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
| `artifactChunk` | `<!-- sync-issue:{task-id}:{artifact-stem}:{part}/{total} -->` |
|
|
14
14
|
| `summary` | `<!-- sync-issue:{task-id}:summary -->` |
|
|
15
15
|
| `cancel` | `<!-- sync-issue:{task-id}:cancel -->` |
|
|
16
|
+
| `recoveryAction` | `<!-- sync-issue:{task-id}:recovery-action:{action-id} -->` |
|
|
17
|
+
| `recoveryPrepare` | `<!-- sync-issue:{task-id}:recovery-prepare:{commit-id} -->` |
|
|
18
|
+
| `recoveryCommit` | `<!-- sync-issue:{task-id}:recovery-commit:{commit-id} -->` |
|
|
16
19
|
|
|
17
20
|
`prSummary` 属于 `.agents/rules/pr-sync.md`,本规则不实现 PR 聚合。
|
|
18
21
|
|
|
@@ -25,15 +28,19 @@
|
|
|
25
28
|
```bash
|
|
26
29
|
agent-infra-internal platform-context resolve [--cwd <path>]
|
|
27
30
|
agent-infra-internal platform-comment list --issue <issue-token> [--cwd <path>]
|
|
31
|
+
agent-infra-internal platform-comment recover --issue <issue-token> --task-id <TASK-id> \
|
|
32
|
+
--output <.agents/workspace/.restore-staging-*/task.md> [--cwd <path>]
|
|
28
33
|
agent-infra-internal platform-comment owner <task-ref>
|
|
29
34
|
agent-infra-internal platform-comment sync <task-ref> \
|
|
30
|
-
--kind task|artifact|summary|cancel --agent {standard-agent-token} \
|
|
35
|
+
--kind task|artifact|summary|cancel|recovery-action|recovery-prepare|recovery-commit --agent {standard-agent-token} \
|
|
31
36
|
[--artifact <canonical.md>] [--body-file <path|->] [--backfill]
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
- `applied|no-op|degraded` → exit 0;`failed` → exit 1;`blocked` → exit 2。
|
|
35
|
-
- task 评论保持 `<details>` frontmatter
|
|
36
|
-
-
|
|
40
|
+
- task 评论保持 `<details>` frontmatter 可逆格式,只同步确定性的当前任务投影;活动日志、产物生命周期收据、失效记录等过程章节由 recovery 事务保存。artifact 原文内联并在超过 profile 上限时使用 `artifactChunk`。
|
|
41
|
+
- 长度预检与 platform verification 使用同一最终渲染正文的 UTF-8 字节数。正文超限时失败关闭;本地 task 文件不会被截断。
|
|
42
|
+
|
|
43
|
+
恢复评论使用 `recovery-action`、`recovery-prepare` 和 `recovery-commit` marker,并携带稳定 recovery id 和 body file。task 同步按 prepare、action、task snapshot 写入并复读、commit 的顺序发布。相同内容重放返回 `no-op`;已有恢复 marker 的正文不同返回 `RECOVERY_IMMUTABLE_CONFLICT`。restore 只接受作者一致、分片完整、phase/摘要/marker 匹配且绑定当前 task 评论正文 SHA-256 的完整事务。
|
|
37
44
|
- 相同 intent 重放必须收敛为 `no-op`;重复 marker 返回 `COMMENT_MARKER_CONFLICT` 且不写入。
|
|
38
45
|
- 外部贡献者锁定统一使用 `platform-comment owner`;不同作者且无 triage 时返回 `COMMENT_OWNER_CONFLICT`。
|
|
39
46
|
|
|
@@ -7,8 +7,8 @@ This rule covers the pre-completion gate for `analyze-task`, `plan-task`, and `c
|
|
|
7
7
|
- Run the applicable finalizer before a completed event; pass only that invocation's `artifactSha256` and `semanticDigest` to the event.
|
|
8
8
|
- When artifact content is invalid, the finalizer returns a controlled `recovery` with a `recoveryId`, `candidatePath`, and baseline digests. The formal artifact remains unchanged until recovery commit.
|
|
9
9
|
- After the mechanical safety gates pass, the model may edit only the returned `candidatePath`. After each byte-changing edit, rerun the complete finalizer with the same task, stage/family, artifact, and `--recovery-id`. Never edit the formal artifact directly and call it a candidate.
|
|
10
|
-
-
|
|
11
|
-
-
|
|
10
|
+
- Preflight stable-reads and validates candidate `S`, then seals immutable digest-addressed generation `R`; candidate SHA is an observation rather than an edit guard.
|
|
11
|
+
- Preflight publishes active `R` through `preflight-ready → preflight-commit-started → preflight-passed`; the business finalizer publishes `F` through `full-finalizer-ready → commit-started → passed` and reuses `R` when `F=R`.
|
|
12
12
|
- Candidate-only is a protocol authorization boundary, not OS isolation: a same-UID process with arbitrary host filesystem write access may tamper with recovery internals. Identity, fingerprint, and state checks detect such anomalies and fail closed, but the protocol does not claim an independent security principal or cross-platform isolation.
|
|
13
13
|
|
|
14
14
|
## Authorization boundary
|
|
@@ -32,14 +32,15 @@ If any condition fails, stop without editing or publishing a completed event.
|
|
|
32
32
|
|
|
33
33
|
| State | Formal artifact | Allowed action |
|
|
34
34
|
| --- | --- | --- |
|
|
35
|
-
| `awaiting-recovery` | baseline `B` | Edit
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
35
|
+
| `awaiting-preflight-recovery` | baseline `B` | Edit `S`; stable-read, validate, and create `R` |
|
|
36
|
+
| `preflight-ready` / `preflight-commit-started` | `B` or `R` | Reconcile/publish only active immutable `R` |
|
|
37
|
+
| `preflight-passed` | `R` | Run the business finalizer for `F` |
|
|
38
|
+
| `full-finalizer-ready` / `commit-started` | `R` or `F` | Reconcile/publish only pending immutable `F` |
|
|
38
39
|
| `passed` | `F` | Completed event validates the final digest and consumes the intent |
|
|
39
40
|
| `consumed` | `F` | Cleanup may reclaim the controlled staging and backup |
|
|
40
41
|
| `aborted` | verified restored `B` | Preserve diagnostics; never fabricate success |
|
|
41
42
|
|
|
42
|
-
The intent is current-only schema version
|
|
43
|
+
The intent is current-only schema version 4. Legacy schemas fail closed; do not add migration, adapters, or dual writes. Candidate, baseline, generation, and intent files live in controlled repo-local directories and use canonical recovery IDs, regular-file checks, stable reads, the task lock, and expected-value CAS. No cross-file atomicity is claimed; unknown combinations remain indeterminate and retain their evidence.
|
|
43
44
|
|
|
44
45
|
## Dynamic convergence loop
|
|
45
46
|
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
## 完成前门禁
|
|
6
6
|
|
|
7
7
|
- 完成事件前必须运行对应 finalizer;只有同一次返回的 `artifactSha256` 和 `semanticDigest` 才能传给 completed event。
|
|
8
|
-
-
|
|
8
|
+
- preflight 先对当前 stable-read candidate 完整验证,并将验证的 `R` 写入 digest-addressed、只读的 generation;在 journal CAS 前正式 artifact 必须保持 baseline `B`。
|
|
9
|
+
- candidate SHA 是 awaiting 状态的最后一次 stable-read 观测值,不是下一次编辑的 guard。合法 `S` 编辑必须重新验证并在成功后 CAS 为 `R`。
|
|
9
10
|
- 只有在机械安全门通过后,模型才可编辑返回的 `candidatePath`;每次实际字节变化后,用同一 task、stage/family、artifact 和 `--recovery-id` 完整重跑 finalizer。不得直接编辑正式 artifact 后假设它属于候选。
|
|
10
|
-
-
|
|
11
|
-
-
|
|
11
|
+
- preflight 按 `preflight-ready → preflight-commit-started → preflight-passed` 发布 immutable `R`;业务 finalizer 再按 `full-finalizer-ready → commit-started → passed` 将 `F` 发布。`F=R` 复用 active generation。
|
|
12
|
+
- preflight-ready 后 publish 只读取 active/pending generation,绝不再读取可编辑 candidate。
|
|
12
13
|
- candidate-only 是协议授权边界,不是操作系统隔离:拥有同一 UID 且可任意写入宿主文件系统的进程可能篡改 recovery 内部文件;协议会通过身份、指纹和状态校验发现异常并失败关闭,但不承诺独立权限主体或跨平台隔离。
|
|
13
14
|
|
|
14
15
|
## 授权边界
|
|
@@ -32,14 +33,15 @@
|
|
|
32
33
|
|
|
33
34
|
| 状态 | formal artifact | 允许动作 |
|
|
34
35
|
| --- | --- | --- |
|
|
35
|
-
| `awaiting-recovery` | baseline `B` |
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
36
|
+
| `awaiting-preflight-recovery` | baseline `B` | 只编辑 candidate `S`,稳定读取、验证并生成 `R` |
|
|
37
|
+
| `preflight-ready` / `preflight-commit-started` | `B` 或 `R` | 只可从 active immutable `R` reconcile/publish |
|
|
38
|
+
| `preflight-passed` | `R` | 执行业务 finalizer,生成或复用 `F` |
|
|
39
|
+
| `full-finalizer-ready` / `commit-started` | `R` 或 `F` | 只可从 pending immutable `F` reconcile/publish |
|
|
38
40
|
| `passed` | `F` | completed event 校验 final digest 后消费 |
|
|
39
41
|
| `consumed` | `F` | 可由中间产物清理流程回收受控 staging/backup |
|
|
40
42
|
| `aborted` | 已确认恢复的 `B` | 只保留诊断,不得伪造成功 |
|
|
41
43
|
|
|
42
|
-
intent 使用 current-only schema version
|
|
44
|
+
intent 使用 current-only schema version 4。旧 schema 直接失败关闭;不添加迁移、adapter 或双写。candidate、baseline、generation 和 intent 位于 repo-local 受控目录,使用 canonical recovery ID、普通文件检查、stable read、task lock 和 expected-value CAS。跨文件不宣称原子性;未知组合返回 indeterminate 并保留现场。
|
|
43
45
|
|
|
44
46
|
## 动态收敛循环
|
|
45
47
|
|
|
@@ -50,7 +52,7 @@ intent 使用 current-only schema version 3。旧 schema 直接失败关闭;
|
|
|
50
52
|
|
|
51
53
|
## 共享入口
|
|
52
54
|
|
|
53
|
-
`task-artifact ... inspect|init|finalize-local` 和 `task-review ... finalize-summary`
|
|
55
|
+
`task-artifact ... inspect|init|preflight|finalize-local` 和 `task-review ... finalize-summary` 是当前入口。preflight 不发布 task metadata、ledger、formal provenance、completed event 或平台状态;恢复重试使用 finalizer 返回的 `recoveryId`,例如:
|
|
54
56
|
|
|
55
57
|
```text
|
|
56
58
|
agent-infra-internal task-artifact {task-id} finalize-local --family code --artifact {code-artifact} --recovery-id {recovery-id}
|
|
@@ -24,7 +24,7 @@ Before generating the implementation report, read `.agents/rules/evidence-report
|
|
|
24
24
|
- Before generating task or lifecycle Markdown that will be synchronized to an Issue, read `.agents/rules/sync-content-generation.md` and apply its producer-side constraints; the sync path does not parse or rewrite the body
|
|
25
25
|
- Read `.agents/rules/compatibility-policy.md` before implementation. Implement only the compatibility budget explicitly approved by the plan; never retain old branches, result contracts, or migration shims merely to be “safe”
|
|
26
26
|
- Fix mode verifies each finding of the latest `review-code` one by one: fix it if it holds, or rebut it and record it under unresolved if it is unfounded/hallucinated; do not expand to issues the review did not list; manual-validation items are out of scope
|
|
27
|
-
- Before `code.completed`, the implementation report must pass `task-artifact ...
|
|
27
|
+
- Before a checkpoint, ledger write, or `code.completed`, the implementation report must pass `task-artifact ... preflight --family code`. Preflight only validates and seals a generation; `finalize-local` publishes the matching final digest later.
|
|
28
28
|
- If implementation encounters a key design decision not covered by the plan, run `agent-infra-internal task-ledger {task-id} decision-next-id`, write the returned `HD-N` detail block per `.agents/rules/human-decision-context.md` and determine whether implementation is required, then run `decision-upsert --id {HD-N} --stage code --artifact {code-artifact} --needs-implementation {true|false}`. Do not scan ids, assemble ledger rows, ask mid-flow, or silently expand scope
|
|
29
29
|
- Do not invoke the `commit` skill or push to a remote; after tests pass, call the shared commit core with `delivery: { mode: 'local' }` to create the local checkpoint. The durable intent must close only after the checkpoint and task state sync succeed; only then emit `code.completed`
|
|
30
30
|
- Create a new code artifact for each round and never overwrite an older one
|
|
@@ -24,7 +24,7 @@ description: >
|
|
|
24
24
|
- 生成会同步到 Issue 的任务或生命周期 Markdown 前,先读取 `.agents/rules/sync-content-generation.md` 并遵循其中的生成端约束;同步端不解析或改写正文
|
|
25
25
|
- 实现前读取 `.agents/rules/compatibility-policy.md`;只实现方案明确批准的兼容预算,不以“稳妥”为由保留旧分支、旧结果契约或迁移 shim
|
|
26
26
|
- 修复模式逐条核实最新 `review-code` 的发现:成立则修复,判定为不成立/幻觉则在报告中反驳并记入 unresolved;不擅自扩大到审查未列出的问题;manual-validation 项不在修复范围
|
|
27
|
-
- 实现报告在 `code.completed`
|
|
27
|
+
- 实现报告在 checkpoint、账本和 `code.completed` 前必须先通过 `task-artifact ... preflight --family code`;preflight 只验证并封存 generation,不发布 formal/task/ledger/platform 状态。随后 `finalize-local` 才发布同一次通过的 digest。
|
|
28
28
|
- 实现中遇到方案未覆盖的关键设计决策时,先调用 `agent-infra-internal task-ledger {task-id} decision-next-id` 取得 `HD-N`,按 `.agents/rules/human-decision-context.md` 写入实现报告的 `## 人工裁决待办` 详情块并判断是否需要实现,再调用 `decision-upsert --id {HD-N} --stage code --artifact {code-artifact} --needs-implementation {true|false}`;不得扫描编号、手写账本行、中途提问或擅自扩范围
|
|
29
29
|
- 不调用 `commit` 技能,也不推送远端;测试通过后直接调用共享 commit core 的 `delivery: { mode: 'local' }` 创建本地 checkpoint。checkpoint 使用 durable intent,只有 checkpoint 与 task 状态同步成功后才发送 `code.completed`
|
|
30
30
|
- 每轮实现都创建新的实现产物,不覆盖旧文件
|
|
@@ -148,7 +148,7 @@ echo "$result"
|
|
|
148
148
|
|
|
149
149
|
如果测试失败,先尝试修复并重新运行测试。只有在确认存在外部阻塞、环境缺失或需求不明确且超出任务范围时,才可以停止。
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
测试通过后,先创建报告并运行 `task-artifact {task-id} preflight --family code --artifact {code-artifact}`;preflight 失败只允许在同一受控 candidate 中修复并完整重跑,且不得产生 checkpoint、ledger、completed 或平台副作用。preflight 通过后,才通过 `agent-infra-internal git-workflow commit --input {checkpoint-input}` 调用共享 commit core,输入 `delivery: { "mode": "local" }`、明确 paths、expected HEAD/tree、task ref、agent 和 code round。该调用只创建本地 checkpoint,不访问远端;core 会在 commit 前写入 durable intent,并在 task writer 成功后清理 intent。checkpoint 失败或 task 状态未闭合时,不得发送 `code.completed`。
|
|
152
152
|
|
|
153
153
|
checkpoint 成功后,若任务存在 `platform_issue_identity`,调用 `agent-infra-internal platform-issue sync {task-id} --agent {standard-agent-token} --in-labels from-diff --base {delivery-base-ref}`,由 task-bound `delivery_base_ref` 产生 Issue 的 `in:` target;该同步失败时记录 warning 并停止本轮,不发送 `code.completed`。
|
|
154
154
|
|
|
@@ -45,13 +45,14 @@ Run `agent-infra-internal platform-comment list --issue {issue-token}` to read a
|
|
|
45
45
|
|
|
46
46
|
### 3. Determine the task-id and Files to Restore
|
|
47
47
|
|
|
48
|
-
Filter comments by the task, artifact,
|
|
48
|
+
Filter comments by the task, artifact, chunked artifact, and recovery markers defined in `.agents/rules/issue-sync.md`.
|
|
49
49
|
|
|
50
50
|
Rules:
|
|
51
51
|
- when `{task-id}` was provided, match only that task
|
|
52
52
|
- when `{task-id}` was omitted, infer it from the task comment marker first
|
|
53
53
|
- if you cannot determine a unique task-id, stop and tell the user
|
|
54
54
|
- ignore `summary` marker comments because they are complete-task aggregate output rather than restorable local task files
|
|
55
|
+
- use the `task` comment only for the current projection and snapshot identity; the controlled recovery core validates `recovery-action`, `recovery-prepare`, and `recovery-commit` comments and reconstructs the complete `task.md`
|
|
55
56
|
- map `{file-stem}` back to filenames:
|
|
56
57
|
- `task` -> `task.md`
|
|
57
58
|
- `analysis` / `analysis-r{N}` -> matching `.md`
|
|
@@ -68,7 +69,7 @@ Read `.agents/rules/issue-sync.md` before executing this step.
|
|
|
68
69
|
|
|
69
70
|
For each file:
|
|
70
71
|
- collect its single comment or chunked comments
|
|
71
|
-
-
|
|
72
|
+
- do not reverse the projected task comment directly into `task.md`; the complete task content must come from a recovery commit matching the current projection
|
|
72
73
|
- when a chunk marker includes part and total indexes, sort by part and verify the set is complete
|
|
73
74
|
- extract the file body by removing the hidden marker, heading, and footer
|
|
74
75
|
- concatenate chunk bodies into the final file content
|
|
@@ -83,10 +84,14 @@ If the directory already exists, stop immediately and tell the user to handle it
|
|
|
83
84
|
|
|
84
85
|
Create the controlled staging directory and write files back in this order:
|
|
85
86
|
|
|
86
|
-
1. `task.md
|
|
87
|
+
1. call the recovery core to write `task.md`:
|
|
88
|
+
```bash
|
|
89
|
+
agent-infra-internal platform-comment recover --issue {issue-token} --task-id {task-id} \
|
|
90
|
+
--output "{staging-dir}/task.md"
|
|
91
|
+
```
|
|
87
92
|
2. every other restored artifact file in filename order
|
|
88
93
|
|
|
89
|
-
Write only files that were actually recovered from Issue comments. Do not invent missing files.
|
|
94
|
+
Write only files that were actually recovered from Issue comments. Do not invent missing files. Stop without calling the lifecycle intent if the recovery core fails.
|
|
90
95
|
|
|
91
96
|
### 6. Apply the Restore Lifecycle Intent
|
|
92
97
|
|
|
@@ -44,13 +44,14 @@ description: >
|
|
|
44
44
|
|
|
45
45
|
### 3. 确定 task-id 与待恢复文件
|
|
46
46
|
|
|
47
|
-
按 `.agents/rules/issue-sync.md` 中定义的 task、artifact
|
|
47
|
+
按 `.agents/rules/issue-sync.md` 中定义的 task、artifact、分片 artifact 和 recovery 标记筛选评论。
|
|
48
48
|
|
|
49
49
|
处理规则:
|
|
50
50
|
- 用户提供了 `{task-id}` 时,仅匹配该任务
|
|
51
51
|
- 未提供时,优先从 task 评论标记推断
|
|
52
52
|
- 若找不到唯一 task-id,立即停止并告知用户
|
|
53
53
|
- 忽略 `summary` 标记评论;它是 complete-task 的聚合产物,不对应本地任务文件
|
|
54
|
+
- `task` 评论仅用于确定当前投影和 snapshot 身份;`recovery-action`、`recovery-prepare`、`recovery-commit` 由受控 recovery core 验证并重建完整 `task.md`
|
|
54
55
|
- 将 `{file-stem}` 映射回文件名:
|
|
55
56
|
- `task` -> `task.md`
|
|
56
57
|
- `analysis` / `analysis-r{N}` -> 对应 `.md`
|
|
@@ -67,7 +68,7 @@ description: >
|
|
|
67
68
|
|
|
68
69
|
对每个文件执行:
|
|
69
70
|
- 收集单条评论或分片评论
|
|
70
|
-
-
|
|
71
|
+
- 不直接把投影 task 评论反向拆成 `task.md`;完整 task 内容必须来自匹配当前投影的 recovery commit
|
|
71
72
|
- 如分片标记中存在 part 和 total 序号,按 part 升序排序并校验分片完整
|
|
72
73
|
- 从评论正文中提取文件内容,去掉隐藏标记、标题和页脚
|
|
73
74
|
- 拼接得到最终文件内容
|
|
@@ -82,10 +83,14 @@ description: >
|
|
|
82
83
|
|
|
83
84
|
创建受控 staging 目录,按以下顺序写回:
|
|
84
85
|
|
|
85
|
-
1. `task.md
|
|
86
|
+
1. 调用 recovery core 写入 `task.md`:
|
|
87
|
+
```bash
|
|
88
|
+
agent-infra-internal platform-comment recover --issue {issue-token} --task-id {task-id} \
|
|
89
|
+
--output "{staging-dir}/task.md"
|
|
90
|
+
```
|
|
86
91
|
2. 其余产物文件(按文件名排序)
|
|
87
92
|
|
|
88
|
-
仅写回从 Issue 评论中实际恢复出的文件,不补造缺失文件。
|
|
93
|
+
仅写回从 Issue 评论中实际恢复出的文件,不补造缺失文件。recovery core 返回失败时停止,不调用 lifecycle intent。
|
|
89
94
|
|
|
90
95
|
### 6. 执行 restore 生命周期意图
|
|
91
96
|
|
|
@@ -83,7 +83,7 @@ Create `.agents/workspace/active/{task-id}/{review-artifact}`.
|
|
|
83
83
|
|
|
84
84
|
### 6. Update Task Status
|
|
85
85
|
|
|
86
|
-
After the report, submit each new finding with `agent-infra-internal task-ledger {task-id} finding-upsert --stage analysis --review-artifact {review-artifact} --ordinal {n} --severity {blocker|major|minor} --evidence {review-artifact}#{anchor}
|
|
86
|
+
After the report, call `agent-infra-internal task-review {task-id} preflight --stage analysis --artifact {review-artifact} {execution-flag}` before any ledger write. On failure, follow `.agents/rules/local-artifact-repair.md`; on success, bind `{recovery-id}` from the response. Only after preflight passes, submit each new finding with `agent-infra-internal task-ledger {task-id} finding-upsert --stage analysis --review-artifact {review-artifact} --ordinal {n} --severity {blocker|major|minor} --evidence {review-artifact}#{anchor}` or prior-response dispositions with `finding-review --id {ledger-id} --status {confirmed|closed|open|needs-human-decision} --evidence {evidence}`. Do not scan ids or edit ledger rows. After all ledger writes, call `agent-infra-internal task-review {task-id} finalize-summary --stage analysis --artifact {review-artifact} --recovery-id {recovery-id} {execution-flag}`; never treat an error type or `changed=false` as automatic authorization.
|
|
87
87
|
|
|
88
88
|
Bind and reuse this structured mapping from that one response:
|
|
89
89
|
|
|
@@ -86,7 +86,7 @@ agent-infra-internal task-artifact {task-id} init --family review-analysis --art
|
|
|
86
86
|
|
|
87
87
|
### 6. 更新任务状态
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
报告完成后,先调用 `agent-infra-internal task-review {task-id} preflight --stage analysis --artifact {review-artifact} {execution-flag}`,不得先写入账本。失败后是否继续编辑并重跑,必须遵循 `.agents/rules/local-artifact-repair.md`;通过时从返回值绑定 `{recovery-id}`。只有 preflight 通过后,才逐条调用 `agent-infra-internal task-ledger {task-id} finding-upsert --stage analysis --review-artifact {review-artifact} --ordinal {n} --severity {blocker|major|minor} --evidence {review-artifact}#{anchor}`,或复核上一轮响应时调用 `finding-review --id {ledger-id} --status {confirmed|closed|open|needs-human-decision} --evidence {相称证据}`。不得扫描编号或手写账本行。全部账本写入完成后调用 `agent-infra-internal task-review {task-id} finalize-summary --stage analysis --artifact {review-artifact} --recovery-id {recovery-id} {execution-flag}`;不能把失败类型或 `changed=false` 当作自动授权。
|
|
90
90
|
|
|
91
91
|
从该次返回值绑定并复用以下结构化映射:
|
|
92
92
|
|
|
@@ -111,8 +111,9 @@ Create `.agents/workspace/active/{task-id}/{review-artifact}`.
|
|
|
111
111
|
### 6. Update Task Status
|
|
112
112
|
|
|
113
113
|
Update task.md:
|
|
114
|
-
- After the report,
|
|
115
|
-
-
|
|
114
|
+
- After the report, call `agent-infra-internal task-review {task-id} preflight --stage code --artifact {review-artifact} {execution-flag}` before any ledger write. On failure, follow `.agents/rules/local-artifact-repair.md`; on success, bind `{recovery-id}` from the response.
|
|
115
|
+
- Only after preflight passes, submit each new finding with `agent-infra-internal task-ledger {task-id} finding-upsert --stage code --review-artifact {review-artifact} --ordinal {n} --severity {blocker|major|minor} --evidence {review-artifact}#{anchor}`; submit prior-response dispositions with `finding-review --id {ledger-id} --status {confirmed|closed|open|needs-human-decision} --evidence {evidence}`. When escalating to `needs-human-decision`, append `--needs-implementation true|false` using the judgment recorded in the detail block. Do not scan ids or edit ledger rows
|
|
116
|
+
- After all ledger writes, call `agent-infra-internal task-review {task-id} finalize-summary --stage code --artifact {review-artifact} --recovery-id {recovery-id} {execution-flag}`; never treat an error type or `changed=false` as automatic authorization
|
|
116
117
|
|
|
117
118
|
Bind and reuse this structured mapping from that one response:
|
|
118
119
|
|
|
@@ -109,8 +109,9 @@ agent-infra-internal task-artifact {task-id} init --family review-code --artifac
|
|
|
109
109
|
|
|
110
110
|
### 6. 更新任务状态
|
|
111
111
|
|
|
112
|
-
-
|
|
113
|
-
-
|
|
112
|
+
- 报告完成后,先调用 `agent-infra-internal task-review {task-id} preflight --stage code --artifact {review-artifact} {execution-flag}`,不得先写入账本。失败后是否继续编辑并重跑,必须遵循 `.agents/rules/local-artifact-repair.md`;通过时从返回值绑定 `{recovery-id}`。
|
|
113
|
+
- 只有 preflight 通过后,新 finding 才逐条调用 `agent-infra-internal task-ledger {task-id} finding-upsert --stage code --review-artifact {review-artifact} --ordinal {n} --severity {blocker|major|minor} --evidence {review-artifact}#{anchor}`;复核上一轮响应时调用 `finding-review --id {ledger-id} --status {confirmed|closed|open|needs-human-decision} --evidence {相称证据}`。升级为 `needs-human-decision` 时,按详情块中的判断追加 `--needs-implementation true|false`。不得扫描编号或手写账本行
|
|
114
|
+
- 全部账本写入完成后调用 `agent-infra-internal task-review {task-id} finalize-summary --stage code --artifact {review-artifact} --recovery-id {recovery-id} {execution-flag}`;不能把失败类型或 `changed=false` 当作自动授权
|
|
114
115
|
|
|
115
116
|
从该次返回值绑定并复用以下结构化映射:
|
|
116
117
|
|
|
@@ -83,7 +83,7 @@ Create `.agents/workspace/active/{task-id}/{review-artifact}`.
|
|
|
83
83
|
|
|
84
84
|
### 6. Update Task Status
|
|
85
85
|
|
|
86
|
-
After the report, submit each new finding with `agent-infra-internal task-ledger {task-id} finding-upsert --stage plan --review-artifact {review-artifact} --ordinal {n} --severity {blocker|major|minor} --evidence {review-artifact}#{anchor}
|
|
86
|
+
After the report, call `agent-infra-internal task-review {task-id} preflight --stage plan --artifact {review-artifact} {execution-flag}` before any ledger write. On failure, follow `.agents/rules/local-artifact-repair.md`; on success, bind `{recovery-id}` from the response. Only after preflight passes, submit each new finding with `agent-infra-internal task-ledger {task-id} finding-upsert --stage plan --review-artifact {review-artifact} --ordinal {n} --severity {blocker|major|minor} --evidence {review-artifact}#{anchor}` or prior-response dispositions with `finding-review --id {ledger-id} --status {confirmed|closed|open|needs-human-decision} --evidence {evidence}`. Do not scan ids or edit ledger rows. After all ledger writes, call `agent-infra-internal task-review {task-id} finalize-summary --stage plan --artifact {review-artifact} --recovery-id {recovery-id} {execution-flag}`; never treat an error type or `changed=false` as automatic authorization.
|
|
87
87
|
|
|
88
88
|
Bind and reuse this structured mapping from that one response:
|
|
89
89
|
|
|
@@ -86,7 +86,7 @@ agent-infra-internal task-artifact {task-id} init --family review-plan --artifac
|
|
|
86
86
|
|
|
87
87
|
### 6. 更新任务状态
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
报告完成后,先调用 `agent-infra-internal task-review {task-id} preflight --stage plan --artifact {review-artifact} {execution-flag}`,不得先写入账本。失败后是否继续编辑并重跑,必须遵循 `.agents/rules/local-artifact-repair.md`;通过时从返回值绑定 `{recovery-id}`。只有 preflight 通过后,才逐条调用 `agent-infra-internal task-ledger {task-id} finding-upsert --stage plan --review-artifact {review-artifact} --ordinal {n} --severity {blocker|major|minor} --evidence {review-artifact}#{anchor}`,或复核上一轮响应时调用 `finding-review --id {ledger-id} --status {confirmed|closed|open|needs-human-decision} --evidence {相称证据}`。不得扫描编号或手写账本行。全部账本写入完成后调用 `agent-infra-internal task-review {task-id} finalize-summary --stage plan --artifact {review-artifact} --recovery-id {recovery-id} {execution-flag}`;不能把失败类型或 `changed=false` 当作自动授权。
|
|
90
90
|
|
|
91
91
|
从该次返回值绑定并复用以下结构化映射:
|
|
92
92
|
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
export const HOST_CONTROL_AUDIT_FILE = 'audit.ndjson';
|
|
4
|
-
export function hostControlAuditPath(endpoint) {
|
|
5
|
-
return path.join(path.dirname(endpoint), HOST_CONTROL_AUDIT_FILE);
|
|
6
|
-
}
|
|
7
|
-
export function appendHostControlAudit(endpoint, entry, at = Date.now()) {
|
|
8
|
-
const filePath = hostControlAuditPath(endpoint);
|
|
9
|
-
const descriptor = fs.openSync(filePath, 'a', 0o600);
|
|
10
|
-
try {
|
|
11
|
-
fs.fchmodSync(descriptor, 0o600);
|
|
12
|
-
fs.writeFileSync(descriptor, `${JSON.stringify({ version: 1, at, ...entry })}\n`, 'utf8');
|
|
13
|
-
fs.fsyncSync(descriptor);
|
|
14
|
-
}
|
|
15
|
-
finally {
|
|
16
|
-
fs.closeSync(descriptor);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=audit.js.map
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import net from 'node:net';
|
|
2
|
-
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { inspectHostControlEndpoint, resolveHostControlEndpoint } from './path.js';
|
|
4
|
-
export const HOST_CONTROL_MAX_REQUEST_BYTES = 64 * 1024;
|
|
5
|
-
export const HOST_CONTROL_COMMANDS = Object.freeze([
|
|
6
|
-
'task-lifecycle', 'task-orchestration', 'task-finalization',
|
|
7
|
-
'task-artifact', 'task-review', 'task-event', 'task-ledger',
|
|
8
|
-
'task-invalidation', 'task-warning'
|
|
9
|
-
]);
|
|
10
|
-
export const HOST_CONTROL_TEST_ENVIRONMENT_KEYS = Object.freeze([
|
|
11
|
-
'TZ', 'AGENT_INFRA_GH_BIN', 'AGENT_INFRA_GH_ARGS_JSON', 'GH_FAKE_PR_PATH', 'GH_FAKE_ARGS_PATH'
|
|
12
|
-
]);
|
|
13
|
-
export class HostControlClientError extends Error {
|
|
14
|
-
code;
|
|
15
|
-
retryable;
|
|
16
|
-
changed;
|
|
17
|
-
constructor(code, message, retryable = false, submitted = false) {
|
|
18
|
-
super(`${code}: ${message}`);
|
|
19
|
-
this.name = 'HostControlClientError';
|
|
20
|
-
this.code = code;
|
|
21
|
-
this.retryable = retryable && !submitted;
|
|
22
|
-
this.changed = submitted ? null : false;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function reject(message) {
|
|
26
|
-
throw new HostControlClientError('HOST_CONTROL_REQUEST_INVALID', message);
|
|
27
|
-
}
|
|
28
|
-
export function validateHostControlRequest(value) {
|
|
29
|
-
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
30
|
-
reject('request must be an object');
|
|
31
|
-
const request = value;
|
|
32
|
-
if (Object.keys(request).sort().join(',') !== 'generation,id,operation,payload,scope,taskId,version'
|
|
33
|
-
|| request.version !== 1 || typeof request.id !== 'string' || !/^[a-f0-9-]{16,64}$/u.test(request.id)
|
|
34
|
-
|| (request.taskId !== null && (typeof request.taskId !== 'string' || !/^TASK-\d{8}-\d{6}$/u.test(request.taskId)))
|
|
35
|
-
|| (request.generation !== null && (typeof request.generation !== 'string' || !request.generation))
|
|
36
|
-
|| request.scope !== 'host-command' || !HOST_CONTROL_COMMANDS.includes(request.operation))
|
|
37
|
-
reject('request schema is invalid');
|
|
38
|
-
const payload = request.payload;
|
|
39
|
-
if (!payload || typeof payload !== 'object' || Array.isArray(payload)
|
|
40
|
-
|| !['args,environment,workingDirectory', 'args,workingDirectory'].includes(Object.keys(payload).sort().join(','))
|
|
41
|
-
|| !Array.isArray(payload.args) || payload.args.length > 128
|
|
42
|
-
|| !payload.args.every((arg) => typeof arg === 'string' && !/[\r\n]/u.test(arg))
|
|
43
|
-
|| typeof payload.workingDirectory !== 'string' || !payload.workingDirectory.startsWith('/'))
|
|
44
|
-
reject('host-command payload is invalid');
|
|
45
|
-
if (payload.environment !== undefined) {
|
|
46
|
-
if (!payload.environment || typeof payload.environment !== 'object' || Array.isArray(payload.environment))
|
|
47
|
-
reject('host-command environment is invalid');
|
|
48
|
-
for (const [key, value] of Object.entries(payload.environment)) {
|
|
49
|
-
if (!HOST_CONTROL_TEST_ENVIRONMENT_KEYS.includes(key)
|
|
50
|
-
|| typeof value !== 'string' || /[\r\n]/u.test(value))
|
|
51
|
-
reject('host-command environment is invalid');
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return request;
|
|
55
|
-
}
|
|
56
|
-
export function hostControlRequestForCommand(command, args, workingDirectory, environment = {}) {
|
|
57
|
-
if (!HOST_CONTROL_COMMANDS.includes(command))
|
|
58
|
-
reject('host-command is unsupported');
|
|
59
|
-
const taskArg = args[0];
|
|
60
|
-
const taskId = taskArg && /^TASK-\d{8}-\d{6}$/u.test(taskArg) ? taskArg : null;
|
|
61
|
-
return validateHostControlRequest({
|
|
62
|
-
version: 1,
|
|
63
|
-
id: randomUUID(),
|
|
64
|
-
taskId,
|
|
65
|
-
generation: null,
|
|
66
|
-
operation: command,
|
|
67
|
-
scope: 'host-command',
|
|
68
|
-
payload: {
|
|
69
|
-
workingDirectory,
|
|
70
|
-
args: [...args],
|
|
71
|
-
...(Object.keys(environment).length > 0 ? { environment } : {})
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
function parseResponse(value, id) {
|
|
76
|
-
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
77
|
-
throw new HostControlClientError('HOST_CONTROL_RESPONSE_INVALID', 'response must be an object');
|
|
78
|
-
const response = value;
|
|
79
|
-
if (Object.keys(response).sort().join(',') !== 'error,exitCode,id,status,stderr,stdout,version'
|
|
80
|
-
|| response.version !== 1 || response.id !== id
|
|
81
|
-
|| !['completed', 'rejected', 'unknown'].includes(response.status)
|
|
82
|
-
|| !Number.isSafeInteger(response.exitCode)
|
|
83
|
-
|| typeof response.stdout !== 'string' || typeof response.stderr !== 'string'
|
|
84
|
-
|| (response.error !== null && (!response.error || typeof response.error !== 'object'))) {
|
|
85
|
-
throw new HostControlClientError('HOST_CONTROL_RESPONSE_INVALID', 'response schema is invalid');
|
|
86
|
-
}
|
|
87
|
-
return response;
|
|
88
|
-
}
|
|
89
|
-
export async function requestHostControl(params) {
|
|
90
|
-
const request = validateHostControlRequest(params.request);
|
|
91
|
-
const endpoint = params.endpoint ?? resolveHostControlEndpoint();
|
|
92
|
-
const inspection = inspectHostControlEndpoint(endpoint, { uid: process.getuid?.() });
|
|
93
|
-
if (!inspection.ok)
|
|
94
|
-
throw new HostControlClientError(inspection.code ?? 'HOST_CONTROL_UNAVAILABLE', 'fixed host-control endpoint is unavailable', true);
|
|
95
|
-
const encoded = `${JSON.stringify(request)}\n`;
|
|
96
|
-
if (Buffer.byteLength(encoded, 'utf8') > HOST_CONTROL_MAX_REQUEST_BYTES)
|
|
97
|
-
throw new HostControlClientError('HOST_CONTROL_REQUEST_TOO_LARGE', 'request exceeds the control limit');
|
|
98
|
-
const timeoutMs = params.timeoutMs ?? 30_000;
|
|
99
|
-
return await new Promise((resolve, rejectPromise) => {
|
|
100
|
-
const socket = net.createConnection(endpoint);
|
|
101
|
-
let output = '';
|
|
102
|
-
let settled = false;
|
|
103
|
-
let submitted = false;
|
|
104
|
-
const failure = (code, message, retryable = false) => new HostControlClientError(code, message, retryable, submitted);
|
|
105
|
-
const finish = (error, response) => {
|
|
106
|
-
if (settled)
|
|
107
|
-
return;
|
|
108
|
-
settled = true;
|
|
109
|
-
clearTimeout(timer);
|
|
110
|
-
socket.destroy();
|
|
111
|
-
if (error)
|
|
112
|
-
rejectPromise(error);
|
|
113
|
-
else
|
|
114
|
-
resolve(response);
|
|
115
|
-
};
|
|
116
|
-
const timer = setTimeout(() => finish(failure('HOST_CONTROL_TIMEOUT', 'host-control did not respond; inspect task state before retrying', true)), timeoutMs);
|
|
117
|
-
socket.setEncoding('utf8');
|
|
118
|
-
socket.on('connect', () => { submitted = true; socket.end(encoded); });
|
|
119
|
-
socket.on('data', (chunk) => {
|
|
120
|
-
output += chunk;
|
|
121
|
-
if (Buffer.byteLength(output, 'utf8') > HOST_CONTROL_MAX_REQUEST_BYTES) {
|
|
122
|
-
finish(failure('HOST_CONTROL_RESPONSE_TOO_LARGE', 'host-control response exceeds the control limit'));
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
const newline = output.indexOf('\n');
|
|
126
|
-
if (newline < 0)
|
|
127
|
-
return;
|
|
128
|
-
try {
|
|
129
|
-
finish(undefined, parseResponse(JSON.parse(output.slice(0, newline)), request.id));
|
|
130
|
-
}
|
|
131
|
-
catch (error) {
|
|
132
|
-
finish(failure('HOST_CONTROL_RESPONSE_INVALID', String(error)));
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
socket.on('error', (error) => finish(failure('HOST_CONTROL_UNAVAILABLE', error.message, true)));
|
|
136
|
-
socket.on('close', () => {
|
|
137
|
-
if (!settled)
|
|
138
|
-
finish(failure('HOST_CONTROL_RESPONSE_INVALID', 'host-control closed without a response'));
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
//# sourceMappingURL=client.js.map
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { readHostControlWorkerToken, resolveHostControlEndpoint } from './path.js';
|
|
5
|
-
export async function dispatchHostControlCommand(request) {
|
|
6
|
-
const { payload } = request;
|
|
7
|
-
const compiledEntry = fileURLToPath(new URL('../../bin/internal-cli.js', import.meta.url));
|
|
8
|
-
const sourceEntry = fileURLToPath(new URL('../../bin/internal-cli.ts', import.meta.url));
|
|
9
|
-
const entry = fs.existsSync(compiledEntry) ? compiledEntry : sourceEntry;
|
|
10
|
-
const payloadEnvironment = payload.environment ?? {};
|
|
11
|
-
const env = { ...process.env, ...payloadEnvironment };
|
|
12
|
-
for (const key of Object.keys(env)) {
|
|
13
|
-
if (key.startsWith('AGENT_INFRA_CONTROL_')
|
|
14
|
-
|| key === 'AGENT_INFRA_TASK_ID'
|
|
15
|
-
|| key === 'AGENT_INFRA_RUNTIME_DIR'
|
|
16
|
-
|| key === 'AGENT_INFRA_EXECUTOR_MANIFEST'
|
|
17
|
-
|| key === 'AGENT_INFRA_HOST_CONTROL_SOCKET') {
|
|
18
|
-
delete env[key];
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
delete env.NODE_OPTIONS;
|
|
22
|
-
delete env.NODE_PATH;
|
|
23
|
-
delete env.AGENT_INFRA_HOST_CONTROL_WORKER;
|
|
24
|
-
delete env.AGENT_INFRA_HOST_CONTROL_WORKER_TOKEN;
|
|
25
|
-
env.AGENT_INFRA_HOST_CONTROL_WORKER = '1';
|
|
26
|
-
env.AGENT_INFRA_HOST_CONTROL_WORKER_TOKEN = readHostControlWorkerToken(process.env.AGENT_INFRA_TEST_HOST_CONTROL_ENDPOINT ?? resolveHostControlEndpoint());
|
|
27
|
-
return await new Promise((resolve, reject) => {
|
|
28
|
-
const runtimeArgs = entry.endsWith('.ts') ? ['--experimental-strip-types', '--no-warnings', entry] : [entry];
|
|
29
|
-
const child = spawn(process.execPath, [...runtimeArgs, request.operation, ...payload.args], {
|
|
30
|
-
cwd: payload.workingDirectory,
|
|
31
|
-
env,
|
|
32
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
33
|
-
});
|
|
34
|
-
let stdout = '';
|
|
35
|
-
let stderr = '';
|
|
36
|
-
child.stdout.setEncoding('utf8');
|
|
37
|
-
child.stderr.setEncoding('utf8');
|
|
38
|
-
child.stdout.on('data', (chunk) => { stdout += chunk; });
|
|
39
|
-
child.stderr.on('data', (chunk) => { stderr += chunk; });
|
|
40
|
-
child.once('error', reject);
|
|
41
|
-
child.once('close', (code, signal) => {
|
|
42
|
-
if (signal)
|
|
43
|
-
reject(new Error(`HOST_CONTROL_WORKER_TERMINATED: ${signal}`));
|
|
44
|
-
else
|
|
45
|
-
resolve({ stdout, stderr, exitCode: code ?? 1 });
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
//# sourceMappingURL=command.js.map
|