@ericrisco/rsc 2.0.18 → 2.0.19

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
@@ -276,7 +276,7 @@ rsc consult "I want to launch a SaaS" # recommend only, no install
276
276
  rsc registry refresh # write .rsc/skill-registry.{json,md}
277
277
  rsc list # installed skills, agents and commands
278
278
  rsc capabilities # installed/available surfaces + memory mode
279
- rsc doctor # health, missing backing, hooks and local memory
279
+ rsc doctor # health, missing backing, hooks and local memory; exits 1 when unhealthy
280
280
  rsc memory status # full / assisted / unsupported / degraded
281
281
  rsc memory save --session handoff # force a deterministic local checkpoint
282
282
  rsc memory resume # print this branch/worktree continuation
package/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.18",
2
+ "version": "2.0.19",
3
3
  "counts": {
4
4
  "skills": 273,
5
5
  "agents": 33,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ericrisco/rsc",
3
- "version": "2.0.18",
3
+ "version": "2.0.19",
4
4
  "description": "A guided harness builder that turns your goal into a minimal, verified AI-agent setup using strict best practices.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -101,6 +101,10 @@
101
101
  {
102
102
  "fixedIn": "2.0.18",
103
103
  "symptom": "Onboarding silently replaced a skill you wrote yourself that had the same name as one of rsc's (review, plan, debug…)"
104
+ },
105
+ {
106
+ "fixedIn": "2.0.19",
107
+ "symptom": "rsc doctor reported missing pieces or an unwired hook but still exited with 0, so a CI or an editor extension could not tell"
104
108
  }
105
109
  ]
106
110
  }
package/scripts/doctor.js CHANGED
@@ -201,7 +201,7 @@ export function doctor({ target, home, cwd }) {
201
201
  const missingAgents = (state.agents || []).filter((id) => {
202
202
  const path = agentPath(target, root, id);
203
203
  return path && !existsSync(path);
204
- }).map((id) => ({ id, action: 'Run `npx @ericrisco/rsc sync` to restore this managed agent.' }));
204
+ }).map((id) => ({ id, path: agentPath(target, root, id), action: 'Run `npx @ericrisco/rsc sync` to restore this managed agent.' }));
205
205
  const report = {
206
206
  target,
207
207
  installed: Object.keys(state.skills),
@@ -251,9 +251,12 @@ export function doctor({ target, home, cwd }) {
251
251
  commandOrphans,
252
252
  commandCollisions: state.commandCollisions || [],
253
253
  };
254
+ // #277 — the three "missing" lists share one shape, { id, path, action }, so whoever builds on top
255
+ // of doctor reads them the same way; and `healthy` is what the exit code says.
254
256
  for (const [id, e] of Object.entries(state.skills)) {
255
- for (const f of e.files) if (!existsSync(f)) report.missing.push(`${id}:${f}`);
257
+ for (const f of e.files) if (!existsSync(f)) report.missing.push({ id, path: f, action: 'Run `npx @ericrisco/rsc sync` to restore this managed skill.' });
256
258
  }
259
+ report.healthy = report.hookWired && !report.missing.length && !missingAgents.length && !missingCommands.length;
257
260
  return report;
258
261
  }
259
262
 
package/scripts/rsc.js CHANGED
@@ -758,6 +758,8 @@ async function main() {
758
758
  }
759
759
  case 'doctor': {
760
760
  const report = doctor({ target });
761
+ // #277 — an automation on top of rsc reads the exit code, not the prose.
762
+ if (!report.healthy) process.exitCode = 1;
761
763
  if (argv.includes('--json')) return void say(JSON.stringify(report, null, 2));
762
764
  printContextBudget(report.contextBudget);
763
765
  return void say(JSON.stringify({ ...report, contextBudget: undefined }, null, 2));