@oevery/rsp 3.1.0-beta.2 → 3.1.0-beta.4

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 CHANGED
@@ -34,17 +34,17 @@ RSP derives the next action from the selected Change, repository evidence, verif
34
34
  ## Quick start
35
35
 
36
36
  ```bash
37
- npx -y @oevery/rsp@3.1.0-beta.2 init
38
- npx -y @oevery/rsp@3.1.0-beta.2 doctor
37
+ npx -y @oevery/rsp@3.1.0-beta.4 init
38
+ npx -y @oevery/rsp@3.1.0-beta.4 doctor
39
39
  ```
40
40
 
41
41
  Recommended bootstrap flow:
42
42
 
43
43
  ```bash
44
- npx -y @oevery/rsp@3.1.0-beta.2 init --with-project-setup
44
+ npx -y @oevery/rsp@3.1.0-beta.4 init --with-project-setup
45
45
  # fill .rsp/changes/project-setup.md
46
46
  # fill .rsp/specs/design.md
47
- npx -y @oevery/rsp@3.1.0-beta.2 doctor
47
+ npx -y @oevery/rsp@3.1.0-beta.4 doctor
48
48
  ```
49
49
 
50
50
  ## Artifact foundation
@@ -62,9 +62,12 @@ npx -y @oevery/rsp@3.1.0-beta.2 doctor
62
62
  .rsp/
63
63
  ├── rsp-rules.md # minimal fallback protocol
64
64
  ├── specs/
65
- │ ├── INDEX.md # auto-generated
65
+ │ ├── 00-index.md # auto-generated direct-child navigation
66
66
  │ ├── design.md
67
- │ └── decisions/ # authoritative Decision Records by default
67
+ │ ├── decisions/ # authoritative Decision Records by default; excluded from Specs indexes
68
+ │ └── <domain>/
69
+ │ ├── 00-index.md # auto-generated direct-child navigation
70
+ │ └── <spec>.md
68
71
  ├── changes/
69
72
  │ ├── <name>.md
70
73
  │ └── <group>/
@@ -73,7 +76,7 @@ npx -y @oevery/rsp@3.1.0-beta.2 doctor
73
76
  ├── focus.d/
74
77
  │ └── <name>
75
78
  └── archives/
76
- └── INDEX.md # auto-generated
79
+ └── YYYY-MM-DD_<change>.md
77
80
  ```
78
81
 
79
82
  ## Concepts
@@ -90,9 +93,10 @@ npx -y @oevery/rsp@3.1.0-beta.2 doctor
90
93
  - A Group Brief blocker is inherited by its direct children as an external blocker in the derived execution plan; it does not create guessed dependency edges.
91
94
  - A Markdown file and directory cannot claim the same work identity.
92
95
  - `rsp status`, `rsp check`, and `rsp doctor` inspect the same complete work tree and dependency facts. `status` derives exact edges with their reasons, ready work, blockers, and stable waves without a graph file; `check` and `doctor` reject incomplete archive inspection, malformed or missing targets, self-dependencies, and cycles. The `changes/` root must exist as a real directory, and existing focus/archive roots and group prefixes must also be real directories. Unsupported directories, non-Markdown entries, symlinks, missing or unreadable current work, incomplete reads, and identity collisions are visible errors. `status` exits non-zero instead of hiding invalid work.
93
- - `rsp init`, `rsp update`, `rsp add spec`, and generated index builders apply the same no-follow managed-path checks. Archive discovery accepts only flat archive files or one real group directory; recursively organized Specs accept only real directories and regular files.
94
- - Final managed files—such as the project `AGENTS.md`, focus markers, fallback/config files, generated indexes, and placeholders—must also be regular files; RSP rejects static symlink targets before reading or writing them.
96
+ - `rsp init`, `rsp update`, `rsp add spec`, and the generated Specs index builder apply the same no-follow managed-path checks. Archive discovery accepts only flat archive files or one real group directory; recursively organized Specs accept only real directories and regular files.
97
+ - Final managed files—such as the project `AGENTS.md`, focus markers, fallback/config files, the generated Specs index, and placeholders—must also be regular files; RSP rejects static symlink targets before reading or writing them.
95
98
  - Completed changes move to `archives/`. Stable current facts belong in Specs; lasting rationale belongs in Decision Records; stable scoped operating instructions belong in nearest project-owned `AGENTS.md`.
99
+ - When later evidence shows that the original acceptance was not actually met, `rsp reopen <work-ref> --reason <text>` restores the same executable WorkRef as focused open work and retains the selected archive as history. Multiple archives require an exact `--from .rsp/archives/...` path. Use a new corrective Change for genuinely new scope or an independently delivered correction; reopening never rewrites Git or published history.
96
100
  - Do not promote task history, debugging notes, or one-off implementation context into Specs, Decision Records, or project instructions.
97
101
  - Change `Spec` delta markers (`### ADDED`, `### MODIFIED`, `### REMOVED`) are planning aids only. `rsp archive` does not automatically promote them into Specs or Decision Records. Durable writeback remains an explicit semantic decision.
98
102
  - `rsp check` performs deterministic hygiene checks. It warns about unfinished template placeholders and unresolved clarification markers, but those warnings do not replace the semantic durable-update decision.
@@ -100,13 +104,12 @@ npx -y @oevery/rsp@3.1.0-beta.2 doctor
100
104
  ## File ownership
101
105
 
102
106
  - `AGENTS.md`: only the `<!-- rsp:begin --> ... <!-- rsp:end -->` block is managed by RSP.
103
- - `.rsp/specs/INDEX.md`: auto-generated index of additional spec files beyond `design.md`. Rebuild with `rsp update`.
104
- - `.rsp/archives/INDEX.md`: auto-generated. Rebuild with `rsp update`.
107
+ - `.rsp/specs/**/00-index.md`: fully generated direct-child navigation for the root and populated Spec directories. Reconcile all local indexes with `rsp update`; `rsp add spec` refreshes only the affected directory chain.
105
108
  - `.rsp/specs/design.md`: created by `rsp init`, then owned by the project.
106
109
  - `.rsp/specs/decisions/`: the default authoritative Decision Record directory; configure `decisions.path` only when the Host Project already owns one external ADR directory.
107
110
  - `.rsp/rsp-rules.md`: generated minimal fallback protocol; use the `rsp` skill when available.
108
- - Keep project-wide boundaries and navigation in `.rsp/specs/design.md`; move cohesive reusable facts to the smallest domain Spec listed by `.rsp/specs/INDEX.md`.
109
- - Treat `.rsp/specs/INDEX.md` as a directory for additional spec files; it does not list `design.md`.
111
+ - Keep project-wide boundaries in `.rsp/specs/design.md`; use the nearest `00-index.md` to discover cohesive reusable facts in the smallest domain Spec.
112
+ - Treat every `00-index.md` as generated navigation, never as an editable current-fact or rationale owner. Each index lists only direct child Specs and populated child Spec directories; Decision Records are excluded.
110
113
  - Keep stable scoped workflow and validation instructions in the nearest project-owned `AGENTS.md`, outside the managed RSP block.
