@oevery/rsp 2.0.0 → 2.0.3

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
@@ -55,11 +55,12 @@ npx -y @oevery/rsp doctor
55
55
  ## File ownership
56
56
 
57
57
  - `AGENTS.md`: only the `<!-- rsp:begin --> ... <!-- rsp:end -->` block is managed by RSP.
58
- - `.rsp/specs/INDEX.md`: auto-generated. Rebuild with `rsp update`.
58
+ - `.rsp/specs/INDEX.md`: auto-generated index of additional spec files beyond `design.md`. Rebuild with `rsp update`.
59
59
  - `.rsp/archives/INDEX.md`: auto-generated. Rebuild with `rsp update`.
60
60
  - `.rsp/specs/design.md`: created by `rsp init`, then owned by the project.
61
61
  - `.rsp/rules/project-rules.md`: optional; create only when the project has durable local rules.
62
62
  - Keep durable architecture, boundaries, and cross-cutting technical constraints in `.rsp/specs/design.md`.
63
+ - Treat `.rsp/specs/INDEX.md` as a directory for additional spec files; it does not list `design.md`.
63
64
  - Keep stable workflow rules, validation expectations, and local operating constraints in `.rsp/rules/project-rules.md`.
64
65
 
65
66
  ## AGENTS integration
@@ -70,6 +71,9 @@ Managed block example:
70
71
  <!-- rsp:begin -->
71
72
  ## RSP Entry
72
73
 
74
+ RSP keeps durable rules, specs, and current work under `.rsp/`.
75
+ Treat AGENTS.md as navigation only; keep durable rules and design in `.rsp/`.
76
+
73
77
  Read in order:
74
78
  1. .rsp/rules/rsp-rules.md
75
79
  2. .rsp/focus.d/
@@ -77,6 +81,9 @@ Read in order:
77
81
  4. .rsp/specs/design.md
78
82
  5. .rsp/specs/INDEX.md
