@opengsd/gsd-core 1.7.0-rc.1 → 1.7.0-rc.2

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 (74) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +711 -0
  4. package/agents/gsd-advisor-researcher.md +2 -0
  5. package/agents/gsd-ai-researcher.md +1 -1
  6. package/agents/gsd-assumptions-analyzer.md +2 -0
  7. package/agents/gsd-code-fixer.md +2 -0
  8. package/agents/gsd-code-reviewer.md +2 -0
  9. package/agents/gsd-codebase-mapper.md +2 -0
  10. package/agents/gsd-debugger.md +2 -0
  11. package/agents/gsd-doc-writer.md +2 -0
  12. package/agents/gsd-eval-auditor.md +2 -0
  13. package/agents/gsd-executor.md +9 -6
  14. package/agents/gsd-integration-checker.md +2 -0
  15. package/agents/gsd-nyquist-auditor.md +2 -0
  16. package/agents/gsd-phase-researcher.md +2 -0
  17. package/agents/gsd-plan-checker.md +2 -0
  18. package/agents/gsd-planner.md +2 -0
  19. package/agents/gsd-project-researcher.md +2 -0
  20. package/agents/gsd-research-synthesizer.md +2 -0
  21. package/agents/gsd-roadmapper.md +2 -0
  22. package/agents/gsd-security-auditor.md +2 -0
  23. package/agents/gsd-ui-auditor.md +2 -0
  24. package/agents/gsd-ui-checker.md +2 -0
  25. package/agents/gsd-ui-researcher.md +2 -0
  26. package/agents/gsd-verifier.md +4 -2
  27. package/bin/install.js +118 -1
  28. package/gemini-extension.json +1 -1
  29. package/gsd-core/bin/gsd-tools.cjs +18 -7
  30. package/gsd-core/bin/lib/capability-loader.cjs +27 -9
  31. package/gsd-core/bin/lib/capability-registry.cjs +51 -49
  32. package/gsd-core/bin/lib/capability-source.cjs +22 -7
  33. package/gsd-core/bin/lib/capability-validator.cjs +24 -2
  34. package/gsd-core/bin/lib/commands.cjs +2 -1
  35. package/gsd-core/bin/lib/frontmatter.cjs +53 -6
  36. package/gsd-core/bin/lib/handshake-serialized.cjs +70 -0
  37. package/gsd-core/bin/lib/host-integration-sdk.cjs +53 -0
  38. package/gsd-core/bin/lib/host-integration.cjs +61 -0
  39. package/gsd-core/bin/lib/init.cjs +34 -6
  40. package/gsd-core/bin/lib/milestone.cjs +49 -10
  41. package/gsd-core/bin/lib/phase-id.cjs +18 -0
  42. package/gsd-core/bin/lib/phase.cjs +37 -27
  43. package/gsd-core/bin/lib/phases-command-router.cjs +4 -3
  44. package/gsd-core/bin/lib/probe-core.cjs +44 -4
  45. package/gsd-core/bin/lib/roadmap-command-router.cjs +3 -2
  46. package/gsd-core/bin/lib/roadmap-parser.cjs +21 -11
  47. package/gsd-core/bin/lib/roadmap.cjs +28 -20
  48. package/gsd-core/bin/lib/state-transition.cjs +15 -0
  49. package/gsd-core/bin/lib/state.cjs +27 -8
  50. package/gsd-core/bin/lib/validate.cjs +2 -1
  51. package/gsd-core/bin/lib/verify.cjs +6 -4
  52. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +12 -2
  53. package/gsd-core/bin/lib/workstream-inventory.cjs +28 -0
  54. package/gsd-core/bin/shared/model-catalog.json +8 -8
  55. package/gsd-core/references/agent-skills-bootstrap.md +60 -0
  56. package/gsd-core/references/model-profiles.md +27 -0
  57. package/gsd-core/workflows/autonomous.md +22 -24
  58. package/gsd-core/workflows/complete-milestone.md +6 -10
  59. package/gsd-core/workflows/execute-phase.md +1 -1
  60. package/gsd-core/workflows/forensics.md +3 -3
  61. package/gsd-core/workflows/help/modes/full.md +1 -1
  62. package/gsd-core/workflows/milestone-summary.md +3 -3
  63. package/gsd-core/workflows/new-milestone.md +6 -0
  64. package/gsd-core/workflows/plan-phase/steps/closed-phase-gate.md +42 -0
  65. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +102 -0
  66. package/gsd-core/workflows/plan-phase/steps/windows-troubleshooting.md +23 -0
  67. package/gsd-core/workflows/plan-phase.md +3 -158
  68. package/gsd-core/workflows/review.md +7 -2
  69. package/gsd-core/workflows/settings-advanced.md +10 -10
  70. package/gsd-core/workflows/verify-work.md +1 -2
  71. package/package.json +3 -1
  72. package/scripts/run-tests.cjs +51 -1
  73. package/scripts/sync-manifest-versions.cjs +66 -14
  74. package/skills/gsd-review/SKILL.md +6 -0