111
114
 
112
115
  ## Decision Record path
@@ -160,17 +163,24 @@ RSP publishes eleven default host-neutral lifecycle Skills for on-demand loading
160
163
  | `rsp-diagnose` | Confirm a cause, or return a truthful unresolved diagnosis, before correction. |
161
164
  | `rsp-tdd` | Drive one clear behavior through RED, GREEN, and safe REFACTOR. |
162
165
  | `rsp-review` | Review a fixed code, document, or mixed comparison without mutation. |
163
- | `rsp-address-review` | Dispose fixed findings, correct accepted ones, verify, and request re-review. |
166
+ | `rsp-resolve-findings` | Dispose fixed findings, correct accepted ones, verify, and request re-review. |
164
167
  | `rsp-commit` | Create one authorized exact-scope local commit with a repository-consistent structured message. |
165
168
  | `rsp-release-docs` | Draft, audit, finalize, or reconcile evidence-based release surfaces. |
166
169
  | `rsp-manage` | Continue one explicitly requested or project-enabled eligible ready Change or shallow Group. |
167
- | `rsp-codebase-audit` (optional) | Audit one bounded repository or subtree for evidence-backed structural risks without mutation. |
170
+ | `rsp-structural-audit` (optional) | Audit one bounded repository or subtree for evidence-backed structural risks without mutation. |
168
171
 
169
- Each lifecycle Skill returns to an existing project or RSP owner. Report-only Pre-Change Design and `rsp-codebase-audit` may return one bounded result directly to the user without inventing an artifact owner. The suite adds no hidden workflow state or recursive Skill orchestration. No Skill infers commit, push, publication, deployment, approval, or human-acceptance authority.
172
+ Each lifecycle Skill returns to an existing project or RSP owner. Report-only Pre-Change Design and `rsp-structural-audit` may return one bounded result directly to the user without inventing an artifact owner. The suite adds no hidden workflow state or recursive Skill orchestration. No Skill infers commit, push, publication, deployment, approval, or human-acceptance authority.
170
173
 
171
- Response language and artifact language are independent. Human-facing response headings, labels, explanations, and conclusions follow the requested response language, response-specific project instructions, then the conversation language. Authorized artifact prose follows the requested artifact language, artifact-specific project instructions, then the existing artifact language, and only then the conversation language. Canonical RSP artifact headings, WorkRef values, paths, commands, identifiers, and machine-consumed values remain unchanged; response labels may retain technical tokens in parentheses but never use them as untranslated labels.
174
+ Response language is user/session-owned; artifact and commit-message language are durable project surfaces. Project `.rsp/config.yaml` never selects response language: response prose follows an explicit current request, user/host personal instructions, then conversation language. A project may set one durable `language.default` and independently override `language.artifacts` or `language.commit`. New authorized artifact prose follows an explicit artifact request, the configured effective artifact language, artifact-specific project instructions, then conversation language; existing artifacts keep their established language unless translation is explicitly authorized. Commit prose follows an explicit current commit-language instruction, configured effective commit language, repository commit authority, then clear recent non-merge history. Configuration changes never rewrite existing artifacts. CLI-generated scaffolds contain canonical structural tokens, neutral `<…>` placeholders, and verbatim user input instead of a locale catalog or silent English prose fallback; Core and discipline Skills fill their authorized natural-language content. Canonical RSP headings, paths, commands, identifiers, Conventional Commit types/scopes, trailers, and machine-consumed values remain unchanged; WorkRefs use the safe Unicode identity contract rather than the prose-language fallback chain.
172
175
 
173
- Compose the suite from evidence: an explicit bounded question may enter report-only Pre-Change Design before Shape; otherwise Shape settles the executable owner and Tracked Design returns one material question to it. Core then chooses Diagnose, TDD, or Implement; Review stays report-only; Address Review corrects accepted findings and requests re-review; Core performs the durable decision before archive. An explicit release operation with a confirmed identity or range may enter Release Docs without a Release Change; create one only for material decisions, coordination, recovery, blockers, or acceptance. Manage is optional: it accepts one selected ready Change or shallow Group that needs independent dispatch, long continuation, or recovery, while small or coupled work stays direct. Projects may keep explicit activation or let Core select eligible managed work automatically.
176
+ ```yaml
177
+ language:
178
+ default: en
179
+ ```
180
+
181
+ `default` is required when the mapping is present and supplies both durable surfaces. Optional `artifacts` and `commit` override only their respective surfaces. `response` is intentionally unsupported because a shared repository must not constrain each collaborator's conversation language. Omit `language` entirely to leave both durable values unset. Plain status shows configured durable values, while status JSON always exposes `language.artifacts` and `language.commit` as a canonical language tag or `null`. Language configuration never grants staging, commit, push, or publication authority.
182
+
183
+ Compose the suite from evidence: an explicit bounded question may enter report-only Pre-Change Design before Shape; otherwise Shape settles the executable owner and Tracked Design returns one material question to it. Core then chooses Diagnose, TDD, or Implement; Review stays report-only; Resolve Findings corrects accepted findings and requests re-review; Core performs the durable decision before archive. An explicit release operation with a confirmed identity or range may enter Release Docs without a Release Change; create one only for material decisions, coordination, recovery, blockers, or acceptance. Manage is optional: it accepts one selected ready Change or shallow Group that needs independent dispatch, long continuation, or recovery, while small or coupled work stays direct. Projects may keep explicit activation or let Core select eligible managed work automatically.
174
184
 
175
185
  ### Managed automation policy
176
186
 
@@ -186,13 +196,15 @@ manage:
186
196
 
187
197
  - `manual`: neither archive nor commit is automatic.
188
198
  - `lifecycle`: archive may follow durable review, but commit still needs separate authority.
189
- - `local`: lifecycle closeout plus the existing bounded local checkpoint or terminal-commit path may run only after its exact-path, clean-boundary, verification, and delivery-value gates.
199
+ - `local`: lifecycle closeout plus separately justified recovery checkpoints; after lifecycle closeout, a qualified clean verified terminal non-small boundary routes once to `rsp-commit`, while terminal small work stays uncommitted.
200
+
201
+ Change granularity follows one observable outcome and its shared acceptance, verification, review, archive, and rollback boundary; it does not prescribe Git commit count. Each `rsp-commit` invocation still creates exactly one local commit.
190
202
 
191
203
  New `rsp init` config templates use the shown `auto` plus `lifecycle` policy. If `manage` is absent, RSP instead resolves `activation: explicit` and `closeout: local` for compatibility with the previous explicitly requested Manage behavior. Plain `rsp status` and the top-level `manage` object in `rsp status --json` show the resolved values. Nearest scoped restrictions and host enforcement can narrow the configured ceiling. RSP intentionally has no `full` preset: push, tag, publication, deployment, approval, and human acceptance remain explicit and external.