79
83
  6. only the relevant additional .rsp/rules/*.md and .rsp/specs/*.md files
84
+
85
+ If `.rsp/focus.d/` is empty, ask what to work on or suggest `npx -y @oevery/rsp create <name>`.
86
+ If your agent supports Agent Skills, load `rsp` for setup, repair, and durable-decision tasks.
80
87
  <!-- rsp:end -->
81
88
  ```
82
89
 
@@ -111,11 +118,17 @@ When this README shows `rsp <command>`, it assumes the command is already availa
111
118
  Example optional installation flow:
112
119
 
113
120
  ```bash
114
- npx skills add oevery/rsp --skill rsp
121
+ npx skills add oevery/rsp
115
122
  ```
116
123
 
117
124
  This repository publishes a skill named `rsp` under `skills/rsp/`.
118
125
 
126
+ `rsp update` refreshes project-local RSP files only. If you use the published RSP skill, refresh it separately after upgrading:
127
+
128
+ ```bash
129
+ npx skills add oevery/rsp
130
+ ```
131
+
119
132
  ## Work Model
120
133
 
121
134
  ```text
package/README.zh-CN.md CHANGED
@@ -55,11 +55,12 @@ npx -y @oevery/rsp doctor
55
55
  ## 文件所有权
56
56
 
57
57
  - `AGENTS.md`:只有 `<!-- rsp:begin --> ... <!-- rsp:end -->` 受管块由 RSP 维护。
58
- - `.rsp/specs/INDEX.md`:自动生成,使用 `rsp update` 重建。
58
+ - `.rsp/specs/INDEX.md`:自动生成,用于索引 `design.md` 之外的附加 spec 文件;使用 `rsp update` 重建。
59
59
  - `.rsp/archives/INDEX.md`:自动生成,使用 `rsp update` 重建。
60
60
  - `.rsp/specs/design.md`:由 `rsp init` 创建,之后由项目维护。
61
61
  - `.rsp/rules/project-rules.md`:可选,仅在项目确有长期本地规则时创建。
62
62
  - 将长期架构、边界和跨模块技术约束放在 `.rsp/specs/design.md`。
63
+ - 将 `.rsp/specs/INDEX.md` 视为附加 spec 的目录;它不列出 `design.md`。
63
64
  - 将稳定的工作流规则、验证要求和本地运行约束放在 `.rsp/rules/project-rules.md`。
64
65
 
65
66
  ## AGENTS 接入
@@ -70,6 +71,9 @@ npx -y @oevery/rsp doctor
70
71
  <!-- rsp:begin -->
71
72
  ## RSP Entry
72
73
 
74
+ RSP keeps durable rules, specs, and current work under `.rsp/`.
75
+ Treat AGENTS.md as navigation only; keep durable rules and design in `.rsp/`.
76
+
73
77
  Read in order:
74
78
  1. .rsp/rules/rsp-rules.md
75
79
  2. .rsp/focus.d/
@@ -77,6 +81,9 @@ Read in order:
77
81
  4. .rsp/specs/design.md
78
82
  5. .rsp/specs/INDEX.md
79
83
  6. only the relevant additional .rsp/rules/*.md and .rsp/specs/*.md files
84
+
85
+ If `.rsp/focus.d/` is empty, ask what to work on or suggest `npx -y @oevery/rsp create <name>`.
86
+ If your agent supports Agent Skills, load `rsp` for setup, repair, and durable-decision tasks.
80
87
  <!-- rsp:end -->
81
88
  ```
82
89
 
@@ -105,11 +112,17 @@ Read in order:
105
112
  可选安装示例:
106
113
 
107
114
  ```bash
108
- npx skills add oevery/rsp --skill rsp
115
+ npx skills add oevery/rsp
109
116
  ```
110
117
 
111
118
  本仓库发布了一个名为 `rsp` 的 skill,位于 `skills/rsp/`。
112
119
 
120
+ `rsp update` 只会刷新项目内的 RSP 文件。如果你在使用发布出来的 RSP skill,升级后还需要单独刷新一次:
121
+
122
+ ```bash
123
+ npx skills add oevery/rsp
124
+ ```
125
+
113
126
  ## 工作模型
114
127
 
115
128
  ```text
package/dist/cli.mjs CHANGED
@@ -19,7 +19,7 @@ import pc from "picocolors";
19
19
 
20
20
  // src/core/helpers.ts
21
21
  import { existsSync } from "fs";
22
- import { readdir, readFile, rmdir, stat } from "fs/promises";
22
+ import { readdir, readFile, rmdir } from "fs/promises";
23
23
  import { basename, dirname, join, relative, sep } from "path";
24
24
  import { parse } from "yaml";
25
25
 
@@ -166,6 +166,7 @@ kind: ops
166
166
 
167
167
  ## Tasks
168
168
  - [ ] Review the repository structure, entrypoints, and primary outputs
169
+ - [ ] Review AGENTS.md and confirm the RSP entry points to the right project files
169
170
  - [ ] Fill .rsp/specs/design.md with durable architecture facts
170
171
  - [ ] Add .rsp/rules/project-rules.md if stable local rules or validation steps exist
171
172
 
@@ -209,12 +210,15 @@ ${template.acceptanceSection}
209
210
  - Approach:
210
211
  - ${template.approach}
211
212
  - Affected areas:
212
- - ${template.affectedAreas}
213
+ - ${template.affectedArea1}
214
+ - ${template.affectedArea2}
213
215
  - Constraints:
214
216
  - ${template.constraints}
215
217
 
216
218
  ## Tasks
219
+ - [ ] Finalize the proposal, spec, and design details for this change
217
220
  - [ ] ${template.task}
221
+ - [ ] Verify the result and update any required durable docs or rules
218
222
 
219
223
  ## Verify
220
224
  - Automated:
@@ -231,6 +235,51 @@ ${template.acceptanceSection}
231
235
  }
232
236
  function getChangeTemplateByKind(kind) {
233
237
  switch (kind) {
238
+ case "feature":
239
+ return {
240
+ why: "<what user need or capability gap this addresses>",
241
+ scope: "<what new behavior or capability will be delivered>",
242
+ nonGoals: "<what related capabilities are explicitly out of scope>",
243
+ specSection: "### ADDED\n- Requirement: <new user-facing behavior>\n - <verifiable requirement for the new capability>",
244
+ acceptanceSection: "#### Scenario: user exercises the new capability\n- GIVEN <context>\n- WHEN <user action>\n- THEN <expected new behavior>",
245
+ approach: "<how the new capability will be implemented>",
246
+ affectedArea1: "<concrete file path, directory, module, or subsystem 1>",
247
+ affectedArea2: "<concrete file path, directory, module, or subsystem 2 if needed>",
248
+ constraints: "<behavior, compatibility, performance, safety, or scope constraint that must hold>",
249
+ task: "<implement the new behavior and its acceptance scenario in the affected areas>",
250
+ automatedVerify: "<exact test, lint, build, or check command for the new behavior>",
251
+ manualVerify: "<exact end-to-end user scenario to validate the new capability>"
252
+ };
253
+ case "fix":
254
+ return {
255
+ why: "<what current behavior is wrong or broken>",
256
+ scope: "<what specific defect is being corrected>",
257
+ nonGoals: "<what related but separate issues are out of scope>",
258
+ specSection: "### MODIFIED\n- Requirement: correct behavior\n - <expected correct behavior after the fix>",
259
+ acceptanceSection: "#### Scenario: defect is resolved\n- GIVEN <conditions that trigger the defect>\n- WHEN <action that previously failed>\n- THEN <expected correct outcome>\n- AND the original broken outcome no longer occurs",
260
+ approach: "<root cause analysis and fix strategy>",
261
+ affectedArea1: "<concrete file path, directory, module, or subsystem containing the defect>",
262
+ affectedArea2: "<secondary path, dependency, or test file if needed>",
263
+ constraints: "<regression, backward-compatibility, safety, or scope constraint that must hold>",
264
+ task: "<identify the root cause and apply the minimal fix>",
265
+ automatedVerify: "<exact regression test, lint, build, or check command that proves the fix>",
266
+ manualVerify: "<exact steps to reproduce the original issue and confirm it no longer occurs>"
267
+ };
268
+ case "refactor":
269
+ return {
270
+ why: "<what maintainability, readability, or structural issue motivates this>",
271
+ scope: "<what code areas are being restructured>",
272
+ nonGoals: "<no behavior change is expected or intended>",
273
+ specSection: "### MODIFIED\n- Requirement: internal structure improvement\n - <desired structural outcome without observable behavior change>",
274
+ acceptanceSection: "#### Scenario: behavior is preserved after restructuring\n- GIVEN the existing codebase before the refactor\n- WHEN the refactored code runs against existing tests\n- THEN all existing tests pass unchanged",
275
+ approach: "<how the code will be restructured (rename, extract, move, etc.)>",
276
+ affectedArea1: "<concrete file path, directory, module, or subsystem being refactored>",
277
+ affectedArea2: "<secondary path, dependency, or test file if needed>",
278
+ constraints: "<observable behavior must remain unchanged; compatibility, performance, and safety constraints must still hold>",
279
+ task: "<restructure the code while keeping behavior identical>",
280
+ automatedVerify: "<exact existing test, lint, build, or check command that must continue to pass>",
281
+ manualVerify: "<exact scenario to spot-check that behavior is unchanged after the refactor>"
282
+ };
234
283
  case "docs":
235
284
  return {
236
285
  why: "<why the documentation change matters>",
@@ -239,11 +288,12 @@ function getChangeTemplateByKind(kind) {
239
288
  specSection: "### MODIFIED\n- Requirement: documentation accuracy\n - <what durable reader-facing behavior or explanation changes>",
240
289
  acceptanceSection: "#### Scenario: reader follows the updated guidance\n- GIVEN the updated documentation\n- WHEN a reader follows the documented workflow\n- THEN the steps are accurate and sufficient",
241
290
  approach: "<how the documentation will be updated and organized>",
242
- affectedAreas: "<doc path or documentation area>",
243
- constraints: "<durable wording, consistency, or scope constraint>",
291
+ affectedArea1: "<concrete doc path, directory, module doc, or documentation surface 1>",
292
+ affectedArea2: "<secondary doc path or reference file if needed>",
293
+ constraints: "<durable wording, consistency, scope, or audience constraint that must hold>",
244
294
  task: "<update the target documentation and supporting references>",
245
- automatedVerify: "<run markdown, docs, or link checks if applicable>",
246
- manualVerify: "<review the updated doc as a reader and confirm it is accurate>"
295
+ automatedVerify: "<exact markdown, docs, link, lint, build, or check command if applicable>",
296
+ manualVerify: "<exact reader or operator scenario to confirm the updated guidance is accurate>"
247
297
  };
248
298
  case "research":
249
299
  return {
@@ -253,11 +303,12 @@ function getChangeTemplateByKind(kind) {
253
303
  specSection: "### ADDED\n- Requirement: research outcome recording\n - <what finding, option, or decision must be captured clearly>",
254
304
  acceptanceSection: "#### Scenario: research question is resolved\n- GIVEN the current uncertainty or open question\n- WHEN the investigation is completed\n- THEN the result is recorded clearly enough to guide follow-up work",
255
305
  approach: "<how the investigation will be performed and what evidence will be gathered>",
256
- affectedAreas: "<code path, subsystem, or source being investigated>",
257
- constraints: "<time, evidence, or scope constraint for the investigation>",
258
- task: "<gather evidence and record the resulting recommendation or finding>",
259
- automatedVerify: "<run any command needed to confirm the observed behavior>",
260
- manualVerify: "<review the findings and confirm they answer the original question>"
306
+ affectedArea1: "<concrete file path, directory, module, subsystem, or source under investigation>",
307
+ affectedArea2: "<secondary path, dependency, environment, or evidence source if needed>",
308
+ constraints: "<time, evidence, safety, or scope constraint for the investigation>",
309
+ task: "<gather evidence, record the recommendation or finding, and note any follow-up implementation work if needed>",
310
+ automatedVerify: "<exact command, script, query, or check used to confirm the observed behavior>",
311
+ manualVerify: "<exact review of the findings to confirm they answer the original question and identify follow-up work if needed>"
261
312
  };
262
313
  case "ops":
263
314
  return {
@@ -267,11 +318,12 @@ function getChangeTemplateByKind(kind) {
267
318
  specSection: "### MODIFIED\n- Requirement: operational behavior\n - <what reliable operational outcome should change or stay true>",
268
319
  acceptanceSection: "#### Scenario: operational path succeeds\n- GIVEN the target environment or workflow\n- WHEN the operational change is applied\n- THEN the expected operational outcome is reliable",
269
320
  approach: "<how the operational change will be applied safely>",
270
- affectedAreas: "<script, config, workflow, or environment path>",
271
- constraints: "<rollback, safety, or environment constraint>",
321
+ affectedArea1: "<concrete script, config path, workflow, environment path, or operational surface 1>",
322
+ affectedArea2: "<secondary script, config path, dependency, or environment surface if needed>",
323
+ constraints: "<rollback, safety, reliability, environment, or scope constraint that must hold>",
272
324
  task: "<apply and verify the operational change>",
273
- automatedVerify: "<run the relevant operational validation command>",
274
- manualVerify: "<exercise the target workflow and confirm the operational result>"
325
+ automatedVerify: "<exact operational validation, lint, build, deploy, or check command>",
326
+ manualVerify: "<exact operator workflow or environment scenario to confirm the operational result>"
275
327
  };
276
328
  default:
277
329
  return {
@@ -281,11 +333,12 @@ function getChangeTemplateByKind(kind) {
281
333
  specSection: "### ADDED\n- Requirement: <new or updated behavior>\n - <verifiable requirement>",
282
334
  acceptanceSection: "#### Scenario: <name>\n- GIVEN <context>\n- WHEN <action>\n- THEN <expected outcome>",
283
335
  approach: "<how the change will be implemented>",
284
- affectedAreas: "<path or subsystem>",
285
- constraints: "<binding technical or product constraint>",
286
- task: "<implementation task>",
287
- automatedVerify: "<test command or automated check>",
288
- manualVerify: "<manual scenario to validate>"
336
+ affectedArea1: "<concrete file path, directory, module, or subsystem 1>",
337
+ affectedArea2: "<concrete file path, directory, module, or subsystem 2 if needed>",
338
+ constraints: "<behavior, compatibility, performance, safety, or scope constraint that must hold>",
339
+ task: "<implement the core change in the affected areas>",
340
+ automatedVerify: "<exact test, lint, build, or check command>",
341
+ manualVerify: "<exact end-to-end scenario to validate>"
289
342
  };
290
343
  }
291
344
  }
@@ -293,6 +346,9 @@ function renderRspAgentsBlock() {
293
346
  return `${RSP_AGENTS_BEGIN}
294
347
  ## RSP Entry
295
348
 
349
+ RSP keeps durable rules, specs, and current work under \`.rsp/\`.
350
+ Treat AGENTS.md as navigation only; keep durable rules and design in \`.rsp/\`.
351
+
296
352
  Read in order:
297
353
  1. .rsp/rules/rsp-rules.md
298
354
  2. .rsp/focus.d/
@@ -300,6 +356,9 @@ Read in order:
300
356
  4. .rsp/specs/design.md
301
357
  5. .rsp/specs/INDEX.md
302
358
  6. only the relevant additional .rsp/rules/*.md and .rsp/specs/*.md files
359
+
360
+ If \`.rsp/focus.d/\` is empty, ask what to work on or suggest \`npx -y @oevery/rsp create <name>\`.
361
+ If your agent supports Agent Skills, load \`rsp\` for setup, repair, and durable-decision tasks.
303
362
  ${RSP_AGENTS_END}`;
304
363
  }
305
364
  function upsertRspAgentsBlock(content) {
@@ -332,6 +391,16 @@ function guardRspInitialized() {
332
391
  process.exit(1);
333
392
  }
334
393
  }
394
+ async function getFocusedChangeNames(options = {}) {
395
+ const names = /* @__PURE__ */ new Set();
396
+ const focusDir = join(RSP_DIR, "focus.d");
397
+ if (!existsSync(focusDir))
398
+ return names;
399
+ const entries = await walkFiles(focusDir, options);
400
+ for (const entryPath of entries)
401
+ names.add(normalizeLogicalPath(relative(focusDir, entryPath)));
402
+ return names;
403
+ }
335
404
  function getOpenCheckboxes(sectionText) {
336
405
  return sectionText.split("\n").map((line) => line.trim()).filter((line) => /^- \[[ /]\]/.test(line));
337
406
  }
