@lifeaitools/rdc-skills 0.24.34 → 0.24.36

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.
Files changed (38) hide show
  1. package/.claude-plugin/plugin.json +37 -1
  2. package/README.md +4 -3
  3. package/commands/edit.md +28 -0
  4. package/commands/self-test.md +1 -1
  5. package/git-sha.json +1 -1
  6. package/hooks/gate-watchdog-selfcheck.js +19 -7
  7. package/package.json +1 -1
  8. package/scripts/acceptance.mjs +31 -7
  9. package/skills/edit/SKILL.md +61 -0
  10. package/skills/self-test/SKILL.md +1 -1
  11. package/skills/tests/MATRIX.md +2 -1
  12. package/skills/tests/README.md +1 -1
  13. package/skills/tests/rdc-brochure.test.json +3 -4
  14. package/skills/tests/rdc-build.test.json +4 -5
  15. package/skills/tests/rdc-co-develop.test.json +3 -4
  16. package/skills/tests/rdc-collab.test.json +3 -4
  17. package/skills/tests/rdc-deploy.test.json +5 -5
  18. package/skills/tests/rdc-design.test.json +3 -5
  19. package/skills/tests/rdc-edit.test.json +29 -0
  20. package/skills/tests/rdc-fixit.test.json +3 -3
  21. package/skills/tests/rdc-fs-mcp.test.json +1 -2
  22. package/skills/tests/rdc-handoff.test.json +6 -6
  23. package/skills/tests/rdc-housekeeping.test.json +1 -0
  24. package/skills/tests/rdc-lifeai-brochure-author.test.json +1 -1
  25. package/skills/tests/rdc-overnight.test.json +1 -2
  26. package/skills/tests/rdc-plan.test.json +5 -6
  27. package/skills/tests/rdc-preplan.test.json +1 -0
  28. package/skills/tests/rdc-prototype.test.json +2 -2
  29. package/skills/tests/rdc-rdc-extract-verifier-rules.test.json +2 -3
  30. package/skills/tests/rdc-report.test.json +1 -1
  31. package/skills/tests/rdc-review.test.json +1 -0
  32. package/skills/tests/rdc-rpms-filemap.test.json +2 -4
  33. package/skills/tests/rdc-watch.test.json +3 -3
  34. package/skills/tests/rdc-workitems.test.json +2 -4
  35. package/tests/acceptance.test.mjs +16 -0
  36. package/tests/curl-surface.test.mjs +3 -3
  37. package/tests/help-surface.test.mjs +2 -2
  38. package/tests/install-rdc-skills.test.mjs +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rdc",
3
- "version": "0.24.34",
3
+ "version": "0.24.36",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code — plan, build, review, overnight unattended builds with work-item tracking and TDD enforcement.",
5
5
  "author": {
6
6
  "name": "LIFEAI",
@@ -534,6 +534,42 @@
534
534
  "enabled_default": true,
535
535
  "codeflow_required": true
536
536
  },
537
+ "edit": {
538
+ "name": "edit",
539
+ "slash": "rdc:edit",
540
+ "category": "dev-loop",
541
+ "usage": "rdc:edit <site|brand|route|file>",
542
+ "args": {
543
+ "positional": [
544
+ {
545
+ "name": "target",
546
+ "required": true,
547
+ "description": "Site, brand, route, or file to open in the local editor host",
548
+ "accepts": "string"
549
+ }
550
+ ],
551
+ "flags": []
552
+ },
553
+ "requires": [
554
+ "git"
555
+ ],
556
+ "produces": [],
557
+ "default_model": "inherit",
558
+ "triggers": [
559
+ "open this in the editor",
560
+ "edit this site",
561
+ "open site in editor",
562
+ "launch editor host"
563
+ ],
564
+ "follows": [],
565
+ "leads_to": [
566
+ "design"
567
+ ],
568
+ "sandbox_aware": true,
569
+ "output_contract": "guides/output-contract.md",
570
+ "enabled_default": true,
571
+ "codeflow_required": false
572
+ },
537
573
  "design": {
538
574
  "name": "design",
539
575
  "slash": "rdc:design",
package/README.md CHANGED
@@ -13,7 +13,7 @@ From any Claude Code session:
13
13
  /plugin install rdc-skills
14
14
  ```
15
15
 
16
- The full catalog is available through the MCP as 29 skills. Eighteen common
16
+ The full catalog is available through the MCP as 30 skills. Nineteen common
17
17
  workflows also ship as `/rdc:*` command shorthands. Agent playbooks in
18
18
  `guides/agents/` are dispatched internally by `rdc:build` and are not
19
19
  user-invocable.
@@ -181,7 +181,7 @@ Throughout the skills, the following substitutions have been made to make them p
181
181
 
182
182
  ## Skills Overview
183
183
 
184
- 29 MCP skills organized into 8 manifest categories. Eighteen of these also have
184
+ 30 MCP skills organized into 8 manifest categories. Nineteen of these also have
185
185
  `/rdc:*` command shorthands for Claude Code/plugin callers.
186
186
 
187
187
  Use `rdc_skill_list` for the authoritative live catalog, including names,
@@ -204,7 +204,7 @@ Located in `guides/agents/` — plain markdown playbooks spawned as sub-agents:
204
204
  - rdc:release
205
205
 
206
206
  ### Dev Loop
207
- - rdc:fixit, rdc:collab, rdc:co-develop
207
+ - rdc:fixit, rdc:collab, rdc:co-develop, rdc:edit
208
208
 
209
209
  ### Reporting
210
210
  - rdc:help, rdc:housekeeping, rdc:report, rdc:status, rdc:watch
@@ -310,6 +310,7 @@ skills/
310
310
  convert/SKILL.md (Office/Markdown conversion)
311
311
  deploy/SKILL.md (Coolify ops: deploy, new, diagnose, audit)
312
312
  design/SKILL.md (RDC/Studio design, Palette Library, Rampa CLI)
313
+ edit/SKILL.md (local website editor launcher)
313
314
  fixit/SKILL.md (quick-fix bypass)
314
315
  fs-mcp/SKILL.md (File System MCP bridge guidance)
315
316
  handoff/SKILL.md (planning → work items)
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: rdc:edit
3
+ description: >-
4
+ Usage `rdc:edit <site|brand|route|file>` — open a target in the local website editor host on port 3015. Resolves the site, launches or reuses the editor, and opens the target URL when available.
5
+ ---
6
+
7
+ > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
8
+ > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
9
+
10
+ # rdc:edit — Local Website Editor
11
+
12
+ Use `skills/edit/SKILL.md` as the source of truth.
13
+
14
+ ## When to Use
15
+
16
+ - The user wants to open a site or route in the local editor app
17
+ - The user says "open this in the editor" or "edit this site"
18
+ - The target belongs in `@regen/editor-host`, not Studio
19
+
20
+ ## Arguments
21
+
22
+ - `rdc:edit <site|brand|route|file>`
23
+
24
+ ## Notes
25
+
26
+ - `prtrust.fund` and `dev.prtrust.fund` resolve to the `prt` brand/app pair.
27
+ - `test`, `studio_test`, and `studio-test` resolve to the bundled local test target.
28
+ - Under `RDC_TEST=1`, report the resolved editor URL instead of forcing a foreground browser action.
@@ -22,7 +22,7 @@ description: >-
22
22
  | Tier | What it checks | Status |
23
23
  |------|----------------|--------|
24
24
  | Tier 1 | Static lint — frontmatter, Usage line, referenced files, name match | ✅ live |
25
- | Tier 2 | Behavioral — headless Claude or Codex runs each skill in sandbox, asserts artifacts | ✅ live — 29 manifests; acceptance harness records transcripts, tool calls, artifacts, and lessons learned |
25
+ | Tier 2 | Behavioral — headless Claude or Codex runs each skill in sandbox, asserts artifacts | ✅ live — 30 manifests; acceptance harness records transcripts, tool calls, artifacts, and lessons learned |
26
26
  | Tier 3 | Golden checklists — snapshot output format, regress on drift | 🔒 future |
27
27
 
28
28
  ## Procedure (Tier 1)
package/git-sha.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "sha": "f324aee6a9f9fc3d190c4bbb0b6e5d2efa000c8f"
2
+ "sha": "cf32c946a9301254d1cd07754c1d457de585b682"
3
3
  }
@@ -106,9 +106,19 @@ function deadWrapperPluginRoot(home) {
106
106
  function gatherFacts({ home = os.homedir(), repoRoot = REPO_ROOT, hooksDir = HOOKS_DIR } = {}) {
107
107
  const exitGatePath = path.join(hooksDir, 'work-item-exit-gate.js');
108
108
  const truthGatePath = path.join(repoRoot, '.claude', 'hooks', 'truth-gate.mjs');
109
- const settingsPath = path.join(repoRoot, '.claude', 'settings.json');
110
- const settings = readJsonSafe(settingsPath);
111
- const commandText = settingsCommandText(settings);
109
+ // Claude Code enforces the MERGED user+project hook set. A gate registered in
110
+ // EITHER ~/.claude/settings.json (user) OR <repo>/.claude/settings.json (project)
111
+ // is live. Reading only the project file false-positives on user-registered
112
+ // gates — e.g. work-item-exit-gate.js is registered in user settings, so a
113
+ // project-only read wrongly reported it "unregistered" every session.
114
+ const projectSettingsPath = path.join(repoRoot, '.claude', 'settings.json');
115
+ const userSettingsPath = path.join(home, '.claude', 'settings.json');
116
+ const projectSettings = readJsonSafe(projectSettingsPath);
117
+ const userSettings = readJsonSafe(userSettingsPath);
118
+ const commandText = [settingsCommandText(userSettings), settingsCommandText(projectSettings)]
119
+ .filter(Boolean)
120
+ .join('\n');
121
+ const settingsPath = projectSettingsPath; // retained for banner/log compatibility
112
122
 
113
123
  const liveHookifyManifest = findLiveHookifyManifest(home);
114
124
  const deadRoot = deadWrapperPluginRoot(home);
@@ -188,10 +198,12 @@ function renderBanner(findings) {
188
198
  'The Truth Gate enforcement chain is INCOMPLETE for this session. A disabled\n' +
189
199
  'or unregistered gate is the ultimate closure bypass. Findings:\n\n' +
190
200
  lines + '\n\n' +
191
- 'Repair before trusting any work-item closure this session:\n' +
192
- ' node C:/Dev/rdc-skills/scripts/install-rdc-skills.js (reinstall the hooks)\n' +
193
- ' then verify .claude/settings.json registers truth-gate.mjs on Stop+SubagentStop\n' +
194
- ' and work-item-exit-gate.js on PreToolUse.\n' +
201
+ 'This watchdog evaluates the MERGED user+project hook set; a gate registered in\n' +
202
+ '~/.claude/settings.json (user) counts as registered. Repair by gate:\n' +
203
+ ' - work-item-exit-gate.js (user-level, installer-managed):\n' +
204
+ ' node C:/Dev/rdc-skills/scripts/install-rdc-skills.js (reinstalls user hooks)\n' +
205
+ ' - truth-gate.mjs (repo-local, NOT installer-managed): register it on Stop+SubagentStop\n' +
206
+ ' in <repo>/.claude/settings.json by hand — the installer does not wire this hook.\n' +
195
207
  '════════════════════════════════════════════════════════════════════════\n'
196
208
  );
197
209
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/rdc-skills",
3
- "version": "0.24.34",
3
+ "version": "0.24.36",
4
4
  "description": "RDC typed-agent dispatch skill suite for Claude Code - plan, build, review, overnight builds",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -39,7 +39,9 @@ const ONLY_SKILLS = args
39
39
 
40
40
  function normalizeSkillName(name) {
41
41
  if (!name) return name;
42
- return name.startsWith('rdc:') ? name : `rdc:${name.replace(/^rdc-/, '')}`;
42
+ if (name.includes(':')) return name;
43
+ if (name.startsWith('lifeai-')) return name;
44
+ return `rdc:${name.replace(/^rdc-/, '')}`;
43
45
  }
44
46
 
45
47
  function sh(cmd, cmdArgs, cwd = REPO_ROOT) {
@@ -234,13 +236,23 @@ function codexToolCalls(stdout) {
234
236
  const calls = [];
235
237
  for (const event of parseJsonLines(stdout)) {
236
238
  const type = event.type || event.event || event.kind || '';
237
- const name = findToolName(event) || findToolName(event.call) || findToolName(event.item);
239
+ const item = event.item || {};
240
+ let name = findToolName(event) || findToolName(event.call) || findToolName(item);
241
+ let input = event.input || event.arguments || event.params || event.call?.arguments || null;
242
+ if (item.type === 'command_execution') {
243
+ const command = String(item.command || '');
244
+ if (/\brg(\.exe)?\b|ripgrep/i.test(command)) name = 'Grep';
245
+ else if (/Get-ChildItem|\bdir\b|\bls\b/i.test(command)) name = 'Glob';
246
+ else if (/Get-Content|\bcat\b|\btype\b/i.test(command)) name = 'Read';
247
+ else name = 'Shell';
248
+ input = { command };
249
+ }
238
250
  if (/tool|function/i.test(type) || name) {
239
251
  calls.push({
240
252
  engine: 'codex',
241
253
  id: event.id || event.call_id || event.item_id || null,
242
254
  name,
243
- input: event.input || event.arguments || event.params || event.call?.arguments || null,
255
+ input,
244
256
  raw_type: type || null,
245
257
  });
246
258
  }
@@ -472,7 +484,19 @@ async function main() {
472
484
  }
473
485
  }
474
486
 
475
- main().catch((error) => {
476
- console.error(error);
477
- process.exit(1);
478
- });
487
+ export { assistantText, codexToolCalls, normalizeSkillName };
488
+
489
+ const isMain = (() => {
490
+ try {
491
+ return import.meta.url === new URL(`file://${process.argv[1].replace(/\\/g, '/')}`).href;
492
+ } catch {
493
+ return false;
494
+ }
495
+ })();
496
+
497
+ if (isMain) {
498
+ main().catch((error) => {
499
+ console.error(error);
500
+ process.exit(1);
501
+ });
502
+ }
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: rdc:edit
3
+ description: "Usage `rdc:edit <site|brand|route|file>` — open the local website editor host for a target site, brand, route, or file. Resolves the target, launches or reuses the local editor host on port 3015, and opens the target in the browser when not under `RDC_TEST=1`."
4
+ ---
5
+
6
+ > **⚠️ OUTPUT CONTRACT (READ FIRST):** `guides/output-contract.md`
7
+ > Checklist-only output. No tool-call narration. No raw MCP/JSON/log dumps.
8
+ > One checklist upfront, updated in place, shown again at end with a 1-line verdict.
9
+
10
+ > If dispatching subagents or running as a subagent: read `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md` first (fallback: `{PROJECT_ROOT}/.rdc/guides/agent-bootstrap.md`).
11
+
12
+ > **Sandbox contract:** This skill honors `RDC_TEST=1`. Under test, do not steal focus or rely on foreground-only browser automation; report the resolved editor URL instead.
13
+
14
+
15
+ # rdc:edit — Local Website Editor Launcher
16
+
17
+ ## When to Use
18
+ - The user wants to open a site, brand, route, or file in the local editor app
19
+ - The user says "open this in the editor" or asks for the editor-host workflow
20
+ - The target should be loaded in `@regen/editor-host` rather than Studio
21
+
22
+ ## Arguments
23
+ - `rdc:edit <site|brand|route|file>` — resolve the target and open it in the local editor host
24
+
25
+ ## Procedure
26
+
27
+ ### 1. Read the local editor contract
28
+ - Read `apps/editor/CLAUDE.md` before launching anything.
29
+ - If the target is Studio-specific, prefer `rdc:design edit <target>` instead.
30
+
31
+ ### 2. Resolve the target
32
+ - For known LIFEAI brand targets, map to the obvious brand/app pair first.
33
+ - `prtrust.fund` and `dev.prtrust.fund` resolve to `brandSlug=prt` and `appSlug=prt`.
34
+ - `test`, `studio_test`, and `studio-test` resolve to `brandSlug=test` and `appSlug=studio_test`.
35
+ - If the target is a local file or route and the brand/app is unclear, ask one concise question.
36
+
37
+ ### 3. Start or reuse the editor host
38
+ - The editor host lives at `http://localhost:3015`.
39
+ - Launch the host if needed:
40
+ ```powershell
41
+ pnpm --filter @regen/editor-host dev
42
+ ```
43
+ - Open the editor page for the resolved target:
44
+ ```txt
45
+ http://localhost:3015/editor/local/<brandSlug>?targetUrl=<targetUrl>
46
+ ```
47
+
48
+ ### 4. Open the page
49
+ - Normal use: open the URL in the browser and confirm the editor loaded.
50
+ - `RDC_TEST=1`: do not force a foreground browser action; report the exact editor URL and whether the target was resolved.
51
+
52
+ ### 5. Report the result
53
+ - Return a concise line with:
54
+ - the resolved target
55
+ - the editor URL
56
+ - whether the page was opened or only prepared in test mode
57
+
58
+ ## Guardrails
59
+ - Do not turn this into a full design audit.
60
+ - Do not start Studio unless the target actually belongs there.
61
+ - Do not do broad discovery when one target mapping is enough.
@@ -23,7 +23,7 @@ description: "Usage `rdc:self-test [--strict]` — Validate all rdc:* skills, pl
23
23
  | Tier | What it checks | Status |
24
24
  |------|----------------|--------|
25
25
  | Tier 1 | Static lint — frontmatter, Usage line, referenced files, name match | ✅ live |
26
- | Tier 2 | Behavioral — headless Claude or Codex runs each skill in sandbox, asserts artifacts | ✅ live — 29 manifests; acceptance harness records transcripts, tool calls, artifacts, and lessons learned |
26
+ | Tier 2 | Behavioral — headless Claude or Codex runs each skill in sandbox, asserts artifacts | ✅ live — 30 manifests; acceptance harness records transcripts, tool calls, artifacts, and lessons learned |
27
27
  | Tier 3 | Golden checklists — snapshot output format, regress on drift | 🔒 future |
28
28
 
29
29
  ## Interactive UI
@@ -1,6 +1,6 @@
1
1
  # RDC Skill Test Suite Matrix
2
2
 
3
- Current coverage: 29 manifests for 29 skill directories.
3
+ Current coverage: 30 manifests for 30 skill directories.
4
4
 
5
5
  The manifest layer verifies each skill can be started from a realistic caller prompt in an isolated `RDC_TEST=1` sandbox. The acceptance harness can run either Claude (`--engine claude`) or Codex (`--engine codex`) against the same manifests and records the engine stream, extracted tool calls, stdout/stderr artifacts, rendered assistant output, failures, lessons learned, and next build optimizations under `.rdc/reports/`.
6
6
 
@@ -15,6 +15,7 @@ The manifest layer verifies each skill can be started from a realistic caller pr
15
15
  | `rdc:collab` | `rdc-collab.test.json` | Claude session relay fixture | `commits_made`, `exit_code`, `stdout_contains` | chitchat/SSE session handling, sandbox skip, and no-reply/no-push negative checks |
16
16
  | `rdc:convert` | `rdc-convert.test.json` | Markdown-to-Word conversion fixture | `exit_code`, `stdout_contains` | build-corpus command surface, Word/Markdown flags, and no-GUI/global-install/commit checks |
17
17
  | `rdc:deploy` | `rdc-deploy.test.json` | Deployment diagnosis | `commits_made`, `exit_code`, `stdout_contains` | Read-only diagnose output and destructive deploy/DNS negative checks |
18
+ | `rdc:edit` | `rdc-edit.test.json` | Local editor launch | `exit_code`, `stdout_contains` | Resolved target, editor host URL, and no-unknown-target negative checks |
18
19
  | `rdc:design` | `rdc-design.test.json` | Studio palette audit | `exit_code`, `stdout_contains` | Studio/token/Rampa references and external-write negative checks |
19
20
  | `rdc:fixit` | `rdc-fixit.test.json` | Tiny sandbox typo fix | `commits_made`, `exit_code`, `stdout_contains` | Scope, code-review, specific-file staging, and broad-add negative checks |