192
204
 
193
205
  Humans should start with this README. Agents should follow the nearest `AGENTS.md`, prefer `skills/rsp/SKILL.md`, and use `.rsp/rsp-rules.md` only when the Skill is unavailable.
194
206
 
195
- When this README shows `rsp <command>`, it assumes the command is already available in your environment. For opt-in beta evaluation, pin the exact prerelease identity, such as `npx -y @oevery/rsp@3.1.0-beta.2 <command>`; stable users can keep using the unversioned package entrypoint for npm `latest`.
207
+ When this README shows `rsp <command>`, it assumes the command is already available in your environment. For opt-in beta evaluation, pin the exact prerelease identity, such as `npx -y @oevery/rsp@3.1.0-beta.4 <command>`; stable users can keep using the unversioned package entrypoint for npm `latest`.
196
208
 
197
209
  Install the exact package's default lifecycle suite into the current project:
198
210
 
@@ -210,16 +222,18 @@ rsp skills list --json
210
222
 
211
223
  The command preflights the eleven default package-owned targets, leaves unrelated `.agents/skills` entries (including optional Skills) untouched, and requires explicit `--force` before replacing a divergent selected directory. Install the optional project-level audit Skill by exact name:
212
224
 
225
+ When upgrading an installation that still contains `rsp-address-review` or `rsp-codebase-audit`, their replacements are `rsp-resolve-findings` and `rsp-structural-audit`. The installer stops without mutation until `--force` explicitly authorizes transactional removal of the obsolete package-owned directory; `--dry-run --force` previews both removal and installation.
226
+
213
227
  ```bash
214
- rsp skills install rsp-codebase-audit --dry-run
215
- rsp skills install rsp-codebase-audit
228
+ rsp skills install rsp-structural-audit --dry-run
229
+ rsp skills install rsp-structural-audit
216
230
  ```
217
231
 
218
232
  Both forms install from the package that invoked `rsp`, so prerelease dogfooding can pin one exact npm identity:
219
233
 
220
234
  ```bash
221
- npx -y @oevery/rsp@3.1.0-beta.2 skills install --dry-run
222
- npx -y @oevery/rsp@3.1.0-beta.2 skills install
235
+ npx -y @oevery/rsp@3.1.0-beta.4 skills install --dry-run
236
+ npx -y @oevery/rsp@3.1.0-beta.4 skills install
223
237
  ```
224
238
 
225
239
  Exact prerelease identities avoid depending on a moving dist-tag. `rsp update` refreshes RSP-managed project files only; run `rsp skills install` separately to refresh the package-owned Skill suite.
@@ -273,8 +287,8 @@ Durable review makes two independent semantic choices: whether current facts or
273
287
 
274
288
  New project:
275
289
 
276
- 1. `npx -y @oevery/rsp@3.1.0-beta.2 init`
277
- 2. Prefer `npx -y @oevery/rsp@3.1.0-beta.2 init --with-project-setup`, or run `rsp create project-setup` manually
290
+ 1. `npx -y @oevery/rsp@3.1.0-beta.4 init`
291
+ 2. Prefer `npx -y @oevery/rsp@3.1.0-beta.4 init --with-project-setup`, or run `rsp create project-setup` manually
278
292
  3. Fill `.rsp/specs/design.md`
279
293
  4. Use `rsp add spec <name>` only when a new durable project doc is needed
280
294
  5. Keep lasting rationale in the configured Decision Record directory and stable scoped operating instructions in the nearest project-owned `AGENTS.md`
@@ -284,17 +298,18 @@ New project:
284
298
  9. Edit the change file directly to implement the work and mark tasks complete
285
299
  10. Use the RSP skill or a human review to decide whether durable updates are needed
286
300
  11. After Core recommends archive, run `rsp archive <name>` before final Git delivery; inspect the complete resulting worktree and obtain Git authority separately
301
+ 12. If later evidence invalidates the original completion, run `rsp reopen <name> --reason <text>` and resolve the restored unfinished Task and Verify evidence under the same WorkRef
287
302
 
288
303
  Existing project with a rich `AGENTS.md`:
289
304
 
290
- 1. `npx -y @oevery/rsp@3.1.0-beta.2 init`
305
+ 1. `npx -y @oevery/rsp@3.1.0-beta.4 init`
291
306
  2. Keep the managed block thin
292
307
  3. Keep project-wide boundaries and navigation in `.rsp/specs/design.md`, and route cohesive durable facts to the smallest domain Spec
293
308
  4. Use `rsp add spec <name>` only when another durable current-fact document is needed
294
309
 
295
310
  AI-assisted setup:
296
311
 
297
- 1. `npx -y @oevery/rsp@3.1.0-beta.2 init --agents-mode print --with-project-setup`
312
+ 1. `npx -y @oevery/rsp@3.1.0-beta.4 init --agents-mode print --with-project-setup`
298
313
  2. Keep the managed block as generated and adapt only the surrounding human-owned content if needed
299
314
  3. Have the AI review and fill `.rsp/changes/project-setup.md`
300
315
  4. Have the AI fill `.rsp/specs/design.md`
@@ -305,7 +320,7 @@ AI-assisted setup:
305
320
  ```text
306
321
  rsp init --agents-mode <mode> Scaffold .rsp/ and ensure AGENTS.md contains the RSP entry block
307
322
  rsp init --with-project-setup Also create .rsp/changes/project-setup.md
308
- rsp update Refresh the fallback protocol, repair the AGENTS block, and rebuild indices
323
+ rsp update Refresh managed project files, not packaged Skills
309
324
  rsp ui [--lang auto|en|zh-CN] Open the read-only interactive dashboard
310
325
  rsp skills Open the interactive project Skill manager on a dual TTY
311
326
  rsp skills list [--json] List bundled Skills and exact project installation status
@@ -317,13 +332,15 @@ rsp group create <name> [goal] Create an unfocused .rsp/changes/<name>/00-brief.
317
332
  rsp group close <name> Archive a completed Group Brief after every child is archived
318
333
  rsp focus <name> Mark an open change as currently focused
319
334
  rsp unfocus <name> Remove an open change from the current focus set
320
- rsp archive <name> Archive to .rsp/archives/ + update archive index
321
- rsp archive --dry-run <name> Preview archive readiness without moving the change
335
+ rsp archive <name> Archive to .rsp/archives/
336
+ rsp archive --dry-run <name> Deprecated compatibility route to rsp ready; never moves the change
337
+ rsp reopen <name> --reason <text> [--from <archive-path>]
338
+ Restore the same WorkRef as focused open work and retain archive history
322
339
  rsp ready <name> [--json [--compact]] [--verbose]
323
- Preview archive readiness (same as archive --dry-run)
340
+ Canonical read-only archive readiness projection
324
341
  rsp show <name|--focused> [--json [--compact]] [--verbose]
325
342
  Show change context with readiness signals and context paths
326
- rsp history [--limit <n>] [--since <date>] [--until <date>] [--kind <kind>] [--group <group>] [--json [--compact]]
343
+ rsp history [--limit <n>] [--since <date>] [--until <date>] [--kind <kind>] [--group <group>] [--search <text>] [--json [--compact]]
327
344
  List bounded archived Change summaries (default 20, maximum 100)
328
345
  rsp history <work-ref> [--json [--compact]]
329
346
  Show bounded evidence detail for one exact archived Change
@@ -339,7 +356,7 @@ Use `skills/rsp/SKILL.md` for operations. When the skill is unavailable, use `.r
339
356
 
