@fitlab-ai/agent-infra 0.6.3 → 0.6.5
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 +12 -2
- package/README.zh-CN.md +12 -2
- package/bin/cli.ts +18 -6
- package/dist/bin/cli.js +20 -6
- package/dist/lib/cp.js +127 -0
- package/dist/lib/sandbox/clipboard/bridge.js +30 -9
- package/dist/lib/sandbox/clipboard/darwin.js +7 -14
- package/dist/lib/sandbox/clipboard/index.js +12 -3
- package/dist/lib/sandbox/commands/create.js +11 -0
- package/dist/lib/sandbox/commands/enter.js +20 -3
- package/dist/lib/sandbox/commands/rebuild.js +11 -5
- package/dist/lib/sandbox/host-timezone.js +33 -0
- package/dist/lib/sandbox/index.js +4 -3
- package/dist/lib/sandbox/readme-scaffold.js +148 -0
- package/dist/lib/sandbox/runtimes/ai-tools.dockerfile +2 -0
- package/dist/lib/sandbox/runtimes/base.dockerfile +24 -19
- package/lib/cp.ts +177 -0
- package/lib/sandbox/clipboard/bridge.ts +30 -10
- package/lib/sandbox/clipboard/darwin.ts +15 -14
- package/lib/sandbox/clipboard/index.ts +12 -3
- package/lib/sandbox/commands/create.ts +12 -0
- package/lib/sandbox/commands/enter.ts +41 -3
- package/lib/sandbox/commands/rebuild.ts +15 -5
- package/lib/sandbox/host-timezone.ts +42 -0
- package/lib/sandbox/index.ts +4 -3
- package/lib/sandbox/readme-scaffold.ts +177 -0
- package/lib/sandbox/runtimes/ai-tools.dockerfile +2 -0
- package/lib/sandbox/runtimes/base.dockerfile +24 -19
- package/package.json +7 -7
- package/templates/.agents/rules/create-issue.github.en.md +19 -1
- package/templates/.agents/rules/create-issue.github.zh-CN.md +19 -1
- package/templates/.agents/rules/milestone-inference.github.en.md +12 -0
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +12 -0
- package/templates/.agents/rules/testing-discipline.en.md +44 -0
- package/templates/.agents/rules/testing-discipline.zh-CN.md +44 -0
- package/templates/.agents/skills/create-task/SKILL.en.md +2 -0
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +2 -0
- package/templates/.agents/skills/create-task/config/verify.json +1 -0
- package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
|
@@ -38,3 +38,47 @@ This mirrors "Goal-Driven Execution" in AGENTS.md: define a verifiable success c
|
|
|
38
38
|
- **Over-mocking**: Stub only real boundaries such as network, filesystem, time, or randomness; do not mock the logic of the unit under test, or the test only proves that the mock followed the script.
|
|
39
39
|
- **Testing implementation details**: Prefer assertions on public APIs, artifacts, state changes, or error results; avoid assertions on private functions, internal call order, or temporary data structures.
|
|
40
40
|
- **Insufficient assertions**: Assertions must pin down concrete expected values; do not replace checks on key fields, counts, and boundaries with "does not throw" or "result exists".
|
|
41
|
+
|
|
42
|
+
## Coverage positioning (informational layer)
|
|
43
|
+
|
|
44
|
+
> CI emits coverage via `node --test --experimental-test-coverage` as a hint about "which files are weakly tested". It is **not a merge gate**.
|
|
45
|
+
|
|
46
|
+
### Local run
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run test:coverage
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The tail of stdout prints per-file line / branch / function coverage and the uncovered line numbers.
|
|
53
|
+
|
|
54
|
+
### CI display
|
|
55
|
+
|
|
56
|
+
`.github/workflows/unit-tests.yml` writes the coverage block into the GitHub Actions step summary on the ubuntu-latest shard (visible on the PR Checks page). Windows / macOS shards do not duplicate this output.
|
|
57
|
+
|
|
58
|
+
The Codecov badge at the top of the README is generated by Codecov after `.github/workflows/unit-tests.yml` uploads `coverage.lcov` from the ubuntu-latest shard.
|
|
59
|
+
|
|
60
|
+
### Boundaries
|
|
61
|
+
|
|
62
|
+
- **No percentage thresholds**: Threshold flags such as `--test-coverage-lines/branches/functions` are forbidden. Goodhart's law reminds us that once coverage becomes a metric, developers write "coverage-friendly but behavior-weak" tests.
|
|
63
|
+
- **Third-party services for the badge only**: Codecov hosts the README coverage badge, but the root `codecov.yml` explicitly disables its project/patch status checks and PR comments — Codecov only displays a number here and does not participate in merge decisions. Do not integrate other services such as coveralls.
|
|
64
|
+
- **No tier split**: Coverage is currently emitted only for the full `test` tier; smoke / core tier coverage has no independent value.
|
|
65
|
+
- **Does not block PRs**: The CI step uses `continue-on-error: true`, so a failed coverage collection does not affect merges.
|
|
66
|
+
|
|
67
|
+
### Where New Tests Go
|
|
68
|
+
|
|
69
|
+
The test directory determines which npm script runs a test file:
|
|
70
|
+
|
|
71
|
+
- `tests/unit/<module>/`: fast structural or pure-function tests; does not spawn the real CLI process or depend on external tools, suitable for `test:smoke`.
|
|
72
|
+
- `tests/integration/<module>/`: combines multiple modules, runs CLI subprocesses, touches temporary filesystems, or verifies template sync flows while staying stable and reasonably fast, suitable for `test:core`.
|
|
73
|
+
- `tests/e2e/<module>/`: slower contract, platform-sync, packaged-output, cross-process, or end-to-end workflow tests, run only by full `npm test`.
|
|
74
|
+
|
|
75
|
+
Modules remain as second-level directories such as `cli`, `core`, `scripts`, and `templates`. Shared helpers and fixtures stay in `tests/helpers/`, `tests/helpers.ts`, and `tests/fixtures/`; do not place them under a tier.
|
|
76
|
+
|
|
77
|
+
### Relation to "test tier coverage"
|
|
78
|
+
|
|
79
|
+
Distinguish two concepts:
|
|
80
|
+
|
|
81
|
+
- **Test tier coverage** (`tests/unit/core/test-tier-coverage.test.ts` checks test directory placement and npm script tier mapping): governs "which test files belong to which tier" and is orthogonal to source-line coverage.
|
|
82
|
+
- **Source-line coverage** (this section): governs "which lines of production source are exercised by tests".
|
|
83
|
+
|
|
84
|
+
The two serve different purposes and should not substitute for each other.
|
|
@@ -38,3 +38,47 @@ assert.match(content, /^name: implement-task$/m); // 正向断言已足够
|
|
|
38
38
|
- **mock 过度**:只在网络、文件系统、时间、随机数等真实边界打桩;不要 mock 被测对象自身逻辑,否则测试只验证 mock 是否按预设运行。
|
|
39
39
|
- **测试实现细节**:优先断言公开接口、产物、状态变化或错误结果;避免断言私有函数、内部调用顺序、临时数据结构。
|
|
40
40
|
- **断言不充分**:断言必须锁定具体期望值;不要用"只要不抛异常""结果存在即可"替代对关键字段、数量和边界的验证。
|
|
41
|
+
|
|
42
|
+
## 覆盖率定位(信息层)
|
|
43
|
+
|
|
44
|
+
> CI 中通过 `node --test --experimental-test-coverage` 输出覆盖率,仅作为"哪些文件被测试薄弱"的提示,**不作为 merge gate**。
|
|
45
|
+
|
|
46
|
+
### 本地运行
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run test:coverage
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
stdout 末尾会打印按文件粒度的行 / 分支 / 函数覆盖率以及未覆盖行号。
|
|
53
|
+
|
|
54
|
+
### CI 展示
|
|
55
|
+
|
|
56
|
+
`.github/workflows/unit-tests.yml` 在 ubuntu-latest 分片上把覆盖率块写入 GitHub Actions 的 step summary(PR Checks 页可见)。Windows / macOS 分片不重复输出。
|
|
57
|
+
|
|
58
|
+
README 顶部的 Codecov 徽章由 `.github/workflows/unit-tests.yml` 在 ubuntu-latest 分片上传 `coverage.lcov` 后由 Codecov 生成。
|
|
59
|
+
|
|
60
|
+
### 边界
|
|
61
|
+
|
|
62
|
+
- **不设置百分比阈值**:`--test-coverage-lines/branches/functions` 等阈值参数禁止加入;Goodhart's law 提醒我们一旦把覆盖率作为指标,开发者会写"覆盖率友好但行为弱"的测试。
|
|
63
|
+
- **第三方服务仅用于徽章**:已接入 Codecov 托管 README 覆盖率徽章,但通过根 `codecov.yml` 显式关闭其 project/patch status check 与 PR 评论——Codecov 在本项目只展示数字,不参与 merge 决策。不接入 coveralls 等其他服务。
|
|
64
|
+
- **不区分 tier**:当前只对 full `test` tier 输出覆盖率;smoke / core tier 的覆盖率没有独立价值。
|
|
65
|
+
- **不阻塞 PR**:CI 步骤 `continue-on-error: true`,即便覆盖率采集失败也不影响 merge。
|
|
66
|
+
|
|
67
|
+
### 新测试该放哪一层
|
|
68
|
+
|
|
69
|
+
测试文件放入哪一层决定它会被哪些 npm script 自动执行:
|
|
70
|
+
|
|
71
|
+
- `tests/unit/<module>/`:快速、结构性或纯函数类测试;不启动真实 CLI 子进程,不依赖外部工具,适合 `test:smoke`。
|
|
72
|
+
- `tests/integration/<module>/`:会组合多个模块、运行 CLI 子进程、触达临时文件系统或验证模板同步流程,但仍应保持稳定和相对快速,适合 `test:core`。
|
|
73
|
+
- `tests/e2e/<module>/`:较慢的契约、平台同步、打包产物、跨进程或端到端流程测试,只在完整 `npm test` 中运行。
|
|
74
|
+
|
|
75
|
+
模块继续作为第二级目录(如 `cli`、`core`、`scripts`、`templates`)。共享 helper 和 fixtures 保持在 `tests/helpers/`、`tests/helpers.ts`、`tests/fixtures/`,不要放入任一 tier。
|
|
76
|
+
|
|
77
|
+
### 与"测试 tier 覆盖"的关系
|
|
78
|
+
|
|
79
|
+
注意区分两个概念:
|
|
80
|
+
|
|
81
|
+
- **测试 tier 覆盖**(`tests/unit/core/test-tier-coverage.test.ts` 校验测试文件目录归属与 npm script tier 映射):管的是"哪些测试文件被纳入哪一 tier",与代码行覆盖率正交。
|
|
82
|
+
- **代码行覆盖率**(本节):管的是"业务源码哪些行被测试触达"。
|
|
83
|
+
|
|
84
|
+
两者目的不同,不要相互替代。
|
|
@@ -116,6 +116,8 @@ The rule's content is determined by the configured code platform:
|
|
|
116
116
|
- A platform that supports Issue creation: contains the full flow for auth detection, template detection, label/type/milestone inference, the create-Issue call, and writing back to `task.md`
|
|
117
117
|
- Custom or empty platforms (no platform-specific variant provided): the rule body is a no-op notice, and this step is skipped entirely
|
|
118
118
|
|
|
119
|
+
> **Hard constraint**: the milestone sub-step in `.agents/rules/create-issue.md` §4 is mandatory; missing it fails the step 5 gate (`verify_milestone: true`) and aborts create-task.
|
|
120
|
+
|
|
119
121
|
Handle the result:
|
|
120
122
|
- Rule successfully created the Issue: `issue_number` has been written back to task.md per the rule; continue by reading `.agents/rules/issue-sync.md`, completing upstream repository and permission detection, then sync the task comment and set `status: waiting-for-triage` by rule
|
|
121
123
|
- Rule failed (auth / network / template parse / etc.): do not roll back task.md; do NOT append an extra Activity Log entry; follow "Scenario C: Issue creation failed" output to surface `error_code` and `error_message` to the user so they can decide whether to retry manually or write `issue_number` later
|
|
@@ -116,6 +116,8 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
116
116
|
- 支持 Issue 创建的平台:包含完整的认证检测、模板检测、label/Issue Type/milestone 推断、Issue 创建调用、`task.md` 回写流程
|
|
117
117
|
- 自定义或空平台(未提供平台变体规则文件):内容为 no-op 说明,本步骤直接跳过
|
|
118
118
|
|
|
119
|
+
> **强约束**:`.agents/rules/create-issue.md` §4 中的 milestone 子步骤为必须执行项;漏设会被步骤 5 的 gate(`verify_milestone: true`)截停,导致 create-task 失败。
|
|
120
|
+
|
|
119
121
|
处理结果:
|
|
120
122
|
- 规则成功创建 Issue:`issue_number` 已按规则回写到 task.md;继续读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测,然后同步 task 评论并按规则设置 `status: waiting-for-triage`
|
|
121
123
|
- 规则失败(认证 / 网络 / 模板解析等):不回滚 task.md;不追加额外 Activity Log;按"场景 C:Issue 创建失败"输出向用户透出 `error_code` 与 `error_message`,让用户决定后续是否手动重试或写入 `issue_number`
|
|
@@ -114,7 +114,7 @@ If task.md contains a valid `issue_number`, use the Issue update command from `.
|
|
|
114
114
|
|
|
115
115
|
If task.md contains a valid `issue_number`, perform these sync actions (skip and continue on any failure):
|
|
116
116
|
- Read `.agents/rules/issue-sync.md` before syncing, and complete upstream repository detection plus permission detection
|
|
117
|
-
- Check the Issue's current milestone; if it is unset, read `.agents/rules/milestone-inference.md
|
|
117
|
+
- Check the Issue's current milestone; if it is unset, read `.agents/rules/milestone-inference.md`, infer a release line using "Phase 1: `create-task` (when the platform rule creates an Issue)", and run its "Backfill when called from `import-issue`" subsection to write back to the remote Issue. If inference fails, permissions are insufficient, or write-back fails, skip and continue without blocking the import
|
|
118
118
|
- After every scenario, task comment sync is mandatory: create or update the task comment marker defined in `.agents/rules/issue-sync.md` so the remote `:task` comment exists and matches the local `task.md` content (follow the task.md comment sync rule in issue-sync.md)
|
|
119
119
|
|
|
120
120
|
### 7. Verification Gate
|
|
@@ -114,7 +114,7 @@ date "+%Y-%m-%d %H:%M:%S%:z"
|
|
|
114
114
|
|
|
115
115
|
如果 task.md 中存在有效的 `issue_number`,执行以下同步操作(任一失败则跳过并继续):
|
|
116
116
|
- 执行前先读取 `.agents/rules/issue-sync.md`,完成 upstream 仓库检测和权限检测
|
|
117
|
-
- 检查 Issue 当前 milestone;如果未设置,先读取 `.agents/rules/milestone-inference.md`,按其中的「阶段 1:`create-task`(平台规则创建 Issue
|
|
117
|
+
- 检查 Issue 当前 milestone;如果未设置,先读取 `.agents/rules/milestone-inference.md`,按其中的「阶段 1:`create-task`(平台规则创建 Issue 时)」推断版本线,并按其「`import-issue` 调用时的兜底」子节执行远端回写;推断失败、权限不足或回写失败均跳过并继续,不阻断导入
|
|
118
118
|
- 所有场景结束后,必须执行一次 task 留言同步,创建或更新 `.agents/rules/issue-sync.md` 中定义的 task 评论标记,确保远端 `:task` 评论存在且内容与本地 `task.md` 一致(按 issue-sync.md 的 task.md 评论同步规则)
|
|
119
119
|
|
|
120
120
|
### 7. 完成校验
|