@@ -19,6 +19,8 @@ Spawned by `discuss-phase` via `Task()`. You do NOT present output directly to t
19
19
 
20
20
  @~/.claude/gsd-core/references/untrusted-input-boundary.md
21
21
 
22
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
23
+
22
24
  <documentation_lookup>
23
25
  @~/.claude/gsd-core/references/research-documentation-lookup.md
24
26
  </documentation_lookup>
@@ -72,7 +72,7 @@ Update AI-SPEC.md at `ai_spec_path`:
72
72
 
73
73
  **Section 3 — Framework Quick Reference:** real installation command, actual imports, working entry point pattern for `system_type`, abstractions table (3-5 rows), pitfall list with why-it's-a-pitfall notes, folder structure, Sources subsection with URLs.
74
74
 
75
- **Section 4 — Implementation Guidance:** specific model (e.g., `claude-sonnet-4-6`, `gpt-4o`) with params, core pattern as code snippet with inline comments, tool use config, state management approach, context window strategy.
75
+ **Section 4 — Implementation Guidance:** specific model (e.g., `claude-sonnet-5`, `gpt-4o`) with params, core pattern as code snippet with inline comments, tool use config, state management approach, context window strategy.
76
76
  </step>
77
77
 
78
78
  <step name="write_section_4b">
@@ -20,6 +20,8 @@ Spawned by `discuss-phase-assumptions` via `Task()`. You do NOT present output d
20
20
 
21
21
  @~/.claude/gsd-core/references/untrusted-input-boundary.md
22
22
 
23
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
24
+
23
25
  <input>
24
26
  Agent receives via prompt:
25
27
 
@@ -24,6 +24,8 @@ Before fixing code, discover project context:
24
24
  **Project instructions:** Read `./CLAUDE.md` if it exists in the working directory. Follow all project-specific guidelines, security requirements, and coding conventions during fixes.
25
25
 
26
26
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
27
+
28
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
27
29
  1. List available skills (subdirectories)
28
30
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
29
31
  3. Load specific `rules/*.md` files as needed during implementation
@@ -40,6 +40,8 @@ Before reviewing, discover project context:
40
40
  **Project instructions:** Read `./CLAUDE.md` if it exists in the working directory. Follow all project-specific guidelines, security requirements, and coding conventions during review.
41
41
 
42
42
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
43
+
44
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
43
45
  1. List available skills (subdirectories)
44
46
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
45
47
  3. Load specific `rules/*.md` files as needed during review
@@ -29,6 +29,8 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
29
29
  **Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
30
30
 
31
31
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
32
+
33
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
32
34
  1. List available skills (subdirectories)
33
35
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
34
36
  3. Load specific `rules/*.md` files as needed during implementation
@@ -40,6 +40,8 @@ Your job: Find the root cause through hypothesis testing, maintain debug file st
40
40
  - Load `rules/*.md` as needed during **investigation and fix**.
41
41
  - Follow skill rules relevant to the bug being investigated and the fix being applied.
42
42
 
43
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
44
+
43
45
  <philosophy>
44
46
 
45
47
  @~/.claude/gsd-core/references/debugger-philosophy.md
@@ -34,6 +34,8 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
34
34
  **Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
35
35
 
36
36
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
37
+
38
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
37
39
  1. List available skills (subdirectories)
38
40
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
39
41
  3. Load specific `rules/*.md` files as needed during implementation
@@ -39,6 +39,8 @@ Read `~/.claude/gsd-core/references/ai-evals.md` before auditing. This is your s
39
39
  **Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
40
40
 
41
41
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
42
+
43
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
42
44
  1. List available skills (subdirectories)
43
45
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
44
46
  3. Load specific `rules/*.md` files as needed during implementation
@@ -64,6 +64,8 @@ Before executing, discover project context:
64
64
  - Load `rules/*.md` as needed during **implementation**.