340
357
  On a real interactive terminal, bare `rsp` opens the same read-only dashboard as `rsp ui`. CI, pipes, redirected streams, and `TERM=dumb` stay on static command output; use `rsp status` for a human snapshot or `rsp status --json` for automation. The dashboard never creates, focuses, or archives work.
341
358
 
342
- Dashboard keys: `Tab` cycles Changes/Groups/History, arrows or `j`/`k` move, `/` filters the active scope, `Enter` opens full-width detail, `r` refreshes the active scope, `?` shows help, and `q`, `Ctrl-C`, or top-level `Esc` exits. History is loaded only when first visited, uses the default bounded recent result, and loads one selected record's structured detail by its unique archive path only after `Enter`; use `rsp history` filters for older work. Set `RSP_UI_LANG=en|zh-CN` or pass `rsp ui --lang`; only dashboard-owned labels are localized. Existing CLI help, plain output, JSON, WorkRefs, paths, commands, Skills, and RSP artifacts remain English.
359
+ Dashboard keys: `Tab` cycles Changes/Groups/History, arrows or `j`/`k` move, `/` filters the active scope, `Enter` opens full-width detail, `r` refreshes the active scope, `?` shows help, and `q`, `Ctrl-C`, or top-level `Esc` exits. History is loaded only when first visited, uses the default bounded recent result, and loads one selected record's structured detail by its unique archive path only after `Enter`; use `rsp history` filters for older work. Set `RSP_UI_LANG=en|zh-CN` or pass `rsp ui --lang`; only dashboard-owned labels are localized. This UI setting does not localize CLI help, plain output, JSON, paths, commands, Skills, or existing artifacts. WorkRefs may use the safe Unicode identity contract, and new artifact prose follows the project language policy described above.
343
360
 
344
361
  When there is no focused change, `rsp status` and `rsp show --focused --json` print `nextActions` instead of guessing which open change is current.
345
362
 
@@ -347,12 +364,13 @@ Human-readable `rsp status` renders its execution guidance as a dependency fores
347
364
 
348
365
  `rsp status --json` returns the same dependency graph under `plan.nodes`, `plan.ready`, `plan.edges`, `plan.blocked`, and `plan.waves`. Nodes distinguish filter-selected Changes from prerequisite context, while filtered plans retain the transitive prerequisite closure needed to explain the result. JSON stays flat rather than nesting children because prerequisites may be shared by multiple Changes. Each edge reads as “`change` requires `requires`”. These are derived navigation facts, not execution authority or persisted workflow state.
349
366
 
350
- `rsp history` inspects authoritative archive files directly instead of trusting the generated archive index. List results are ordered by archive date descending, WorkRef, then source path; inclusive date, exact kind, and exact Group filters are applied before the 1–100 record bound. Each record includes its project-relative archive path as a stable identity. `rsp history <work-ref>` returns bounded summary, scenario and checkbox counts, and bounded Tasks/Verify/Blockers evidence. It never returns raw Markdown; duplicate generations of one WorkRef fail with candidate archive paths instead of choosing implicitly. Unreadable, malformed, path-inconsistent, missing-root, or reserved executable Group Brief identities fail the complete query even when filters would exclude them. Archived Group Briefs are validated but are not list records. The command accepts at most one positional WorkRef. Diagnostics and ambiguous candidates are capped at 20 entries with total/returned/`hasMore` metadata, and human errors report how many entries were omitted.
367
+ `rsp history` inspects authoritative archive files directly; no generated Archive Index is created or read. List results are ordered by archive date descending, WorkRef, then source path; inclusive date, exact kind, exact Group, and case-insensitive literal WorkRef/summary search filters are applied before the 1–100 record bound. Each record includes its project-relative archive path as a stable identity. `rsp history <work-ref>` returns bounded summary, scenario and checkbox counts, and bounded Tasks/Verify/Blockers evidence. It never returns raw Markdown; duplicate generations of one WorkRef fail with candidate archive paths instead of choosing implicitly. Unreadable, malformed, path-inconsistent, missing-root, or reserved executable Group Brief identities fail the complete query even when filters would exclude them. Archived Group Briefs are validated but are not list records. The command accepts at most one positional WorkRef. Diagnostics and ambiguous candidates are capped at 20 entries with total/returned/`hasMore` metadata, and human errors report how many entries were omitted. `status` archive trends and TUI History use the same validated inspection.
351
368
 
352
369
  Examples:
353
370
 
354
371
  ```sh
355
372
  rsp history --since 2026-07-01 --kind fix --limit 10 --json
373
+ rsp history --search migration --limit 10 --json
356
374
  rsp history cli-machine-output/add-bounded-history-query --json --compact
357
375
  ```
358
376
 
package/README.zh-CN.md CHANGED
@@ -34,17 +34,17 @@ RSP 根据 selected Change、仓库证据、验证结果和 blockers 推导下
34
34
  ## 快速开始
35
35
 
36
36
  ```bash
37
- npx -y @oevery/rsp@3.1.0-beta.2 init
38
- npx -y @oevery/rsp@3.1.0-beta.2 doctor
37
+ npx -y @oevery/rsp@3.1.0-beta.4 init
38
+ npx -y @oevery/rsp@3.1.0-beta.4 doctor
39
39
  ```
40
40
 
41
41
  推荐启动流程:
42
42
 
43
43
  ```bash
44
- npx -y @oevery/rsp@3.1.0-beta.2 init --with-project-setup
44
+ npx -y @oevery/rsp@3.1.0-beta.4 init --with-project-setup
45
45
  # 填写 .rsp/changes/project-setup.md
46
46
  # 填写 .rsp/specs/design.md
47
- npx -y @oevery/rsp@3.1.0-beta.2 doctor
47
+ npx -y @oevery/rsp@3.1.0-beta.4 doctor
48
48
  ```
49
49
 
50
50
  ## Artifact foundation
@@ -62,9 +62,12 @@ npx -y @oevery/rsp@3.1.0-beta.2 doctor
62
62
  .rsp/
63
63
  ├── rsp-rules.md # 最小 fallback protocol
64
64
  ├── specs/
65
- │ ├── INDEX.md # 自动生成
65
+ │ ├── 00-index.md # 自动生成的直接子项导航
66
66
  │ ├── design.md