@@ -632,14 +701,17 @@ async function buildSpecsIndex({ acquireLock = true } = {}) {
632
701
  `);
633
702
  return;
634
703
  }
635
- const specFiles = (await walkMarkdownFiles(specsDir)).filter((fp) => basename2(fp) !== "INDEX.md").sort();
704
+ const specFiles = (await walkMarkdownFiles(specsDir)).filter((fp) => {
705
+ const name = basename2(fp);
706
+ return name !== "INDEX.md" && name !== "design.md";
707
+ }).sort();
636
708
  const lines = [];
637
709
  lines.push("# Specs Index");
638
710
  lines.push("");
639
- lines.push("_Project-level specs and design notes._");
711
+ lines.push("_Additional project-level specs beyond `design.md`._");
640
712
  lines.push("");
641
713
  if (specFiles.length === 0) {
642
- lines.push("_No project-level specs yet._");
714
+ lines.push("_No additional project-level specs yet._");
643
715
  } else {
644
716
  lines.push("| File | Title | Summary |");
645
717
  lines.push("|------|-------|---------|");
@@ -782,6 +854,7 @@ async function archiveChange(name) {
782
854
  console.error(` ${pc.red("Error:")} change name must be kebab-case with optional subdirectory (lowercase, digits, hyphens, slashes)`);
783
855
  process.exit(1);
784
856
  }
857
+ guardRspInitialized();
785
858
  const srcPath = join7(CHANGES_DIR, `${name}.md`);
786
859
  if (!existsSync7(srcPath)) {
787
860
  console.error(` ${pc.red("Change not found:")} .rsp/changes/${name}.md`);
@@ -1185,7 +1258,7 @@ async function createChange(name, summary = "", kind) {
1185
1258
  console.log(` ${pc.dim("Unchanged focus.")} Run: rsp focus ${name}`);
1186
1259
  else
1187
1260
  console.log(` ${pc.dim("focused via focus.d")} \u2192 ${name}`);
1188
- console.log(` ${pc.cyan("Next:")} edit the change file and complete the tasks
1261
+ console.log(` ${pc.cyan("Next:")} fill proposal/spec/design first, then implement and complete the tasks
1189
1262
  `);
1190
1263
  });