65
65
  - Follow skill rules relevant to the task you are about to commit.
66
66
 
67
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
68
+
67
69
  **CLAUDE.md enforcement:** If `./CLAUDE.md` exists, treat its directives as hard constraints during execution. Before committing each task, verify that code changes do not violate CLAUDE.md rules (forbidden patterns, required conventions, mandated tools). If a task action would contradict a CLAUDE.md directive, apply the CLAUDE.md rule — it takes precedence over plan instructions. Document any CLAUDE.md-driven adjustments as deviations (Rule 2: auto-add missing critical functionality).
68
70
  </project_context>
69
71
 
@@ -689,7 +691,7 @@ Do NOT skip. Do NOT proceed to state updates if self-check fails.
689
691
  </self_check>
690
692
 
691
693
  <state_updates>
692
- After SUMMARY.md, update STATE.md using `gsd-tools query` state handlers (positional args; see `sdk/src/query/QUERY-HANDLERS.md`):
694
+ After SUMMARY.md, update STATE.md using `gsd-tools query` state handlers (named flags; see `sdk/src/query/QUERY-HANDLERS.md`):
693
695
 
694
696
  ```bash
695
697
  # Advance plan counter (handles edge cases automatically)
@@ -700,16 +702,17 @@ gsd_run query state.update-progress
700
702
 
701
703
  # Record execution metrics (phase, plan, duration, tasks, files)
702
704
  gsd_run query state.record-metric \
703
- "${PHASE}" "${PLAN}" "${DURATION}" "${TASK_COUNT}" "${FILE_COUNT}"
705
+ --phase "${PHASE}" --plan "${PLAN}" --duration "${DURATION}" \
706
+ --tasks "${TASK_COUNT}" --files "${FILE_COUNT}"
704
707
 
705
708
  # Add decisions (extract from SUMMARY.md key-decisions)
706
709
  for decision in "${DECISIONS[@]}"; do
707
- gsd_run query state.add-decision "${decision}"
710
+ gsd_run query state.add-decision --summary "${decision}"
708
711
  done
709
712
 
710
- # Update session info (timestamp, stopped-at, resume-file)
713
+ # Update session info (stopped-at, resume-file; timestamp set automatically)
711
714
  gsd_run query state.record-session \
712
- "" "Completed ${PHASE}-${PLAN}-PLAN.md" "None"
715
+ --stopped-at "Completed ${PHASE}-${PLAN}-PLAN.md" --resume-file "None"
713
716
  ```
714
717
 
715
718
  ```bash
@@ -736,7 +739,7 @@ gsd_run query requirements.mark-complete ${REQ_IDS}
736
739
 
737
740
  **For blockers found during execution:**
738
741
  ```bash