67
- │ └── decisions/ # 默认的权威 Decision Records
67
+ │ ├── decisions/ # 默认的权威 Decision Records;不进入 Specs 索引
68
+ │ └── <domain>/
69
+ │ ├── 00-index.md # 自动生成的直接子项导航
70
+ │ └── <spec>.md
68
71
  ├── changes/
69
72
  │ ├── <name>.md
70
73
  │ └── <group>/
@@ -73,7 +76,7 @@ npx -y @oevery/rsp@3.1.0-beta.2 doctor
73
76
  ├── focus.d/
74
77
  │ └── <name>
75
78
  └── archives/
76
- └── INDEX.md # 自动生成
79
+ └── YYYY-MM-DD_<change>.md
77
80
  ```
78
81
 
79
82
  ## 概念
@@ -100,13 +103,12 @@ npx -y @oevery/rsp@3.1.0-beta.2 doctor
100
103
  ## 文件所有权
101
104
 
102
105
  - `AGENTS.md`:只有 `<!-- rsp:begin --> ... <!-- rsp:end -->` 受管块由 RSP 维护。
103
- - `.rsp/specs/INDEX.md`:自动生成,用于索引 `design.md` 之外的附加 spec 文件;使用 `rsp update` 重建。
104
- - `.rsp/archives/INDEX.md`:自动生成,使用 `rsp update` 重建。
106
+ - `.rsp/specs/**/00-index.md`:为根目录及含内容的 Spec 目录生成直接子项导航。使用 `rsp update` 对齐全部本地索引;`rsp add spec` 只刷新受影响的目录链。
105
107
  - `.rsp/specs/design.md`:由 `rsp init` 创建,之后由项目维护。
106
108
  - `.rsp/specs/decisions/`:默认的权威 Decision Record 目录;只有 Host Project 已有外部 ADR 目录时才配置 `decisions.path`。
107
109
  - `.rsp/rsp-rules.md`:生成的最小 fallback protocol;可用时优先加载 `rsp` skill。
108
- - 将项目级边界与导航放在 `.rsp/specs/design.md`;把成组且可复用的事实放入 `.rsp/specs/INDEX.md` 所列的最小领域 Spec。
109
- - 将 `.rsp/specs/INDEX.md` 视为附加 spec 的目录;它不列出 `design.md`。
110
+ - 将项目级边界放在 `.rsp/specs/design.md`;通过最近的 `00-index.md` 发现归属于最小领域 Spec 的成组、可复用事实。
111
+ - 所有 `00-index.md` 都只是生成导航,不能作为可编辑的当前事实或理由 owner。每个索引只列直接子 Spec 与含内容的直接子目录,并排除 Decision Records。
110
112
  - 将稳定且有作用域的工作流、验证和本地运行指令放在 nearest project-owned `AGENTS.md` 的非受管区域。
111
113
 
112
114
  ## Decision Record 路径
@@ -160,17 +162,24 @@ RSP 发布十一个默认、宿主无关、按需加载的生命周期 Skills,
160
162
  | `rsp-diagnose` | 修正前确认原因,或如实返回 unresolved diagnosis。 |
161
163
  | `rsp-tdd` | 让一个清晰行为经过 RED、GREEN 与安全的 REFACTOR。 |
162
164
  | `rsp-review` | 对固定的 Code、Document 或 mixed comparison 做只读审查。 |
163
- | `rsp-address-review` | 处置固定 findings,修正 accepted 项,验证并请求复审。 |
165
+ | `rsp-resolve-findings` | 处置固定 findings,修正 accepted 项,验证并请求复审。 |
164
166
  | `rsp-commit` | 使用与仓库一致的结构化消息创建一个已授权、精确范围的本地提交。 |
165
167
  | `rsp-release-docs` | 起草、审计、定稿或校准基于证据的发布表面。 |
166
168
  | `rsp-manage` | 继续一个显式请求或项目启用且符合条件的 ready Change 或 shallow Group。 |
167
- | `rsp-codebase-audit`(可选) | 只读审计一个有界仓库或子树,发现有证据支撑的结构风险。 |
169
+ | `rsp-structural-audit`(可选) | 只读审计一个有界仓库或子树,发现有证据支撑的结构风险。 |
168
170
 
169
- 每个生命周期 Skill 都把结果返回现有项目或 RSP owner。只读的 Pre-Change Design 与 `rsp-codebase-audit` 可以把一个有界结果直接返回用户,而不虚构 artifact owner。套件不引入隐藏 workflow state 或递归 Skill 编排。任何 Skill 都不会推断 commit、push、publication、deployment、approval 或 human-acceptance 权限。
171
+ 每个生命周期 Skill 都把结果返回现有项目或 RSP owner。只读的 Pre-Change Design 与 `rsp-structural-audit` 可以把一个有界结果直接返回用户,而不虚构 artifact owner。套件不引入隐藏 workflow state 或递归 Skill 编排。任何 Skill 都不会推断 commit、push、publication、deployment、approval 或 human-acceptance 权限。
170
172
 
171
- 响应语言与产物语言相互独立。面向人的响应标题、标签、解释和结论依次遵循明确指定的响应语言、项目中针对响应的指令和会话语言;已授权写入的产物正文依次遵循明确指定的产物语言、项目中针对产物的指令、目标产物的现有语言,最后才回退到会话语言。RSP 的 canonical artifact headings、WorkRef 值、路径、命令、标识符和机器消费值保持不变;响应标签可以在括号中保留技术 token,但不能直接使用未翻译的 token 作为标签。
173
+ 响应语言归用户和会话所有;产物与 commit message 语言才是项目持久表面。项目 `.rsp/config.yaml` 绝不选择响应语言:响应正文依次遵循当前明确请求、用户/宿主个人指令和会话语言。项目可以设置共享的 `language.default`,并通过 `language.artifacts` 或 `language.commit` 分别覆盖。新产物正文依次遵循明确产物语言、有效产物语言、项目产物指令和会话语言;已有产物除非明确授权翻译,否则保持现有语言。Commit 正文依次遵循当前明确的 commit 语言、有效 commit 语言、仓库 commit 规则和清晰的近期非 merge 历史。配置变化不会重写历史。CLI 生成的脚手架只包含 canonical 结构 token、中立的 `<…>` 占位符和用户原样输入,不维护 locale 字典,也不会静默回退为英文正文;Core 与 discipline Skills 再按授权语言填写自然语言内容。RSP 的 canonical headings、路径、命令、标识符、Conventional Commit type/scope、trailers 和机器消费值保持不变;WorkRef 遵循安全 Unicode 身份契约。
172
174
 
173
- 按证据组合套件:Shape 确定 owner;Design 返回一个关键问题;Core 在 Diagnose、TDD 与 Implement 之间选择;Review 保持只读;Address Review 修正 accepted findings 并请求复审;Core 在 archive 前执行 durable decision。显式 release operation 在 identity 或 range 已确认时,可以不创建 Release Change 就进入 Release Docs;只有重大决策、协调、恢复、blocker 或 acceptance 需要持久 owner 时才创建。Manage 是可选能力:它接受一个 selected ready Change 或 shallow Group,并要求独立调度、长时 continuation 或恢复需求;小型或紧耦合工作保持直接执行。项目可以保持显式启用,也可以让 Core 自动选择符合条件的 managed work。
175
+ ```yaml
176
+ language:
177
+ default: en
178
+ ```
179
+
180
+ 配置了 `language` mapping 时,`default` 必填并同时为产物和 commit 提供持久默认值;可选的 `artifacts` 与 `commit` 只覆盖对应表面。`response` 被明确禁止,因为共享仓库不应限制每位协作者的会话语言。完全省略 `language` 时,两项持久有效值都保持未设置。普通 status 显示持久语言值,status JSON 则始终把 `language.artifacts` 与 `language.commit` 投影为规范化语言标签或 `null`。语言配置不会授予 stage、commit、push 或 publication 权限。
181
+
182
+ 按证据组合套件:Shape 确定 owner;Design 返回一个关键问题;Core 在 Diagnose、TDD 与 Implement 之间选择;Review 保持只读;Resolve Findings 修正 accepted findings 并请求复审;Core 在 archive 前执行 durable decision。显式 release operation 在 identity 或 range 已确认时,可以不创建 Release Change 就进入 Release Docs;只有重大决策、协调、恢复、blocker 或 acceptance 需要持久 owner 时才创建。Manage 是可选能力:它接受一个 selected ready Change 或 shallow Group,并要求独立调度、长时 continuation 或恢复需求;小型或紧耦合工作保持直接执行。项目可以保持显式启用,也可以让 Core 自动选择符合条件的 managed work。
174
183
 
175
184
  ### Managed automation policy
176
185
 
@@ -186,13 +195,15 @@ manage:
186
195
 
187
196
  - `manual`:archive 与 commit 都不会自动执行。
188
197
  - `lifecycle`:durable review 后可以 archive,但 commit 仍需要独立权限。
189
- - `local`:允许 lifecycle closeout,并仅在 exact-path、clean-boundary、verification 和 delivery-value gate 通过后进入已有的有界本地 checkpoint 或 terminal commit 路径。
198
+ - `local`:允许 lifecycle closeout 和有独立依据的 recovery checkpoint;lifecycle closeout 后,符合条件且 clean、已验证的非小型终态边界会调用一次 `rsp-commit`,小型终态仍不提交。
199
+
200
+ Change 粒度由一个可观察结果及其共享的 acceptance、verification、review、archive 和 rollback 边界决定,不规定 Git commit 数量。每次 `rsp-commit` 调用仍只创建一个本地 commit。
190
201
 
191
202
  新的 `rsp init` config template 使用上面的 `auto` 加 `lifecycle` policy。如果省略 `manage`,RSP 则为兼容既有显式 Manage 行为解析为 `activation: explicit` 与 `closeout: local`。普通 `rsp status` 和 `rsp status --json` 顶层的 `manage` 对象都会显示解析后的值。nearest scoped restriction 与 host enforcement 可以缩小该配置上限。RSP 有意不提供 `full` preset:push、tag、publication、deployment、approval 与 human acceptance 始终保持显式且属于外部边界。
192
203
 
193
204
  人类应从本 README 开始;agent 应遵循 nearest `AGENTS.md`,优先加载 `skills/rsp/SKILL.md`,仅在 Skill 不可用时读取 `.rsp/rsp-rules.md`。
194
205
 
195
- 如果文档中写的是 `rsp <command>`,默认前提是你的环境里已经能直接运行 `rsp`。进行 opt-in beta 评估时,应固定精确 prerelease 身份,例如 `npx -y @oevery/rsp@3.1.0-beta.2 <command>`;stable 用户仍可使用不带版本的入口获取 npm `latest`。
206
+ 如果文档中写的是 `rsp <command>`,默认前提是你的环境里已经能直接运行 `rsp`。进行 opt-in beta 评估时,应固定精确 prerelease 身份,例如 `npx -y @oevery/rsp@3.1.0-beta.4 <command>`;stable 用户仍可使用不带版本的入口获取 npm `latest`。
196
207
 
197
208
  将当前精确包内置的默认生命周期 Skill 套件安装到当前项目:
198
209
 
@@ -210,16 +221,18 @@ rsp skills list --json
210
221
 
211
222
  该命令会预检十一个默认 package-owned targets,保留无关的 `.agents/skills` 条目(包括可选 Skills),并且只有显式传入 `--force` 才会替换内容不同的已选目录。按精确名称安装可选的项目级审计 Skill:
212
223
 
224
+ 升级仍包含 `rsp-address-review` 或 `rsp-codebase-audit` 的安装时,其替代项分别是 `rsp-resolve-findings` 和 `rsp-structural-audit`。安装器会在变更前停止,直到 `--force` 显式授权事务性移除这个过时的 package-owned 目录;`--dry-run --force` 可同时预览移除与安装。
225
+
213
226
  ```bash
