Skip to content

Commit 8a1de53

Browse files
feat(affected): affected-tests recipe + codemap affected CLI (#132)
* feat(cli): add affected-tests recipe and codemap affected command Reverse-dependency walk from changed files to test paths via test_suites and default test suffix globs; stdin/git/positional path sources. * docs: link PR 132 in agent-surface delivery tracker * docs: fix quick-resume link for PR 132 * fix(cli): address PR 132 review findings Document affected in README and skill; fix test_glob/max_depth docs; attach recipe actions on --json; expand goldens and stdin e2e tests. * docs: clarify affected-tests agent path is query_recipe Moat A via recipe + query_recipe; codemap affected is CI-first. No dedicated MCP tool planned unless eval shows friction. * fix(affected): index minimal fixture in e2e beforeAll CI has no committed index.db under fixtures/minimal; run --full once with a 120s hook timeout so affected e2e matches cmd-query-recency. * fix(affected): use pipe stdin in e2e spawn helper Blob ReadableStream stdin was flaky on Linux CI — path reads returned [] while positional args worked. Write+end on an explicit pipe instead.
1 parent a8cf25b commit 8a1de53

18 files changed

Lines changed: 816 additions & 20 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@stainless-code/codemap": patch
3+
---
4+
5+
Add `affected-tests` recipe and `codemap affected` CLI for reverse-dependency test selection from changed files.

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,13 @@ codemap impact runWatchLoop --json --summary | jq '.summary.nodes' # CI-gate fa
198198
# (default 3, --depth 0 = unbounded), limit-capped (default 500). Result envelope:
199199
# {target, matches: [{depth, edge, kind, name?, file_path}], summary: {nodes, terminated_by}}.
200200

201+
# Affected tests — reverse dependency walk from changed sources → test files to run
202+
codemap affected --json # working-tree changes vs HEAD (git status + diff)
203+
git diff --name-only origin/main | codemap affected --stdin --json
204+
codemap affected src/lib/cache.ts --json # explicit changed paths
205+
codemap affected --changed-since origin/main --json # committed delta + working tree vs ref
206+
# Moat-A twin: `affected-tests` recipe. Output: [{test_path, impact_depth}] — CI composes the runner command.
207+
201208
# Apply — substrate-shaped fix executor (recipe SQL describes hunks; codemap validates + writes)
202209
codemap apply rename-preview --params old=usePermissions,new=useAccess,kind=function --dry-run
203210
codemap apply rename-preview --params old=usePermissions,new=useAccess,kind=function --yes # TTY prompts without --yes

docs/plans/affected-tests-recipe.md

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@
1010

1111
## Pre-locked decisions
1212

13-
| # | Decision | Source |
14-
| --- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
15-
| L.1 | **Moat-A clean**`affected-tests` recipe + optional CLI alias `codemap affected` (outcome alias cap: 5 totalaudit alias budget). | [Moat A](../roadmap.md#moats-load-bearing) |
16-
| L.2 | Algorithm: reverse BFS on `dependencies` from changed files → filter test paths via `test_suites.file_path` and configurable globs. | Uses existing substrate |
17-
| L.3 | **Stdin support** — accept changed paths from `git diff --name-only` (same ergonomics as CI scripts). | CLI ergonomics |
18-
| L.4 | Not a verdict — output is file paths only; CI composes exit policy. | Moat A |
13+
| # | Decision | Source |
14+
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ |
15+
| L.1 | **Moat-A clean**`affected-tests` recipe satisfies the agent surface; **`query_recipe`** is the MCP/HTTP path. Optional dedicated CLI verb **`codemap affected`** for CI (`stdin` / git path discovery)not a 6th outcome alias. | [Moat A](../roadmap.md#moats-load-bearing) |
16+
| L.2 | Algorithm: reverse BFS on `dependencies` from changed files → filter test paths via `test_suites.file_path` and configurable globs. | Uses existing substrate |
17+
| L.3 | **Stdin support** — accept changed paths from `git diff --name-only` (same ergonomics as CI scripts). | CLI ergonomics |
18+
| L.4 | Not a verdict — output is file paths only; CI composes exit policy. | Moat A |
1919

2020
---
2121

@@ -37,31 +37,37 @@
3737

3838
---
3939

40-
## CLI alias
40+
## CLI verb (CI)
4141

4242
```bash
43-
codemap affected --json # git diff vs HEAD
43+
codemap affected --json # working tree vs HEAD
4444
git diff --name-only origin/main | codemap affected --stdin --json
4545
```
4646

47-
Implement in `src/cli/aliases.ts` if alias budget allows; else recipe-only with documented shell wrapper.
47+
Dedicated `cmd-affected.ts` (not an outcome alias — 5-alias cap unchanged). Shipped as **`codemap affected`**, not `aliases.ts`.
48+
49+
## Agent surface (Moat A)
50+
51+
No dedicated MCP tool required — agents call **`query_recipe`** with `recipe: "affected-tests"` and `params.changed_files` (ASCII RS between paths when multiple). The recipe is the Moat-A substrate; the CLI verb is CI ergonomics only.
4852

4953
---
5054

5155
## Implementation steps
5256

5357
1. Recipe SQL + frontmatter + golden query fixture
54-
2. CLI stdin handling in `cmd-query` or dedicated thin `cmd-affected.ts`
58+
2. CLI stdin handling in dedicated `cmd-affected.ts`
5559
3. Document test-file conventions in recipe `.md`
5660
4. Optional GitHub Action input `mode: affected` in [github-marketplace-action](./github-marketplace-action.md) (follow-up)
5761

62+
**Out of scope:** dedicated MCP/HTTP `affected` tool (same outcome reachable via `query_recipe`; revisit only if agent eval shows friction).
63+
5864
---
5965

6066
## Acceptance
6167

62-
- [ ] Recipe returns test file paths for a known fixture delta
63-
- [ ] Stdin mode works in shell pipeline
64-
- [ ] Documented in README + skill
68+
- [x] Recipe returns test file paths for a known fixture delta
69+
- [x] Stdin mode works in shell pipeline
70+
- [x] Documented in README + skill
6571

6672
---
6773

docs/plans/agent-surface-delivery.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
## Quick resume
1212

13-
| Next action | Detail |
14-
| -------------------- | ----------------------------------------------------------------------------------- |
15-
| **Review / merge** | PR 4trace recipes ([#131](https://github.com/stainless-code/codemap/pull/131)) |
16-
| **Start next** | **PR 5**`affected-tests-recipe` or **PR 6** — MCP trace tools (after PR 4 lands) |
17-
| **Do not start yet** | PR 6 until PR 4 lands; PR 9 (eval harness) until PR 8 |
13+
| Next action | Detail |
14+
| -------------------- | ---------------------------------------------------------------------------------- |
15+
| **Review / merge** | PR 5affected tests ([#132](https://github.com/stainless-code/codemap/pull/132)) |
16+
| **Start next** | **PR 6**MCP trace tools (`trace` / `explore` / `node`) |
17+
| **Do not start yet** | PR 9 (eval harness) until PR 8 |
1818

1919
Update the table below when a PR merges or a new branch opens.
2020

@@ -38,8 +38,8 @@ Max **3 parallel tracks** at once.
3838
| PR | Plans | Status | Blocked by | Parallel with |
3939
| ----- | ----------------------------------------------------------------------------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------- |
4040
| **3** | [`index-lock-and-error-log`](./index-lock-and-error-log.md)[`parse-worker-hardening`](./parse-worker-hardening.md) (stack) | merged | [#129](https://github.com/stainless-code/codemap/pull/129), [#130](https://github.com/stainless-code/codemap/pull/130) | 4, 5 |
41-
| **4** | Recipe half of [`mcp-trace-explore-tools`](./mcp-trace-explore-tools.md) (`call-path`, `symbol-neighborhood` SQL + tests) | open | [#131](https://github.com/stainless-code/codemap/pull/131) | 3, 5 |
42-
| **5** | [`affected-tests-recipe`](./affected-tests-recipe.md) | planned | | 3, 4 |
41+
| **4** | Recipe half of [`mcp-trace-explore-tools`](./mcp-trace-explore-tools.md) (`call-path`, `symbol-neighborhood` SQL + tests) | merged | [#131](https://github.com/stainless-code/codemap/pull/131) | 3, 5 |
42+
| **5** | [`affected-tests-recipe`](./affected-tests-recipe.md) | open | [#132](https://github.com/stainless-code/codemap/pull/132) | 3, 4 |
4343
| **6** | MCP half of trace (`trace` / `explore` / `node` tools) + update instructions | planned | PR 1, PR 4 ||
4444
| **7** | [`field-qualified-search`](./field-qualified-search.md) | planned | PR 1 | 4, 5 if `mcp-server.ts` untouched |
4545
| **8** | [`agents-init-mcp-wiring`](./agents-init-mcp-wiring.md) | planned | PR 1 | 3–5 |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"test_path": "src/__tests__/smoke.test.ts",
4+
"impact_depth": 1
5+
}
6+
]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"test_path": "src/__tests__/smoke.test.ts",
4+
"impact_depth": 0
5+
}
6+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"test_path": "src/__tests__/smoke.test.ts",
4+
"impact_depth": 0
5+
}
6+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[
2+
{
3+
"test_path": "src/__tests__/smoke.test.ts",
4+
"impact_depth": 1
5+
}
6+
]

0 commit comments

Comments
 (0)