739
- gsd_run query state.add-blocker "Blocker description"
742
+ gsd_run query state.add-blocker --text "Blocker description"
740
743
  ```
741
744
  </state_updates>
742
745
 
@@ -35,6 +35,8 @@ Every expected cross-phase connection must resolve to WIRED (verified end-to-end
35
35
  **Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
36
36
 
37
37
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
38
+
39
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
38
40
  1. List available skills (subdirectories)
39
41
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
40
42
  3. Load specific `rules/*.md` files as needed during implementation
@@ -51,6 +51,8 @@ Read ALL files from `<required_reading>`. Extract:
51
51
  **Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
52
52
 
53
53
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
54
+
55
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
54
56
  1. List available skills (subdirectories)
55
57
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
56
58
  3. Load specific `rules/*.md` files as needed during implementation
@@ -50,6 +50,8 @@ Before researching, discover project context:
50
50
  - Load `rules/*.md` as needed during **research**.
51
51
  - Research output should account for project skill patterns and conventions.
52
52
 
53
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
54
+
53
55
  **CLAUDE.md enforcement:** If `./CLAUDE.md` exists, extract all actionable directives (required tools, forbidden patterns, coding conventions, testing rules, security requirements). Include a `## Project Constraints (from CLAUDE.md)` section in RESEARCH.md listing these directives so the planner can verify compliance. Treat CLAUDE.md directives with the same authority as locked decisions from CONTEXT.md — research should not recommend approaches that contradict them.
54
56
  </project_context>
55
57
 
@@ -54,6 +54,8 @@ Before verifying, discover project context:
54
54
  **Project instructions:** Read `./CLAUDE.md` if it exists in the working directory. Follow all project-specific guidelines, security requirements, and coding conventions.
55
55
 
56
56
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
57
+
58
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
57
59
  1. List available skills (subdirectories)
58
60
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
59
61
  3. Load specific `rules/*.md` files as needed during verification
@@ -46,6 +46,8 @@ Before planning, discover project context:
46
46
  **Project skills:** @~/.claude/gsd-core/references/project-skills-discovery.md
47
47
  - Load `rules/*.md` as needed during **planning**.
48
48
  - Ensure plans account for project skill patterns and conventions.
49
+
50
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
49
51
  </project_context>
50
52
 
51
53
  <context_fidelity>
@@ -34,6 +34,8 @@ Your files feed the roadmap:
34
34
 
35
35
  @~/.claude/gsd-core/references/untrusted-input-boundary.md
36
36
 
37
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
38
+
37
39
  <documentation_lookup>
38
40
  @~/.claude/gsd-core/references/research-documentation-lookup.md
39
41
  </documentation_lookup>
@@ -34,6 +34,8 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
34
34
 
35
35
  @~/.claude/gsd-core/references/untrusted-input-boundary.md
36
36
 
37
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
38
+
37
39
  <downstream_consumer>
38
40
  Your SUMMARY.md is consumed by the gsd-roadmapper agent which uses it to:
39
41
 
@@ -26,6 +26,8 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
26
26
  **Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
27
27
 
28
28
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
29
+
30
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
29
31
  1. List available skills (subdirectories)
30
32
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
31
33
  3. Load specific `rules/*.md` files as needed during implementation
@@ -51,6 +51,8 @@ Read ALL files from `<required_reading>`. Extract:
51
51
  **Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
52
52
 
53
53
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
54
+
55
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
54
56
  1. List available skills (subdirectories)
55
57
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
56
58
  3. Load specific `rules/*.md` files as needed during implementation
@@ -49,6 +49,8 @@ Before auditing, discover project context:
49
49
  **Project instructions:** Read `./CLAUDE.md` if it exists in the working directory. Follow all project-specific guidelines.
50
50
 
51
51
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
52
+
53
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
52
54
  1. List available skills (subdirectories)
53
55
  2. Read `SKILL.md` for each skill
54
56
  3. Do NOT load full `AGENTS.md` files (100KB+ context cost)
@@ -30,6 +30,8 @@ Before verifying, discover project context:
30
30
  **Project instructions:** Read `./CLAUDE.md` if it exists in the working directory. Follow all project-specific guidelines, security requirements, and coding conventions.
31
31
 
32
32
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
33
+
34
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
33
35
  1. List available skills (subdirectories)
34
36
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
35
37
  3. Load specific `rules/*.md` files as needed during verification
@@ -39,6 +39,8 @@ Before researching, discover project context:
39
39
  **Project instructions:** Read `./CLAUDE.md` if it exists in the working directory. Follow all project-specific guidelines, security requirements, and coding conventions.
40
40
 
41
41
  **Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
42
+
43
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
42
44
  1. List available skills (subdirectories)
43
45
  2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
44
46
  3. Load specific `rules/*.md` files as needed during research
@@ -52,14 +52,16 @@ Before verifying, discover project context:
52
52
  **Project skills:** @~/.claude/gsd-core/references/project-skills-discovery.md
53
53
  - Load `rules/*.md` as needed during **verification**.
54
54
  - Apply skill rules when scanning for anti-patterns and verifying quality.
55
+
56
+ **agent_skills:** self-load per @~/.claude/gsd-core/references/agent-skills-bootstrap.md
55
57
  </project_context>
56
58
 
57
59
  <core_principle>
58
60
  **Task completion ≠ Goal achievement**
59
61
 
60
- A task "create chat component" can be marked complete when the component is a placeholder. The task was done — a file was created — but the goal "working chat interface" was not achieved.
62
+ A "create chat component" task can be complete with a placeholder file — task done, goal "working chat interface" missed.
61
63
 
62
- Goal-backward verification starts from the outcome and works backwards:
64
+ Start from the outcome and work backwards:
63
65
 
64
66
  1. What must be TRUE for the goal to be achieved?
65
67
  2. What must EXIST for those truths to hold?
package/bin/install.js CHANGED
@@ -374,6 +374,7 @@ const {
374
374
  } = require(path.join(__dirname, '..', 'gsd-core', 'bin', 'lib', 'legacy-cleanup.cjs'));
375
375
  const {
376
376
  updateCacheFileName,
377
+ PACKAGE_NAME,
377
378
  } = require(path.join(__dirname, '..', 'gsd-core', 'bin', 'lib', 'package-identity.cjs'));
378
379
 
379
380
  // ADR-1239 Phase B: runtime-artifact install cluster extracted to install-engine.cjs.
@@ -7316,6 +7317,22 @@ function uninstall(isGlobal, runtime = 'claude') {
7316
7317
  }
7317
7318
  }
7318
7319
 
7320
+ // 4z. Remove the OpenCode native plugin adapter (#1914). Only GSD's own
7321
+ // plugin file is removed; the plugins/ dir is pruned only if it becomes
7322
+ // empty, preserving any user-authored OpenCode plugins.
7323
+ if (isOpencode) {
7324
+ const pluginsDir = path.join(targetDir, 'plugins');
7325
+ const pluginPath = path.join(pluginsDir, 'gsd-core.js');
7326
+ if (fs.existsSync(pluginPath)) {
7327
+ try {
7328
+ fs.unlinkSync(pluginPath);
7329
+ removedCount++;
7330
+ console.log(` ${green}✓${reset} Removed OpenCode plugin`);
7331
+ } catch (_) { /* best-effort */ }
7332
+ try { fs.rmdirSync(pluginsDir); } catch (_) { /* not empty — user plugins present */ }
7333
+ }
7334
+ }
7335
+
7319
7336
  // 4a. Remove scripts/changeset/ and scripts/lib/ (#935)