214
- rsp skills install rsp-codebase-audit --dry-run
215
- rsp skills install rsp-codebase-audit
227
+ rsp skills install rsp-structural-audit --dry-run
228
+ rsp skills install rsp-structural-audit
216
229
  ```
217
230
 
218
231
  两种形式都从调用 `rsp` 的同一个包安装,因此 beta 评估可以固定精确 npm 身份:
219
232
 
220
233
  ```bash
221
- npx -y @oevery/rsp@3.1.0-beta.2 skills install --dry-run
222
- npx -y @oevery/rsp@3.1.0-beta.2 skills install
234
+ npx -y @oevery/rsp@3.1.0-beta.4 skills install --dry-run
235
+ npx -y @oevery/rsp@3.1.0-beta.4 skills install
223
236
  ```
224
237
 
225
238
  精确 prerelease 身份可以避免依赖持续移动的 dist-tag。`rsp update` 只刷新由 RSP 管理的项目文件;刷新 package-owned Skill 套件需要单独运行 `rsp skills install`。
@@ -273,8 +286,8 @@ durable review 包含两个独立语义判断:是否更新当前事实或作
273
286
 
274
287
  新项目:
275
288
 
276
- 1. `npx -y @oevery/rsp@3.1.0-beta.2 init`
277
- 2. 优先使用 `npx -y @oevery/rsp@3.1.0-beta.2 init --with-project-setup`,或手动执行 `rsp create project-setup`
289
+ 1. `npx -y @oevery/rsp@3.1.0-beta.4 init`
290
+ 2. 优先使用 `npx -y @oevery/rsp@3.1.0-beta.4 init --with-project-setup`,或手动执行 `rsp create project-setup`
278
291
  3. 填写 `.rsp/specs/design.md`
279
292
  4. 仅在需要新的长期项目文档时使用 `rsp add spec <name>`
280
293
  5. 将长期理由写入配置的 Decision Record 目录,将稳定的作用域操作指令写入 nearest project-owned `AGENTS.md`
@@ -287,14 +300,14 @@ durable review 包含两个独立语义判断:是否更新当前事实或作
287
300
 
288
301
  已有复杂 `AGENTS.md` 的项目:
289
302
 
290
- 1. `npx -y @oevery/rsp@3.1.0-beta.2 init`
303
+ 1. `npx -y @oevery/rsp@3.1.0-beta.4 init`
291
304
  2. 保持受管块尽量薄
292
305
  3. 将项目级边界与导航放在 `.rsp/specs/design.md`,把成组的长期事实放入最小领域 Spec
293
306
  4. 只有需要额外的 durable current-fact 文档时才使用 `rsp add spec <name>`
294
307
 
295
308
  AI 协助接入:
296
309
 
297
- 1. `npx -y @oevery/rsp@3.1.0-beta.2 init --agents-mode print --with-project-setup`
310
+ 1. `npx -y @oevery/rsp@3.1.0-beta.4 init --agents-mode print --with-project-setup`
298
311
  2. 保持受管块原样,只在需要时调整周围由人维护的内容
299
312
  3. 让 AI 审阅并填写 `.rsp/changes/project-setup.md`
300
313
  4. 让 AI 填写 `.rsp/specs/design.md`
@@ -305,7 +318,7 @@ AI 协助接入:
305
318
  ```text
306
319
  rsp init --agents-mode <mode> 搭建 .rsp/,并确保 AGENTS.md 含有 RSP 入口块
307
320
  rsp init --with-project-setup 同时创建 .rsp/changes/project-setup.md
308
- rsp update 刷新 fallback protocol、修复 AGENTS 受管块并重建索引
321
+ rsp update 刷新受管项目文件,不更新 packaged Skills
309
322
  rsp ui [--lang auto|en|zh-CN] 打开只读交互式仪表盘
310
323
  rsp skills 在 dual TTY 中打开交互式项目 Skill 管理器
311
324
  rsp skills list [--json] 列出内置 Skills 及其精确项目安装状态
@@ -317,13 +330,13 @@ rsp group create <name> [goal] 创建不进入 focus 的 .rsp/changes/<name>/00-
317
330
  rsp group close <name> 所有子 Change 归档后关闭并归档 Group Brief
318
331
  rsp focus <name> 将一个 open change 标记为当前聚焦
319
332
  rsp unfocus <name> 将一个 open change 移出当前聚焦集合
320
- rsp archive <name> 归档到 .rsp/archives/ 并更新 archive index
321
- rsp archive --dry-run <name> 预览归档就绪状态,不移动 change
333
+ rsp archive <name> 归档到 .rsp/archives/
334
+ rsp archive --dry-run <name> 已弃用的 rsp ready 兼容入口;不会移动 change
322
335
  rsp ready <name> [--json [--compact]] [--verbose]
323
- 预览归档就绪状态(与 archive --dry-run 相同)
336
+ canonical 只读归档就绪投影
324
337
  rsp show <name|--focused> [--json [--compact]] [--verbose]
325
338
  显示 change 上下文,带就绪信号和上下文路径
326
- rsp history [--limit <n>] [--since <date>] [--until <date>] [--kind <kind>] [--group <group>] [--json [--compact]]
339
+ rsp history [--limit <n>] [--since <date>] [--until <date>] [--kind <kind>] [--group <group>] [--search <text>] [--json [--compact]]
327
340
  列出有界的已归档 Change 摘要(默认 20,最大 100)
328
341
  rsp history <work-ref> [--json [--compact]]
329
342
  显示一个精确已归档 Change 的有界证据详情
@@ -339,7 +352,7 @@ rsp doctor [--fix] [--json [--compact]] [--verbose]
339
352
 
340
353
  在真实交互式终端中,裸 `rsp` 会打开与 `rsp ui` 相同的只读仪表盘。CI、管道、重定向流和 `TERM=dumb` 继续使用静态命令输出;人类快照使用 `rsp status`,自动化使用 `rsp status --json`。仪表盘不会创建、聚焦或归档工作。
341
354
 
342
- 仪表盘快捷键:`Tab` 按 Changes/Groups/History 顺序切换,方向键或 `j`/`k` 移动,`/` 筛选当前 scope,`Enter` 打开全宽详情,`r` 刷新当前 scope,`?` 显示帮助,`q`、`Ctrl-C` 或顶层 `Esc` 退出。History 首次进入时才加载默认有界的近期结果,只有选中记录并按 `Enter` 后才按唯一 archive path 加载结构化详情;更早的记录使用 `rsp history` 过滤查询。可设置 `RSP_UI_LANG=en|zh-CN` 或传入 `rsp ui --lang`;只有仪表盘自有标签会本地化。现有 CLI help、纯文本输出、JSON、WorkRef、路径、命令、Skills 和 RSP artifacts 仍保持英文。
355
+ 仪表盘快捷键:`Tab` 按 Changes/Groups/History 顺序切换,方向键或 `j`/`k` 移动,`/` 筛选当前 scope,`Enter` 打开全宽详情,`r` 刷新当前 scope,`?` 显示帮助,`q`、`Ctrl-C` 或顶层 `Esc` 退出。History 首次进入时才加载默认有界的近期结果,只有选中记录并按 `Enter` 后才按唯一 archive path 加载结构化详情;更早的记录使用 `rsp history` 过滤查询。可设置 `RSP_UI_LANG=en|zh-CN` 或传入 `rsp ui --lang`;只有仪表盘自有标签会本地化。该 UI 设置不会本地化 CLI help、纯文本输出、JSON、路径、命令、Skills 或已有产物。WorkRef 可使用安全 Unicode 身份契约,新产物正文则遵循上文的项目语言策略。
343
356
 
344
357
  当没有 focused change 时,`rsp status` 和 `rsp show --focused --json` 会输出 `nextActions`,但不会自动猜测哪个 open change 是当前工作。
345
358
 
@@ -347,7 +360,7 @@ rsp doctor [--fix] [--json [--compact]] [--verbose]
347
360
 
348
361
  `rsp status --json` 会在 `plan.nodes`、`plan.ready`、`plan.edges`、`plan.blocked` 和 `plan.waves` 中返回同一份依赖图。节点会区分过滤器选中的 Change 与仅用于解释的前置依赖上下文;过滤后的计划会保留解释结果所需的传递前置依赖闭包。由于同一个前置依赖可能被多个 Change 共享,JSON 保持扁平图结构而不嵌套 children。每条边都读作“`change` requires `requires`”。这些内容是派生的导航事实,不是执行授权或持久化 workflow state。
349
362
 
350
- `rsp history` 直接检查权威 archive 文件,而不信任生成的 archive index。列表按 archive date 降序、WorkRef、source path 排序,在 1–100 的结果上限前应用 inclusive date、精确 kind 和精确 Group 过滤。详情只返回有界 summary、scenario/checkbox counts 与结构化 Tasks/Verify/Blockers evidence,不返回 raw Markdown;重复 WorkRef、不可读或格式错误的 archive 会 fail closed。
363
+ `rsp history` 直接检查权威 archive 文件;系统不再生成或读取 Archive Index。列表按 archive date 降序、WorkRef、source path 排序,在 1–100 的结果上限前应用 inclusive date、精确 kind、精确 Group 以及 WorkRef/summary 的大小写不敏感字面搜索。详情只返回有界 summary、scenario/checkbox counts 与结构化 Tasks/Verify/Blockers evidence,不返回 raw Markdown;重复 WorkRef、不可读或格式错误的 archive 会 fail closed。`status` archive trend 与 TUI History 使用同一份已验证 inspection。
351
364
 
352
365
  产生 JSON 的 `status`、`show`、`ready`、`check`、`doctor` 和 `history` 都支持 `--json --compact`:内容与普通 `--json` 解析结果相同,但序列化为一行并以 LF 结尾。`--compact` 必须与 `--json` 同时使用,其他命令会在执行行为前拒绝它。
353
366
 
@@ -5,7 +5,7 @@ import {
5
5
  inspectManagedDirectory,
6
6
  inspectManagedFileTree,
7
7
  resolveManagedDirectoryChain
8
- } from "./chunk-OTJFL6XH.mjs";
8
+ } from "./chunk-FJVH7ZYU.mjs";
9
9
 
10
10
  // src/commands/skills.ts
11
11
  import { randomUUID } from "crypto";
@@ -14,17 +14,21 @@ import { chmod, copyFile, mkdir, readdir, readFile, rename, rm } from "fs/promis
14
14
  import { dirname, join, relative } from "path";
15
15
  var DEFAULT_PACKAGED_SKILL_NAMES = [
16
16
  "rsp",
17
- "rsp-address-review",
18
17
  "rsp-commit",
19
18
  "rsp-design",
20
19
  "rsp-diagnose",
21
20
  "rsp-implement",
22
21
  "rsp-manage",
23
22
  "rsp-release-docs",
23
+ "rsp-resolve-findings",
24
24
  "rsp-review",
25
25
  "rsp-shape",
26
26
  "rsp-tdd"
27
27
  ];
28
+ var OBSOLETE_PACKAGED_SKILL_RENAMES = {
29
+ "rsp-address-review": "rsp-resolve-findings",
30
+ "rsp-codebase-audit": "rsp-structural-audit"
31
+ };
28
32
  function unsupportedEntry(path, label) {
29
33
  return new ManagedPathError(path, `unsupported entry in the ${label} tree: ${path}`);
30
34
  }
@@ -199,8 +203,9 @@ async function installPackagedSkills(args = {}, options = {}) {
199
203
  }
200
204
  const skills = requestedNames.map((name) => packagedSkillsByName.get(name)).sort((a, b) => a.name.localeCompare(b.name));
201
205
  const targetRoot = resolveManagedDirectoryChain(projectRoot, [".agents", "skills"], "project Skills root");
202
- const result = { installed: [], unchanged: [], replaced: [] };
206
+ const result = { installed: [], removed: [], unchanged: [], replaced: [] };
203
207
  const conflicts = [];
208
+ const obsoleteConflicts = [];
204
209
  const targetTreeIdentities = /* @__PURE__ */ new Map();
205
210
  for (const skill of skills) {
206
211
  const target = join(targetRoot, skill.name);
@@ -221,8 +226,30 @@ async function installPackagedSkills(args = {}, options = {}) {
221
226
  conflicts.push(skill.name);
222
227
  }
223
228
  }
229
+ const selectedNames = new Set(skills.map((skill) => skill.name));
230
+ const obsoleteTreeIdentities = /* @__PURE__ */ new Map();
231
+ for (const [obsolete, replacement] of Object.entries(OBSOLETE_PACKAGED_SKILL_RENAMES)) {
232
+ if (!selectedNames.has(replacement))
233
+ continue;
234
+ const target = join(targetRoot, obsolete);
235
+ if (inspectTarget(target, obsolete) === "missing")
236
+ continue;
237
+ const targetIdentity = inspectDirectoryIdentity(target, `obsolete installed Skill ${obsolete}`);
238
+ assertDirectoryIdentities([targetIdentity], `obsolete installed Skill ${obsolete}`);
239
+ if (args.force) {
240
+ result.removed.push(obsolete);
241
+ obsoleteTreeIdentities.set(obsolete, targetIdentity);
242
+ } else {
243
+ obsoleteConflicts.push(`${obsolete} -> ${replacement}`);
244
+ }
245
+ }
246
+ const conflictMessages = [];
224
247
  if (conflicts.length > 0)
225
- throw new Error(`conflicting packaged Skills: ${conflicts.join(", ")}; rerun with --force to replace only these package-owned directories`);
248
+ conflictMessages.push(`conflicting packaged Skills: ${conflicts.join(", ")}`);
249
+ if (obsoleteConflicts.length > 0)
250
+ conflictMessages.push(`obsolete packaged Skill renames: ${obsoleteConflicts.join(", ")}`);
251
+ if (conflictMessages.length > 0)
252
+ throw new Error(`${conflictMessages.join("; ")}; rerun with --force to replace or remove only these package-owned directories`);
226
253
  if (args.dryRun)
227
254
  return result;
228
255
  await options.onMutationStep?.({ phase: "before-target-root-mutation", targetRoot });
@@ -252,6 +279,15 @@ async function installPackagedSkills(args = {}, options = {}) {
252
279
  for (const name of result.replaced) {
253
280
  assertDirectoryIdentities([targetTreeIdentities.get(name)], `installed Skill ${name}`);
254
281
  }
282
+ for (const name of result.removed) {
283
+ assertDirectoryIdentities([obsoleteTreeIdentities.get(name)], `obsolete installed Skill ${name}`);
284
+ }
285
+ for (const name of result.removed) {
286
+ assertDirectoryIdentities(targetIdentities, "project Skills root");
287
+ assertDirectoryIdentities([obsoleteTreeIdentities.get(name)], `obsolete installed Skill ${name}`);
288
+ await renamePath(join(targetRoot, name), join(previousRoot, name));
289
+ movedPrevious.push(name);
290
+ }
255
291
  for (const name of result.replaced) {
256
292
  assertDirectoryIdentities(targetIdentities, "project Skills root");
257
293
  assertDirectoryIdentities([targetTreeIdentities.get(name)], `installed Skill ${name}`);
@@ -308,7 +344,7 @@ async function installPackagedSkills(args = {}, options = {}) {
308
344
  }
309
345
  function printSkillInstallResult(result, dryRun = false) {
310
346
  const prefix = dryRun ? "would be " : "";
311
- for (const status of ["installed", "unchanged", "replaced"]) {
347
+ for (const status of ["installed", "unchanged", "replaced", "removed"]) {
312
348
  if (result[status].length > 0)
313
349
  console.log(` ${prefix}${status}: ${result[status].join(", ")}`);
314
350
  }