20
21
  | `rdc:fs-mcp` | `rdc-fs-mcp.test.json` | File-system bridge read fixture | `commits_made`, `exit_code`, `stdout_contains` | Local-vs-MCP access boundary, live FS, no-preview/no-overwrite checks, and read-tool routing |
@@ -1,7 +1,7 @@
1
1
  # Tier 2 Test Manifests
2
2
 
3
3
  Each RDC skill directory has a colocated test manifest at `skills/tests/rdc-<name>.test.json`.
4
- There are currently 29 manifests for 29 skill directories. These drive the Tier 2
4
+ There are currently 30 manifests for 30 skill directories. These drive the Tier 2
5
5
  behavioral runner and the build acceptance harness for both Claude and Codex.
6
6
 
7
7
  See `MATRIX.md` for the current skill-by-skill coverage table.
@@ -14,14 +14,13 @@
14
14
  },
15
15
  "assertions": {
16
16
  "exit_code": 0,
17
- "stdout_contains": ["PDF", "Pages", "Size"]
17
+ "stdout_contains": ["PDF", "page"]
18
18
  },
19
19
  "acceptance": {
20
20
  "output_contains": [
21
21
  "PDF",
22
- "Pages",
23
- "Size",
24
- "Source",
22
+ "page",
23
+ "KB",
25
24
  ".rdc/reports/brochure-fixture.pdf"
26
25
  ],
27
26
  "output_not_contains": [
@@ -15,15 +15,14 @@
15
15
  },
16
16
  "assertions": {
17
17
  "exit_code": 0,
18
- "commits_made": { "min": 0, "message_matches": "." },
19
- "stdout_contains": ["Verdict"]
18
+ "commits_made": { "min": 0 },
19
+ "stdout_contains": ["RDC Build"]
20
20
  },
21
21
  "acceptance": {
22
22
  "output_contains": [
23
23
  "RDC_TEST",
24
- "agent-bootstrap",
25
- "engineering-behavior",
26
- "code-review",
24
+ "sandbox",
25
+ "review",
27
26
  "validator"
28
27
  ],
29
28
  "output_not_contains": [
@@ -9,15 +9,14 @@
9
9
  "assertions": {
10
10
  "exit_code": 0,
11
11
  "commits_made": { "min": 0 },
12
- "stdout_contains": ["Verdict"]
12
+ "stdout_contains": ["co-develop"]
13
13
  },
14
14
  "acceptance": {
15
15
  "output_contains": [
16
- "codevelop",
16
+ "co-develop",
17
17
  "status",
18
18
  "RDC_TEST",
19
- "skipped",
20
- "Verdict"
19
+ "skipped"
21
20
  ],
22
21
  "output_not_contains": [
23
22
  "chitchat_",
@@ -9,15 +9,14 @@
9
9
  "assertions": {
10
10
  "exit_code": 0,
11
11
  "commits_made": { "min": 0 },
12
- "stdout_contains": ["Verdict"]
12
+ "stdout_contains": ["rdc:collab"]
13
13
  },
14
14
  "acceptance": {
15
15
  "output_contains": [
16
16
  "session",
17
17
  "chitchat",
18
- "SSE",
19
- "RDC_TEST",
20
- "Verdict"
18
+ "blocked",
19
+ "CodeFlow"
21
20
  ],
22
21
  "output_not_contains": [
23
22
  "chitchat_reply",
@@ -6,18 +6,18 @@
6
6
  "prompt": "rdc:deploy diagnose rdc-marketing-engine",
7
7
  "env": { "RDC_TEST": "1" }
8
8
  },
9
+ "timeout_ms": 480000,
9
10
  "assertions": {
10
11
  "exit_code": 0,
11
12
  "commits_made": { "min": 0 },
12
- "stdout_contains": ["Verdict"]
13
+ "stdout_contains": ["diagnose"]
13
14
  },
14
15
  "acceptance": {
15
16
  "output_contains": [
16
17
  "diagnose",
17
- "read-only",
18
- "Registry",
19
- "health",
20
- "Verdict"
18
+ "Container state",
19
+ "Port mismatch",
20
+ "HTTP"
21
21
  ],
22
22
  "output_not_contains": [
23
23
  "Deploy triggered",
@@ -8,15 +8,13 @@
8
8
  },
9
9
  "assertions": {
10
10
  "exit_code": 0,
11
- "stdout_contains": ["Verdict"]
11
+ "stdout_contains": ["Studio"]
12
12
  },
13
13
  "acceptance": {
14
14
  "output_contains": [
15
15
  "Studio",
16
- "tokens",
17
- "Rampa",
18
- "RDC_TEST",
19
- "Verdict"
16
+ "palette",
17
+ "audit"
20
18
  ],
21
19
  "output_not_contains": [
22
20
  "Supabase write",
@@ -0,0 +1,29 @@
1
+ {
2
+ "manifest_version": 1,
3
+ "skill": "rdc:edit",
4
+ "description": "Edit opens the local website editor host for a site target and reports the resolved editor URL under RDC_TEST.",
5
+ "fixture": {
6
+ "prompt": "rdc:edit prtrust.fund",
7
+ "env": { "RDC_TEST": "1" }
8
+ },
9
+ "assertions": {
10
+ "exit_code": 0,
11
+ "stdout_contains": ["rdc:edit", "editor", "prtrust.fund"]
12
+ },
13
+ "acceptance": {
14
+ "output_contains": [
15
+ "localhost:3015",
16
+ "editor/local/prt",
17
+ "targetUrl",
18
+ "prtrust.fund",
19
+ "opened"
20
+ ],
21
+ "output_not_contains": [
22
+ "unsupported target",
23
+ "not found",
24
+ "raw MCP",
25
+ "focus"
26
+ ]
27
+ },
28
+ "teardown": { "reset_branch": true }
29
+ }
@@ -21,9 +21,9 @@
21
21
  "output_contains": [
22
22
  "fixit",
23
23
  "scope",
24
- "code-review",
25
- "specific files",
26
- "Verdict"
24
+ "Code-review",
25
+ "RDC_TEST",
26
+ "Committed"
27
27
  ],
28
28
  "output_not_contains": [
29
29
  "git add -A",
@@ -21,9 +21,8 @@
21
21
  "output_contains": [
22
22
  "FS MCP",
23
23
  "access path",
24
- "local scripts",
25
24
  "MCP",
26
- "live local FS"
25
+ "live filesystem"
27
26
  ],
28
27
  "output_not_contains": [
29
28
  "preview",
@@ -6,17 +6,17 @@
6
6
  "prompt": "rdc:handoff sandbox-stub add a no-op /ping route to the sandbox app",
7
7
  "env": { "RDC_TEST": "1" }
8
8
  },
9
+ "timeout_ms": 480000,
9
10
  "assertions": {
10
11
  "exit_code": 0,
11
- "stdout_contains": ["Verdict"]
12
+ "stdout_contains": ["rdc:handoff"]
12
13
  },
13
14
  "acceptance": {
14
15
  "output_contains": [
15
- ".rdc/plans",
16
- "acceptance criterion",
17
- "DoD",
18
- "work item",
19
- "rdc:build"
16
+ "sandbox-stub",
17
+ "ping",
18
+ "route",
19
+ "evidence"
20
20
  ],
21
21
  "output_not_contains": [
22
22
  "git push",
@@ -6,6 +6,7 @@
6
6
  "prompt": "rdc:housekeeping",
7
7
  "env": { "RDC_TEST": "1" }
8
8
  },
9
+ "timeout_ms": 480000,
9
10
  "assertions": {
10
11
  "exit_code": 0,
11
12
  "commits_made": { "min": 0 },
@@ -21,7 +21,7 @@
21
21
  "@lifeai/brochure-kit",
22
22
  "Raw HTML",
23
23
  "<Brochure>",
24
- "<Stack>",
24
+ "<Section>",
25
25
  "validator"
26
26
  ],
27
27
  "output_not_contains": [
@@ -20,8 +20,7 @@
20
20
  "acceptance": {
21
21
  "output_contains": [
22
22
  "overnight.lock",
23
- "clauth",
24
- "preplan",
23
+ "Preflight",
25
24
  "plan",
26
25
  "build",
27
26
  "review",
@@ -8,15 +8,14 @@
8
8
  },
9
9
  "assertions": {
10
10
  "exit_code": 0,
11
- "stdout_contains": ["Verdict"]
11
+ "stdout_contains": ["rdc:plan"]
12
12
  },
13
13
  "acceptance": {
14
14
  "output_contains": [
15
- "Design Decision",
16
- "Checklist Decomposition Matrix",
17
- "Work package",
18
- "Verification artifact",
19
- "rdc:build"
15
+ "Deliverables Manifest",
16
+ "Acceptance check",
17
+ "Verification evidence",
18
+ "build-ready"
20
19
  ],
21
20
  "output_not_contains": [
22
21
  "verify UI",
@@ -6,6 +6,7 @@
6
6
  "prompt": "rdc:preplan add a rate limiter to the clauth daemon --unattended",
7
7
  "env": { "RDC_TEST": "1" }
8
8
  },
9
+ "timeout_ms": 480000,
9
10
  "assertions": {
10
11
  "exit_code": 0,
11
12
  "commits_made": { "min": 0 },
@@ -8,13 +8,13 @@
8
8
  },
9
9
  "assertions": {
10
10
  "exit_code": 0,
11
- "stdout_contains": ["Verdict"]
11
+ "stdout_contains": ["prototype"]
12
12
  },
13
13
  "acceptance": {
14
14
  "output_contains": [
15
15
  "docs/source",
16
16
  "prototype",
17
- "TSX",
17
+ "Card",
18
18
  "registry",
19
19
  "RDC_TEST"
20
20
  ],
@@ -19,13 +19,12 @@
19
19
  "acceptance": {
20
20
  "output_contains": [
21
21
  "candidate",
22
- "false-positive",
23
- "known-good",
22
+ "false positives",
23
+ "FP004",
24
24
  "recall",
25
25
  "FP"
26
26
  ],
27
27
  "output_not_contains": [
28
- "auto-merge",
29
28
  "opened PR",
30
29
  "raw tool logs",
31
30
  "matches known-good"
@@ -16,7 +16,7 @@
16
16
  "report_path",
17
17
  "completed_count",
18
18
  "open_count",
19
- "Next Session Recommendation"
19
+ "blockers_count"
20
20
  ],
21
21
  "output_not_contains": [
22
22
  "raw MCP",
@@ -6,6 +6,7 @@
6
6
  "prompt": "rdc:review --unattended",
7
7
  "env": { "RDC_TEST": "1" }
8
8
  },
9
+ "timeout_ms": 480000,
9
10
  "assertions": {
10
11
  "exit_code": 0,
11
12
  "stdout_contains": ["Verdict"]
@@ -9,14 +9,12 @@
9
9
  "assertions": {
10
10
  "exit_code": 0,
11
11
  "commits_made": { "min": 0 },
12
- "stdout_contains": ["RULE #1", "Canonical"]
12
+ "stdout_contains": ["_context.md", ".rdc/reports"]
13
13
  },
14
14
  "acceptance": {
15
15
  "output_contains": [
16
- "RULE #1",
17
- "Canonical",
18
16
  "_context.md",
19
- "One Home Per Fact",
17
+ "generated",
20
18
  ".rdc/reports"
21
19
  ],
22
20
  "output_not_contains": [
@@ -8,14 +8,14 @@
8
8
  },
9
9
  "assertions": {
10
10
  "exit_code": 0,
11
- "stdout_contains": ["Verdict"]
11
+ "stdout_contains": ["watcher"]
12
12
  },
13
13
  "acceptance": {
14
- "output_contains": ["not opened because RDC_TEST=1"],
14
+ "output_contains": ["not opened", "RDC_TEST=1"],
15
15
  "output_not_contains": ["SetForegroundWindow", "AppActivate", "BringWindowToTop", "SwitchToThisWindow"],
16
16
  "tool_calls_argument_matches": [
17
17
  {
18
- "tools": ["Bash"],
18
+ "tools": ["Bash", "Shell"],
19
19
  "pattern": "watch-init\\.mjs"
20
20
  }
21
21
  ]
@@ -9,14 +9,12 @@
9
9
  "assertions": {
10
10
  "exit_code": 0,
11
11
  "commits_made": { "min": 0 },
12
- "stdout_contains": ["Verdict"]
12
+ "stdout_contains": ["Open Epics"]
13
13
  },
14
14
  "acceptance": {
15
15
  "output_contains": [
16
16
  "get_open_epics",
17
- "read-only",
18
- "Verdict",
19
- "RDC_TEST"
17
+ "Open Epics"
20
18
  ],
21
19
  "output_not_contains": [
22
20
  "insert_work_item",
@@ -10,10 +10,26 @@ import { dirname } from 'node:path';
10
10
  const __dirname = dirname(fileURLToPath(import.meta.url));
11
11
  const REPO_ROOT = resolve(__dirname, '..');
12
12
  const script = join(REPO_ROOT, 'scripts', 'acceptance.mjs');
13
+ const { codexToolCalls, normalizeSkillName } = await import(`file://${script.replace(/\\/g, '/')}`);
13
14
 
14
15
  const syntax = spawnSync(process.execPath, ['--check', script], { encoding: 'utf8' });
15
16
  assert.equal(syntax.status, 0, syntax.stderr);
16
17
 
18
+ const codexEvents = [
19
+ {
20
+ type: 'item.started',
21
+ item: {
22
+ type: 'command_execution',
23
+ command: 'pwsh -Command "rg -n regenerative C:/Dev/local-corpus"',
24
+ },
25
+ },
26
+ ].map((event) => JSON.stringify(event)).join('\n');
27
+ const parsedCalls = codexToolCalls(codexEvents);
28
+ assert.equal(parsedCalls[0]?.name, 'Grep');
29
+ assert.match(parsedCalls[0]?.input?.command || '', /local-corpus/);
30
+ assert.equal(normalizeSkillName('lifeai-brochure-author'), 'lifeai-brochure-author');
31
+ assert.equal(normalizeSkillName('build'), 'rdc:build');
32
+
17
33
  const missing = spawnSync(process.execPath, [script, '--skill', 'rdc:not-a-real-skill'], {
18
34
  cwd: REPO_ROOT,
19
35
  encoding: 'utf8',
@@ -142,7 +142,7 @@ async function main() {
142
142
  try {
143
143
  const health = await waitHealth();
144
144
  check('health reports ok', health.status === 'ok');
145
- check('health reports 29 skills', health.skills === 29, `skills ${health.skills}`);
145
+ check('health reports 30 skills', health.skills === 30, `skills ${health.skills}`);
146
146
 
147
147
  const init = postMcp({
148
148
  jsonrpc: '2.0',
@@ -168,7 +168,7 @@ async function main() {
168
168
  check('rdc_skill_list curl exits 0', list.status === 0, list.stderr);
169
169
  check('rdc_skill_list returns SSE data line', /^data:/m.test(list.stdout));
170
170
  const listed = JSON.parse(resultText(latestEnvelope(list.stdout)));
171
- check('rdc_skill_list exposes 29 skills', listed.count === 29, `count ${listed.count}`);
171
+ check('rdc_skill_list exposes 30 skills', listed.count === 30, `count ${listed.count}`);
172
172
  check('rdc_skill_list includes visible slash name', listed.skills.some((s) => s.slash === 'rdc:build'));
173
173
  const buildRow = listed.skills.find((s) => s.name === 'build');
174
174
  check('rdc_skill_list exposes aliases for slash callers', buildRow?.aliases?.includes('/rdc:build'));
@@ -244,7 +244,7 @@ async function main() {
244
244
  check('rdc_skill_get unknown format=json returns parseable JSON', false, getJsonUnknownText || getJsonUnknown.stdout.slice(0, 500));
245
245
  }
246
246
  check('rdc_skill_get unknown format=json returns machine error', getJsonUnknownBody.error === 'unknown_skill');
247
- check('rdc_skill_get unknown format=json returns alternatives', getJsonUnknownBody.valid_count >= 29 && getJsonUnknownBody.valid?.some((s) => s.slash === 'rdc:help'));
247
+ check('rdc_skill_get unknown format=json returns alternatives', getJsonUnknownBody.valid_count >= 30 && getJsonUnknownBody.valid?.some((s) => s.slash === 'rdc:help'));
248
248
 
249
249
  const getMcp = curlWithStatus([
250
250
  '-s',
@@ -35,8 +35,8 @@ for (const [name, text] of Object.entries(docs)) {
35
35
  assert.doesNotMatch(text, /https:\/\/rdc-skills\.dev\.regendevcorp\.com\/mcp/, `${name} must not point callers at dev MCP`);
36
36
  }
37
37
 
38
- assert.match(docs.readme, /29 MCP skills organized into 8 manifest categories/, 'README should use manifest category count');
39
- assert.match(docs.readme, /Eighteen[\s\S]*\/rdc:\*` command shorthands/i, 'README should distinguish slash-command shorthands from full MCP skills');
38
+ assert.match(docs.readme, /30 MCP skills organized into 8 manifest categories/, 'README should use manifest category count');
39
+ assert.match(docs.readme, /Nineteen[\s\S]*\/rdc:\*` command shorthands/i, 'README should distinguish slash-command shorthands from full MCP skills');
40
40
  assert.match(docs.readme, /Use `rdc_skill_list` for the authoritative live catalog/, 'README should point callers to live MCP catalog');
41
41
  assert.doesNotMatch(docs.readme, /All user-invocable skills become available as slash commands/, 'README must not imply all MCP skills are slash commands');
42
42
  assert.doesNotMatch(docs.readme, /29 skills organized into 6 categories/, 'README must not carry stale category count');
@@ -24,7 +24,7 @@ const plugin = JSON.parse(readFileSync(join(REPO_ROOT, '.claude-plugin', 'plugin
24
24
  const skillCount = Array.isArray(plugin.skills_meta)
25
25
  ? plugin.skills_meta.length
26
26
  : Object.keys(plugin.skills_meta || {}).length;
27
- assert.equal(skillCount, 29, 'test fixture should expose all 29 MCP skills from plugin skills_meta');
27
+ assert.equal(skillCount, 30, 'test fixture should expose all 30 MCP skills from plugin skills_meta');
28
28
  assert.match(
29
29
  source,
30
30
  /Available MCP skills.*\/rdc:\* command shorthands/,