1191
1264
  }
@@ -1387,8 +1460,7 @@ function reportConfigListField(checks, parsed, key) {
1387
1460
  async function checkActiveChangeConsistency(checks, reportRuntime) {
1388
1461
  const changeFiles = existsSync10(CHANGES_DIR) ? await walkMarkdownFiles(CHANGES_DIR, { onError: reportRuntime }) : [];
1389
1462
  const changeNames = new Set(changeFiles.map((fp) => changeNameFromPath(CHANGES_DIR, fp)));
1390
- const focusEntries = existsSync10(FOCUS_DIR) ? await walkFiles(FOCUS_DIR, { onError: reportRuntime }) : [];
1391
- const focusNames = new Set(focusEntries.map((fp) => normalizeLogicalPath(relative5(FOCUS_DIR, fp))));
1463
+ const focusNames = await getFocusedChangeNames({ onError: reportRuntime });
1392
1464
  const missingChangeFiles = [...focusNames].filter((name) => !changeNames.has(name));
1393
1465
  const unfocusedChangeFiles = [...changeNames].filter((name) => !focusNames.has(name));
1394
1466
  if (missingChangeFiles.length === 0) {
@@ -1515,7 +1587,7 @@ async function initProject(args = {}) {
1515
1587
  const bundledRules = await readFile9(join12(PKG_ROOT, "rules", "rsp-rules.md"), "utf-8");
1516
1588
  created = await ensureFile(join12(RSP_DIR, "rules", "rsp-rules.md"), bundledRules) || created;
1517
1589
  created = await ensureFile(join12(RSP_DIR, "config.yaml"), generateConfigTemplate()) || created;
1518
- const createdSpecsIndex = await ensureFile(join12(RSP_DIR, "specs", "INDEX.md"), "# Specs Index\n\n_Project-level specs and design notes._\n");
1590
+ const createdSpecsIndex = await ensureFile(join12(RSP_DIR, "specs", "INDEX.md"), "# Specs Index\n\n_Additional project-level specs beyond `design.md`._\n");
1519
1591
  created = createdSpecsIndex || created;
1520
1592
  const createdDesign = await ensureFile(join12(RSP_DIR, "specs", "design.md"), generateDesignContent(projectName));
1521
1593
  created = createdDesign || created;
@@ -1595,21 +1667,16 @@ ${managed}
1595
1667
 
1596
1668
  // src/commands/status.ts
1597
1669
  import { existsSync as existsSync13 } from "fs";
1598
- import { readFile as readFile10, stat as stat2 } from "fs/promises";
1599
- import { join as join13, relative as relative6 } from "path";
1670
+ import { readFile as readFile10, stat } from "fs/promises";
1671
+ import { join as join13 } from "path";
1600
1672
  var COL_CHANGE = 32;
1601
1673
  var COL_KIND = 10;
1602
1674
  var COL_AGE = 7;
1603
1675
  var COL_PROGRESS = 10;
1604
1676
  async function showStatus(options = {}, runOptions = {}) {
1605
- const focusedSet = /* @__PURE__ */ new Set();
1606
1677
  const runtime = [];
1607
1678
  const reportRuntime = (diagnostic) => recordRuntimeDiagnostic(runtime, diagnostic, Boolean(runOptions.verbose) && !runOptions.json);
1608
- if (existsSync13(FOCUS_DIR)) {
1609
- const entries = await walkFiles(FOCUS_DIR, { onError: reportRuntime });
1610
- for (const entryPath of entries)
1611
- focusedSet.add(normalizeLogicalPath(relative6(FOCUS_DIR, entryPath)));
1612
- }
1679
+ const focusedSet = await getFocusedChangeNames({ onError: reportRuntime });
1613
1680
  const changeFiles = existsSync13(CHANGES_DIR) ? await walkMarkdownFiles(CHANGES_DIR, { onError: reportRuntime }) : [];
1614
1681
  const changeMap = {};
1615
1682
  for (const fp of changeFiles)
@@ -1655,7 +1722,7 @@ async function showStatus(options = {}, runOptions = {}) {
1655
1722
  });
1656
1723
  }
1657
1724
  try {
1658
- const s = await stat2(fp);
1725
+ const s = await stat(fp);
1659
1726
  ageDays = Math.floor((Date.now() - s.mtime.getTime()) / (1e3 * 60 * 60 * 24));
1660
1727
  } catch (error) {
1661
1728
  reportRuntime({
@@ -1816,9 +1883,11 @@ function printArchiveTrend(trend) {
1816
1883
  import { existsSync as existsSync14 } from "fs";
1817
1884
  import { mkdir as mkdir8, readFile as readFile11, writeFile as writeFile9 } from "fs/promises";
1818
1885
  import { join as join14 } from "path";
1886
+ var SKILL_REFRESH_HINT = " Note: if you use the published RSP skill, refresh it too:\n npx skills add oevery/rsp\n";
1819
1887
  async function updateProject() {
1820
1888
  if (!existsSync14(RSP_DIR)) {
1821
- console.log(` ${pc.red("Error:")} RSP is not initialized. Run: rsp init`);
1889
+ console.error(` ${pc.red("Error:")} RSP is not initialized in this project`);
1890
+ console.error(` ${pc.dim("Run: rsp init")}`);
1822
1891
  process.exit(1);
1823
1892
  }
1824
1893
  return withRspLock("update", async () => {
@@ -1845,12 +1914,15 @@ async function updateProject() {
1845
1914
  }
1846
1915
  await buildSpecsIndex({ acquireLock: false });
1847
1916
  await buildArchiveIndex({ acquireLock: false });
1848
- if (!updated)
1917
+ if (!updated) {
1849
1918
  console.log(` ${pc.dim("Already up to date.")}
1850
1919
  `);
1851
- else
1920
+ console.log(SKILL_REFRESH_HINT);
1921
+ } else {
1852
1922
  console.log(` ${pc.green("Update complete.")}
1853
1923
  `);
1924
+ console.log(SKILL_REFRESH_HINT);
1925
+ }
1854
1926
  });
1855
1927
  }
1856
1928
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oevery/rsp",
3
3
  "type": "module",
4
- "version": "2.0.0",
4
+ "version": "2.0.3",
5
5
  "description": "RSP (Rules, Specs, Plans) workflow for lightweight AI-assisted change management",
6
6
  "author": "oevery",
7
7
  "license": "MIT",
@@ -7,6 +7,12 @@ description: Core RSP rules for Rules, Specs, and Plans driven development.
7
7
 
8
8
  This file is the canonical RSP rules source.
9
9
 
10
+ ## Scope
11
+
12
+ - Paths in this file are relative to the project root unless stated otherwise.
13
+ - These rules are tool-agnostic and apply even when the agent does not support skills.
14
+ - If the agent supports Agent Skills, load the `rsp` skill for initialization, audit or repair, and durable-decision tasks.
15
+
10
16
  ## Read order
11
17
 
12
18
  1. Read `AGENTS.md`.
@@ -15,6 +21,7 @@ This file is the canonical RSP rules source.
15
21
  4. If `focus.d/` is empty, ask the user what to work on or suggest `npx -y @oevery/rsp create <name>`.
16
22
  5. Read each `changes/<name>.md` file marked in `focus.d/`.
17
23
  6. Read `specs/design.md` and `specs/INDEX.md`.
24
+ `specs/INDEX.md` lists only additional spec files beyond `specs/design.md`.
18
25
  7. Read only the relevant additional `rules/` and `specs/` files.
19
26
 
20
27
  ## Core rules
@@ -1,6 +1,18 @@
1
1
  ---
2
2
  name: rsp
3
- description: Use this skill when adopting, operating, auditing, or repairing an RSP project and its .rsp structure.
3
+ description: Use this skill when initializing RSP in a repository, operating an existing .rsp project, auditing or repairing .rsp state, or deciding whether a change needs durable updates before archive.
4
+ compatibility:
5
+ agents:
6
+ - any agent that supports the Agent Skills format
7
+ requirements:
8
+ - Node.js 18+
9
+ - local filesystem read/write access
10
+ - shell access for `rsp` or `npx -y @oevery/rsp`
11
+ optional_requirements:
12
+ - network access for first-run `npx` installation or skill refresh
13
+ metadata:
14
+ author: oevery
15
+ version: 2.0.3
4
16
  ---
5
17
 
6
18
  # RSP Skill
@@ -11,6 +23,19 @@ This skill operationalizes the rules in `.rsp/rules/rsp-rules.md`. Always load a
11
23
 
12
24
  Prefer exact file paths, exact commands, and exact durable facts over vague summaries.
13
25
 
26
+ ## When to use
27
+
28
+ - Use this skill when a repository already contains `.rsp/` and the task is to operate within that workflow.
29
+ - Use this skill when adopting RSP in a repository that does not yet have `.rsp/`.
30
+ - Use this skill when the task is to audit or repair `.rsp/`, `AGENTS.md`, generated indices, or focus markers.
31
+ - Use this skill when deciding whether a completed change needs durable updates before archive.
32
+
33
+ ## When not to use
34
+
35
+ - Do not load this skill for general coding tasks unrelated to `.rsp/`.
36
+ - Do not use this skill as a substitute for reading `.rsp/rules/rsp-rules.md` during a focused RSP task.
37
+ - Do not use this skill when the repository does not use RSP and the user did not ask to adopt it.
38
+
14
39
  ## Workflow
15
40
 
16
41
  ### Adopt or initialize
@@ -40,9 +65,23 @@ Prefer exact file paths, exact commands, and exact durable facts over vague summ
40
65
  2. Check that `AGENTS.md` contains the managed RSP block.
41
66
  3. Check that `specs/design.md` exists.
42
67
  4. Check that `specs/INDEX.md` and `archives/INDEX.md` are still generated files.
68
+ `specs/INDEX.md` should list only additional spec files beyond `specs/design.md`.
43
69
  5. Check that `focus.d/` markers and `changes/` files are in sync.
44
70
  6. If generated indices or the managed AGENTS block drift, run `npx -y @oevery/rsp update`.
45
71
 
72
+ ## Expected outputs
73
+
74
+ - exact file paths to read or update
75
+ - exact RSP commands to run
76
+ - a single durable-decision result in the required template when evaluating archive readiness
77
+
78
+ ## Trigger examples
79
+
80
+ - "Set up RSP in this repository."
81
+ - "Repair the broken .rsp state in this project."
82
+ - "Check whether this change needs spec or rule writeback before archive."
83
+ - "Audit the RSP setup and tell me what is missing."
84
+
46
85
  ## Durable decision
47
86
 
48
87
  Before `npx -y @oevery/rsp archive <name>`: