@opengsd/gsd-core 1.6.0-rc.3 → 1.7.0-rc.1

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 (105) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/agents/gsd-advisor-researcher.md +2 -0
  3. package/agents/gsd-ai-researcher.md +2 -0
  4. package/agents/gsd-assumptions-analyzer.md +2 -0
  5. package/agents/gsd-doc-classifier.md +2 -0
  6. package/agents/gsd-doc-synthesizer.md +2 -0
  7. package/agents/gsd-domain-researcher.md +2 -0
  8. package/agents/gsd-eval-auditor.md +6 -9
  9. package/agents/gsd-phase-researcher.md +2 -0
  10. package/agents/gsd-project-researcher.md +2 -0
  11. package/agents/gsd-research-synthesizer.md +2 -0
  12. package/agents/gsd-ui-researcher.md +2 -0
  13. package/agents/gsd-verifier.md +1 -0
  14. package/bin/gsd-mcp-server.js +31 -0
  15. package/bin/install.js +512 -1150
  16. package/commands/gsd/review.md +6 -0
  17. package/gemini-extension.json +1 -1
  18. package/gsd-core/bin/gsd-tools.cjs +127 -2
  19. package/gsd-core/bin/lib/adapter-declarative.cjs +35 -0
  20. package/gsd-core/bin/lib/adapter-imperative.cjs +52 -0
  21. package/gsd-core/bin/lib/assumption-delta.cjs +231 -0
  22. package/gsd-core/bin/lib/capability-lifecycle.cjs +7 -7
  23. package/gsd-core/bin/lib/capability-loader.cjs +18 -0
  24. package/gsd-core/bin/lib/capability-lock.cjs +2 -2
  25. package/gsd-core/bin/lib/capability-registry.cjs +889 -82
  26. package/gsd-core/bin/lib/capability-source.cjs +4 -4
  27. package/gsd-core/bin/lib/capability-validator.cjs +198 -0
  28. package/gsd-core/bin/lib/cli-skew-check.cjs +44 -0
  29. package/gsd-core/bin/lib/command-aliases.cjs +18 -1
  30. package/gsd-core/bin/lib/config.cjs +27 -0
  31. package/gsd-core/bin/lib/decisions.cjs +27 -0
  32. package/gsd-core/bin/lib/embedding-adapter.cjs +27 -0
  33. package/gsd-core/bin/lib/eval-command-router.cjs +21 -0
  34. package/gsd-core/bin/lib/eval.cjs +60 -0
  35. package/gsd-core/bin/lib/external-descriptor-trust.cjs +70 -0
  36. package/gsd-core/bin/lib/frontmatter.cjs +132 -13
  37. package/gsd-core/bin/lib/hook-bus.cjs +81 -0
  38. package/gsd-core/bin/lib/host-integration.cjs +408 -0
  39. package/gsd-core/bin/lib/init.cjs +132 -27
  40. package/gsd-core/bin/lib/install-engine.cjs +755 -0
  41. package/gsd-core/bin/lib/install-profiles.cjs +35 -4
  42. package/gsd-core/bin/lib/installer-migrations.cjs +1 -1
  43. package/gsd-core/bin/lib/io.cjs +1 -0
  44. package/gsd-core/bin/lib/mcp-server.cjs +194 -0
  45. package/gsd-core/bin/lib/milestone.cjs +27 -30
  46. package/gsd-core/bin/lib/model-adapter.cjs +50 -0
  47. package/gsd-core/bin/lib/phase.cjs +57 -74
  48. package/gsd-core/bin/lib/plan-scan.cjs +2 -2
  49. package/gsd-core/bin/lib/planning-workspace.cjs +1 -1
  50. package/gsd-core/bin/lib/probe-core.cjs +91 -1
  51. package/gsd-core/bin/lib/review-reviewer-selection.cjs +129 -13
  52. package/gsd-core/bin/lib/roadmap-upgrade.cjs +3 -2
  53. package/gsd-core/bin/lib/roadmap.cjs +17 -3
  54. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +65 -9
  55. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +54 -4
  56. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +5 -2
  57. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +1 -1
  58. package/gsd-core/bin/lib/runtime-name-policy.cjs +160 -30
  59. package/gsd-core/bin/lib/shell-command-projection.cjs +47 -1
  60. package/gsd-core/bin/lib/stale-bake-guard.cjs +254 -0
  61. package/gsd-core/bin/lib/state-command-router.cjs +4 -0
  62. package/gsd-core/bin/lib/state-io.cjs +55 -0
  63. package/gsd-core/bin/lib/state-transition.cjs +1588 -0
  64. package/gsd-core/bin/lib/state.cjs +340 -689
  65. package/gsd-core/bin/lib/surface.cjs +4 -1
  66. package/gsd-core/bin/lib/uat-predicate.cjs +13 -6
  67. package/gsd-core/bin/lib/verification.cjs +67 -6
  68. package/gsd-core/bin/lib/verify.cjs +8 -1
  69. package/gsd-core/bin/lib/workstream.cjs +4 -4
  70. package/gsd-core/bin/shared/config-defaults.manifest.json +3 -0
  71. package/gsd-core/bin/shared/config-schema.manifest.json +11 -1
  72. package/gsd-core/references/honest-verifier.md +105 -0
  73. package/gsd-core/references/reviewer-instances.md +99 -0
  74. package/gsd-core/references/untrusted-input-boundary.md +13 -0
  75. package/gsd-core/workflows/autonomous.md +61 -54
  76. package/gsd-core/workflows/complete-milestone.md +27 -8
  77. package/gsd-core/workflows/execute-phase.md +1 -1
  78. package/gsd-core/workflows/manager.md +30 -20
  79. package/gsd-core/workflows/new-project.md +78 -12
  80. package/gsd-core/workflows/plan-phase.md +1 -1
  81. package/gsd-core/workflows/profile-user.md +6 -2
  82. package/gsd-core/workflows/progress.md +37 -4
  83. package/gsd-core/workflows/quick.md +3 -1
  84. package/gsd-core/workflows/review.md +26 -0
  85. package/gsd-core/workflows/ship.md +3 -1
  86. package/gsd-core/workflows/spec-phase.md +3 -1
  87. package/gsd-core/workflows/thread.md +4 -4
  88. package/gsd-core/workflows/transition.md +14 -12
  89. package/gsd-core/workflows/ui-review.md +2 -6
  90. package/gsd-core/workflows/verify-phase.md +11 -4
  91. package/gsd-core/workflows/verify-work.md +44 -0
  92. package/hooks/dist/gsd-graphify-update.sh +7 -1
  93. package/hooks/dist/gsd-read-injection-scanner.js +49 -25
  94. package/hooks/gsd-graphify-update.sh +7 -1
  95. package/hooks/gsd-read-injection-scanner.js +49 -25
  96. package/hooks/hooks.json +1 -1
  97. package/package.json +4 -4
  98. package/scripts/check-alias-drift.cjs +5 -0
  99. package/scripts/ci-test-scope.cjs +38 -9
  100. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -1
  101. package/scripts/lint-regression-test-names.allowlist.json +3 -0
  102. package/scripts/lint-test-file-count.allowlist.json +19 -5
  103. package/scripts/mutation-matrix.cjs +45 -3
  104. package/scripts/prompt-injection-scan.sh +13 -0
  105. package/scripts/lint-windows-test-portability.cjs +0 -178
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gsd-core",
3
3
  "displayName": "GSD Core",
4
- "version": "1.6.0-rc.3",
4
+ "version": "1.7.0-rc.1",
5
5
  "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
6
6
  "author": {
7
7
  "name": "open-gsd",
@@ -17,6 +17,8 @@ Spawned by `discuss-phase` via `Task()`. You do NOT present output directly to t
17
17
  - Return structured markdown output for the main agent to synthesize
18
18
  </role>
19
19
 
20
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
21
+
20
22
  <documentation_lookup>
21
23
  @~/.claude/gsd-core/references/research-documentation-lookup.md
22
24
  </documentation_lookup>
@@ -16,6 +16,8 @@ You are a GSD AI researcher. Answer: "How do I correctly implement this AI syste
16
16
  Write Sections 3–4b of AI-SPEC.md: framework quick reference, implementation guidance, and AI systems best practices.
17
17
  </role>
18
18
 
19
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
20
+
19
21
  <documentation_lookup>
20
22
  @~/.claude/gsd-core/references/research-documentation-lookup.md
21
23
  </documentation_lookup>
@@ -18,6 +18,8 @@ Spawned by `discuss-phase-assumptions` via `Task()`. You do NOT present output d
18
18
  - Flag topics where codebase analysis alone is insufficient (needs external research)
19
19
  </role>
20
20
 
21
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
22
+
21
23
  <input>
22
24
  Agent receives via prompt:
23
25
 
@@ -18,6 +18,8 @@ You are a GSD doc classifier. You read ONE document and write a structured class
18
18
  If the prompt contains a `<required_reading>` block, use the `Read` tool to load every file listed there before doing anything else. That is your primary context.
19
19
  </role>
20
20
 
21
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
22
+
21
23
  <why_this_matters>
22
24
  Your classification drives extraction. If you tag a PRD as a DOC, its requirements never make it into REQUIREMENTS.md. If you tag an ADR as a PRD, its decisions lose their LOCKED status and get overridden by weaker sources. Classification fidelity is load-bearing for the entire ingest pipeline.
23
25
  </why_this_matters>
@@ -20,6 +20,8 @@ You do NOT prompt the user. You do NOT write PROJECT.md, REQUIREMENTS.md, or ROA
20
20
  If the prompt contains a `<required_reading>` block, load every file listed there first — especially `references/doc-conflict-engine.md` which defines your conflict report format.
21
21
  </role>
22
22
 
23
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
24
+
23
25
  <why_this_matters>
24
26
  You are the precedence-enforcing layer. Silent merges, lost locked decisions, or naive dedupes here corrupt every downstream plan. When in doubt, surface the conflict rather than pick.
25
27
  </why_this_matters>
@@ -16,6 +16,8 @@ You are a GSD domain researcher. Answer: "What do domain experts actually care a
16
16
  Research the business domain — not the technical framework. Write Section 1b of AI-SPEC.md.
17
17
  </role>
18
18
 
19
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
20
+
19
21
  <documentation_lookup>
20
22
  @~/.claude/gsd-core/references/research-documentation-lookup.md
21
23
  </documentation_lookup>
@@ -109,17 +109,14 @@ Score 5 components (ok / partial / missing):
109
109
  </step>
110
110
 
111
111
  <step name="calculate_scores">
112
- ```
113
- coverage_score = covered_count / total_dimensions × 100
114
- infra_score = (tooling + dataset + cicd + guardrails + tracing) / 5 × 100
115
- overall_score = (coverage_score × 0.6) + (infra_score × 0.4)
112
+ Do NOT compute scores by hand. Call the deterministic verb with your audited inputs:
113
+
114
+ ```bash
115
+ _GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
116
+ gsd_run query eval.score --covered <covered_count> --total <total_dimensions> --infra <tooling>,<dataset>,<cicd>,<guardrails>,<tracing> --raw
116
117
  ```
117
118
 
118
- Verdict:
119
- - 80-100: **PRODUCTION READY** — deploy with monitoring
120
- - 60-79: **NEEDS WORK** — address CRITICAL gaps before production
121
- - 40-59: **SIGNIFICANT GAPS** — do not deploy
122
- - 0-39: **NOT IMPLEMENTED** — review AI-SPEC.md and implement
119
+ where each infra component is `ok`, `partial`, or `missing` (from the audit_infrastructure step). Parse the JSON result — it returns `coverage_score`, `infra_score`, `overall_score`, and `verdict` (PRODUCTION READY / NEEDS WORK / SIGNIFICANT GAPS / NOT IMPLEMENTED). Use those values verbatim in EVAL-REVIEW.md; never recompute or override them.
123
120
  </step>
124
121
 
125
122
  <step name="write_eval_review">
@@ -35,6 +35,8 @@ Spawned by `/gsd:plan-phase` (integrated) or `/gsd:plan-phase --research-phase <
35
35
  Claims tagged `[ASSUMED]` signal to the planner and discuss-phase that the information needs user confirmation before becoming a locked decision. Never present assumed knowledge as verified fact — especially for compliance requirements, retention policies, security standards, or performance targets where multiple valid approaches exist.
36
36
  </role>
37
37
 
38
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
39
+
38
40
  <documentation_lookup>
39
41
  @~/.claude/gsd-core/references/research-documentation-lookup.md
40
42
  </documentation_lookup>
@@ -32,6 +32,8 @@ Your files feed the roadmap:
32
32
  **Be comprehensive but opinionated.** "Use X because Y" not "Options are X, Y, Z."
33
33
  </role>
34
34
 
35
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
36
+
35
37
  <documentation_lookup>
36
38
  @~/.claude/gsd-core/references/research-documentation-lookup.md
37
39
  </documentation_lookup>
@@ -32,6 +32,8 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
32
32
  - Commit ALL research files (researchers write but don't commit — you commit everything)
33
33
  </role>
34
34
 
35
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
36
+
35
37
  <downstream_consumer>
36
38
  Your SUMMARY.md is consumed by the gsd-roadmapper agent which uses it to:
37
39
 
@@ -27,6 +27,8 @@ If the prompt contains a `<required_reading>` block, you MUST use the `Read` too
27
27
  - Return structured result to orchestrator
28
28
  </role>
29
29
 
30
+ @~/.claude/gsd-core/references/untrusted-input-boundary.md
31
+
30
32
  <documentation_lookup>
31
33
  @~/.claude/gsd-core/references/research-documentation-lookup.md
32
34
  </documentation_lookup>
@@ -197,6 +197,7 @@ For each truth:
197
197
  - A pre-existing test exercises the transition/invariant and passes (confirm via Step 7b's single-named-test path) → ✓ VERIFIED.
198
198
  - No such test exists, or it can't run without a server/state mutation → ⚠️ PRESENT_BEHAVIOR_UNVERIFIED. Emit a human-verification item (Step 8) and do not count it toward the verified score (Step 9).
199
199
  - An accepted override (Step 3b) carries the truth as PASSED (override), exactly as it does for a FAILED truth.
200
+ 5b. **Non-inferable (`backstop`) truths:** a `verification: backstop` truth (via `truthVerification()`) abstains unless confirmed by explicit evidence — mark `insufficient_spec` -> a human-verification item -> `human_needed`. See `references/honest-verifier.md`.
200
201
  6. Determine truth status
201
202
 
202
203
  ## Step 3b: Check Verification Overrides
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /**
4
+ * gsd-mcp-server — companion MCP server bin entry (ADR-1239 Phase C-2 / #1681).
5
+ *
6
+ * Lives at top-level bin/ (alongside install.js) — it is a PACKAGE bin the host
7
+ * spawns via `npx gsd-mcp-server` (or the global bin), NOT a per-runtime
8
+ * artifact copied into a host's config dir. (Placing it under gsd-core/bin/
9
+ * would leak it into every runtime install + break golden parity.)
10
+ *
11
+ * A stdio JSON-RPC 2.0 server exposing GSD interface points 1 (command) + 5
12
+ * (state IO) so any MCP-consuming host (Claude/Codex/OpenCode/VS Code/Gemini/
13
+ * Cursor/Cline/Hermes) can drive GSD with no bespoke plugin. Delegates to the
14
+ * tested server module (gsd-core/bin/lib/mcp-server.cjs runServer). Reads
15
+ * line-delimited JSON-RPC from stdin, writes one response + newline per
16
+ * request, exits cleanly when stdin closes.
17
+ *
18
+ * The protocol logic (handleMessage) + the injectable-stream loop (runServer)
19
+ * are unit-tested in tests/gsd-mcp-server.test.cjs; the process lifecycle
20
+ * (spawn → JSON-RPC → clean exit) in tests/gsd-mcp-server-bin.test.cjs.
21
+ */
22
+ const { runServer } = require('../gsd-core/bin/lib/mcp-server.cjs');
23
+
24
+ runServer({
25
+ input: process.stdin,
26
+ output: process.stdout,
27
+ ctx: { cwd: process.cwd() },
28
+ }).catch((err) => {
29
+ process.stderr.write(String((err && err.message) || err) + '\n');
30
+ process.exit(1);
31
+ });