7320
7337
  // GSD-managed files only: enumerate the exact set the installer writes.
7321
7338
  // Any file NOT in this set is user-owned and must survive uninstall.
@@ -7360,6 +7377,11 @@ function uninstall(isGlobal, runtime = 'claude') {
7360
7377
  const fixSlashUninstallPath = path.join(targetDir, 'scripts', 'fix-slash-commands.cjs');
7361
7378
  try { fs.unlinkSync(fixSlashUninstallPath); } catch (_) { /* best-effort */ }
7362
7379
 
7380
+ // Remove the capability registry generator scripts (#1920) — before the scripts/ rmdir
7381
+ for (const gen of ['gen-capability-registry.cjs', 'gen-loop-host-contract.cjs']) {
7382
+ try { fs.unlinkSync(path.join(targetDir, 'scripts', gen)); } catch (_) { /* best-effort */ }
7383
+ }
7384
+
7363
7385
  // If scripts/ dir is now empty, remove it too
7364
7386
  const scriptsUninstallDir = path.join(targetDir, 'scripts');
7365
7387
  if (fs.existsSync(scriptsUninstallDir)) {
@@ -7702,7 +7724,7 @@ function configureOpencodePermissions(isGlobal = true, configDir = null) {
7702
7724
  modified = true;
7703
7725
  }
7704
7726
 
7705
- // Configure external_directory permission (the safety guard for paths outside project)
7727
+ // Configure external_directory permission (the safety guard for paths outside)
7706
7728
  if (!config.permission.external_directory || typeof config.permission.external_directory !== 'object') {
7707
7729
  config.permission.external_directory = {};
7708
7730
  }
@@ -7711,6 +7733,25 @@ function configureOpencodePermissions(isGlobal = true, configDir = null) {
7711
7733
  modified = true;
7712
7734
  }
7713
7735
 
7736
+ // ADR-1239 Phase D / #1682 — register the companion MCP server (Phase 4) so
7737
+ // OpenCode connects to GSD's command (point 1) + state-IO (point 5) surface
7738
+ // with NO bespoke plugin. Idempotent + non-clobbering: only added when
7739
+ // `mcp.gsd` is absent (a user-defined `mcp.gsd` is respected — Hyrum's Law).
7740
+ // Local-stdio schema per OpenCode config (packages/core/src/config/mcp.ts).
7741
+ // `-p @opengsd/gsd-core` resolves the `gsd-mcp-server` bin from this package
7742
+ // (bin name != package name) regardless of global-install state.
7743
+ if (!config.mcp || typeof config.mcp !== 'object') {
7744
+ config.mcp = {};
7745
+ }
7746
+ if (config.mcp.gsd === undefined) {
7747
+ config.mcp.gsd = {
7748
+ type: 'local',
7749
+ command: ['npx', '-y', '-p', PACKAGE_NAME, 'gsd-mcp-server'],
7750
+ enabled: true,
7751
+ };
7752
+ modified = true;
7753
+ }
7754
+
7714
7755
  if (!modified) {
7715
7756
  return; // Already configured
7716
7757
  }
@@ -8064,6 +8105,24 @@ function writeManifest(configDir, runtime = 'claude', options = {}) {
8064
8105
  manifest.files['scripts/fix-slash-commands.cjs'] = fileHash(fixSlashInstallPath);
8065
8106
  }
8066
8107
 
8108
+ // Track the capability registry generator scripts (#1920) — top-level scripts/ files
8109
+ // not covered by the changeset/lib loops.
8110
+ for (const gen of ['gen-capability-registry.cjs', 'gen-loop-host-contract.cjs']) {
8111
+ const genInstallPath = path.join(configDir, 'scripts', gen);
8112
+ if (fs.existsSync(genInstallPath)) {
8113
+ manifest.files['scripts/' + gen] = fileHash(genInstallPath);
8114
+ }
8115
+ }
8116
+
8117
+ // Track the OpenCode native plugin adapter (#1914) so update/drift detection
8118
+ // and uninstall can account for it.
8119
+ if (isOpencode) {
8120
+ const pluginInstallPath = path.join(configDir, 'plugins', 'gsd-core.js');
8121
+ if (fs.existsSync(pluginInstallPath)) {
8122
+ manifest.files['plugins/gsd-core.js'] = fileHash(pluginInstallPath);
8123
+ }
8124
+ }
8125
+
8067
8126
  fs.writeFileSync(path.join(configDir, MANIFEST_NAME), JSON.stringify(manifest, null, 2));
8068
8127
  return manifest;
8069
8128
  }
@@ -8999,6 +9058,39 @@ function install(isGlobal, runtime = 'claude', options = {}) {
8999
9058
  } else {
9000
9059
  failures.push('skills/gsd-*');
9001
9060
  }
9061
+
9062
+ // OpenCode-only: install the native plugin adapter (#1914). OpenCode
9063
+ // declares hooksSurface: 'none', so GSD's lifecycle hooks are never
9064
+ // registered as settings.json hooks the way Claude Code does — the hook
9065
+ // *scripts* ship to <configDir>/hooks/ but nothing invokes them. This
9066
+ // plugin bridges OpenCode's event bus onto those existing hook scripts
9067
+ // (prompt guard, read guard, injection scanner, context monitor, ...),
9068
+ // spawning them as subprocesses. OpenCode auto-discovers plugin files under
9069
+ // <configDir>/plugins/ at startup — no opencode.json registration needed
9070
+ // (its `plugin` array is for npm packages, not local file paths).
9071
+ //
9072
+ // The file MUST land as `.js`: OpenCode's loader globs
9073
+ // `{plugin,plugins}/*.{ts,js}` (verified against its source) — a `.cjs`
9074
+ // extension would never be discovered. The config dir carries a
9075
+ // `{"type":"commonjs"}` package.json (written above), so the `.js` file is
9076
+ // interpreted as CommonJS, matching the adapter's module.exports/require.
9077
+ // Kilo has no plugin surface, so this is gated to OpenCode only.
9078
+ if (isOpencode) {
9079
+ const pluginSrc = path.join(src, '.opencode', 'plugins', 'gsd-core.js');
9080
+ const pluginDestDir = path.join(targetDir, 'plugins');
9081
+ const pluginDest = path.join(pluginDestDir, 'gsd-core.js');
9082
+ if (fs.existsSync(pluginSrc)) {
9083
+ fs.mkdirSync(pluginDestDir, { recursive: true });
9084
+ fs.copyFileSync(pluginSrc, pluginDest);
9085
+ if (fs.existsSync(pluginDest)) {
9086
+ console.log(` ${green}✓${reset} Installed OpenCode plugin (bridges GSD hooks)`);
9087
+ } else {
9088
+ failures.push('plugins/gsd-core.js');
9089
+ }
9090
+ } else {
9091
+ failures.push('plugins/gsd-core.js');
9092
+ }
9093
+ }
9002
9094
  } else if (isCline) {
9003
9095
  // Cline local install: rules-based only — commands are embedded in .clinerules (generated below).
9004
9096
  // No skills/commands directory needed for local installs.
@@ -9551,6 +9643,31 @@ function install(isGlobal, runtime = 'claude', options = {}) {
9551
9643
  }
9552
9644
  }
9553
9645
 
9646
+ // Copy scripts/gen-capability-registry.cjs + scripts/gen-loop-host-contract.cjs —
9647
+ // required by gsd-core/bin/lib/capability-loader.cjs at overlay-composition time via
9648
+ // require('../../../scripts/gen-capability-registry.cjs') (which itself requires
9649
+ // gen-loop-host-contract.cjs). Without these, the loader's never-crash invariant
9650
+ // discards EVERY third-party capability overlay and silently falls back to the frozen
9651
+ // first-party registry, so installed capabilities are inert (#1920). Same class of
9652
+ // gap as #1223 (fix-slash-commands.cjs) and copied unconditionally for the same reason:
9653
+ // any runtime that installs gsd-core/ needs the capability system to compose.
9654
+ {
9655
+ const capGenDestDir = path.join(targetDir, 'scripts');
9656
+ fs.mkdirSync(capGenDestDir, { recursive: true });
9657
+ for (const gen of ['gen-capability-registry.cjs', 'gen-loop-host-contract.cjs']) {
9658
+ const genSrc = path.join(src, 'scripts', gen);
9659
+ const genDest = path.join(capGenDestDir, gen);
9660
+ if (!fs.existsSync(genSrc)) {
9661
+ failures.push(`scripts/${gen} (source missing from package — reinstall from npm)`);
9662
+ } else {
9663
+ fs.copyFileSync(genSrc, genDest);
9664
+ if (!verifyFileInstalled(genDest, `scripts/${gen}`)) {
9665
+ failures.push(`scripts/${gen}`);
9666
+ }
9667
+ }
9668
+ }
9669
+ }
9670
+
9554
9671
  // Remove legacy get-shit-done-cc artifacts and stale update caches (#607).
9555
9672
  // cleanupLegacyGsdCc handles both the legacy shared cache and the per-package
9556
9673
  // cache (formerly an inline unlinkSync here). A cleanup failure must never
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsd-core",
3
- "version": "1.7.0-rc.1",
3
+ "version": "1.7.0-rc.2",
4
4
  "description": "GSD Core — a meta-prompting, context engineering, and spec-driven development system for AI coding agents. Loads gsd's operating context into every Gemini CLI session.",
5
5
  "contextFileName": "GEMINI.md"
6
6
  }
@@ -57,7 +57,7 @@
57
57
  * Milestone Operations:
58
58
  * milestone complete <version> Archive milestone, create MILESTONES.md
59
59
  * [--name <name>]
60
- * [--archive-phases] Move phase dirs to milestones/vX.Y-phases/
60
+ * [--no-archive-phases] Skip moving phase dirs to milestones/vX.Y-phases/ (archived by default)
61
61
  *
62
62
  * User Story Validation:
63
63
  * user-story validate --story "..." Validate "As a / I want to / so that" format
@@ -1453,7 +1453,9 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1453
1453
  const subcommand = args[1];
1454
1454
  if (subcommand === 'complete') {
1455
1455
  const milestoneName = parseMultiwordArg(args, 'name');
1456
- const archivePhases = args.includes('--archive-phases');
1456
+ // #1871: archive phase dirs by default on milestone complete so the next
1457
+ // new-milestone never inherits un-archived dirs. --no-archive-phases opts out.
1458
+ const archivePhases = !args.includes('--no-archive-phases');
1457
1459
  const force = args.includes('--force');
1458
1460
  milestone.cmdMilestoneComplete(cwd, args[2], { name: milestoneName, archivePhases, force }, raw);
1459
1461
  } else {
@@ -1665,13 +1667,22 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1665
1667
  return undefined;
1666
1668
  };
1667
1669
  // Running GSD version (hard gate for engines.gsd at install/load); fail-closed to 0.0.0.
1670
+ // #1920: prefer the authoritative gsd-core/VERSION the installer writes for EVERY runtime
1671
+ // (gsd-core/bin/ -> ../VERSION), so installed layouts report the true version even when the
1672
+ // walked-up ../../package.json is the versionless CommonJS marker or the user's own project.
1673
+ // Fall back to the runtime-root package.json (dev/source tree), then fail-closed. Mirrors
1674
+ // readHostVersion() in capability-loader.cts.
1668
1675
  const capHostVersion = () => {
1676
+ const SEMVER_PREFIX = /^\d+\.\d+\.\d+/;
1669
1677
  try {
1670
- const pkg = require('../../package.json'); // gsd-core/bin/ -> repo root is two up
1671
- return typeof pkg.version === 'string' && pkg.version ? pkg.version : '0.0.0';
1672
- } catch {
1673
- return '0.0.0';
1674
- }
1678
+ const v = fs.readFileSync(path.join(__dirname, '..', 'VERSION'), 'utf8').trim();
1679
+ if (SEMVER_PREFIX.test(v)) return v;
1680
+ } catch { /* not an installed tree (no gsd-core/VERSION) */ }
1681
+ try {
1682
+ const pkg = require(path.join(__dirname, '..', '..', 'package.json')); // gsd-core/bin/ -> repo root is two up
1683
+ if (pkg && typeof pkg.version === 'string' && SEMVER_PREFIX.test(pkg.version)) return pkg.version;
1684
+ } catch { /* runtime root has no package.json */ }
1685
+ return '0.0.0';
1675
1686
  };
1676
1687
  // #1459: the USER-OWNED consent home (GSD_HOME||homedir()) where project-scope consent records
1677
1688
  // live — OUTSIDE any repo. SAME rule as the loader/consent-store path resolution so a record
@@ -67,6 +67,7 @@ var __importStar = (this && this.__importStar) || (function () {
67
67
  };
68
68
  })();
69
69
  Object.defineProperty(exports, "__esModule", { value: true });
70
+ exports.readHostVersion = readHostVersion;
70
71
  exports.loadRegistry = loadRegistry;
71
72
  const fs = __importStar(require("node:fs"));
72
73
  const os = __importStar(require("node:os"));
@@ -110,17 +111,33 @@ function _setValidatorForTest(v) {
110
111
  function _setGeneratorForTest(g) {
111
112
  _generatorOverride = g;
112
113
  }
113
- /** Resolve the running GSD version; fail-closed to '0.0.0' if it cannot be read. */
114
- function readHostVersion() {
114
+ /**
115
+ * Resolve the running GSD version; fail-closed to '0.0.0' if it cannot be read.
116
+ *
117
+ * Prefer the authoritative `gsd-core/VERSION` the installer writes for EVERY runtime
118
+ * (libDir = gsd-core/bin/lib/, so `../../VERSION` = gsd-core/VERSION). This is reliable
119
+ * across all installed layouts — including runtimes that get no marker package.json, and
120
+ * local installs where the walked-up `../../../package.json` would resolve to the USER's
121
+ * own project and report a wrong version (#1920). Fall back to the runtime-root
122
+ * package.json for the dev/source tree, then fail-closed. Mirrors resolveVersionFrom()
123
+ * (#1383). `libDir` is injectable for tests; it defaults to this module's directory.
124
+ */
125
+ function readHostVersion(libDir = __dirname) {
126
+ const SEMVER_PREFIX = /^\d+\.\d+\.\d+/;
115
127
  try {
116
- // gsd-core/bin/lib/ -> repo/package root is three levels up.
117
- // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment
118
- const pkg = require('../../../package.json');
119
- return typeof pkg.version === 'string' && pkg.version ? pkg.version : '0.0.0';
128
+ const v = fs.readFileSync(path.join(libDir, '..', '..', 'VERSION'), 'utf8').trim();
129
+ if (SEMVER_PREFIX.test(v))
130
+ return v;
120
131
  }
121
- catch {
122
- return '0.0.0';
132
+ catch { /* not an installed tree (no gsd-core/VERSION) */ }
133
+ try {
134
+ // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment
135
+ const pkg = require(path.join(libDir, '..', '..', '..', 'package.json'));
136
+ if (pkg && typeof pkg.version === 'string' && SEMVER_PREFIX.test(pkg.version))
137
+ return pkg.version;
123
138
  }
139
+ catch { /* runtime root has no package.json */ }
140
+ return '0.0.0';
124
141
  }
125
142
  /**
126
143
  * Canonicalize a directory path for dedup/scope-escalation comparison. #1459 finding 1 (HIGH): the dedup
@@ -779,4 +796,5 @@ function loadRegistry(options = {}) {
779
796
  return withOverlayMeta(base, meta);
780
797
  }
781
798
  }
782
- module.exports = { loadRegistry, _setValidatorForTest, _setGeneratorForTest };
799
+ // readHostVersion is exported for the #1920 regression (VERSION-first host-version resolution).
800
+ module.exports = { loadRegistry, readHostVersion, _setValidatorForTest, _setGeneratorForTest };