@specship/specship-win32-arm64 0.23.0 → 0.25.0

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 (143) hide show
  1. package/lib/dist/activation/steering.d.ts +4 -4
  2. package/lib/dist/activation/steering.d.ts.map +1 -1
  3. package/lib/dist/activation/steering.js +6 -6
  4. package/lib/dist/activation/steering.js.map +1 -1
  5. package/lib/dist/bin/specship.js +277 -40
  6. package/lib/dist/bin/specship.js.map +1 -1
  7. package/lib/dist/commands/specship/learn.md +5 -3
  8. package/lib/dist/commands/specship/spec.md +73 -15
  9. package/lib/dist/db/spec-queries.d.ts +73 -3
  10. package/lib/dist/db/spec-queries.d.ts.map +1 -1
  11. package/lib/dist/db/spec-queries.js +139 -5
  12. package/lib/dist/db/spec-queries.js.map +1 -1
  13. package/lib/dist/diagram/flow-diagram.d.ts +86 -0
  14. package/lib/dist/diagram/flow-diagram.d.ts.map +1 -0
  15. package/lib/dist/diagram/flow-diagram.js +0 -0
  16. package/lib/dist/diagram/flow-diagram.js.map +1 -0
  17. package/lib/dist/enforce/changed-files.d.ts +28 -0
  18. package/lib/dist/enforce/changed-files.d.ts.map +1 -0
  19. package/lib/dist/enforce/changed-files.js +72 -0
  20. package/lib/dist/enforce/changed-files.js.map +1 -0
  21. package/lib/dist/enforce/enforce.d.ts +28 -1
  22. package/lib/dist/enforce/enforce.d.ts.map +1 -1
  23. package/lib/dist/enforce/enforce.js +37 -5
  24. package/lib/dist/enforce/enforce.js.map +1 -1
  25. package/lib/dist/extraction/grammars.d.ts +10 -0
  26. package/lib/dist/extraction/grammars.d.ts.map +1 -1
  27. package/lib/dist/extraction/grammars.js +32 -3
  28. package/lib/dist/extraction/grammars.js.map +1 -1
  29. package/lib/dist/extraction/index.d.ts +7 -0
  30. package/lib/dist/extraction/index.d.ts.map +1 -1
  31. package/lib/dist/extraction/index.js.map +1 -1
  32. package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts +7 -0
  33. package/lib/dist/extraction/specs/markdown-spec-extractor.d.ts.map +1 -1
  34. package/lib/dist/extraction/specs/markdown-spec-extractor.js +81 -8
  35. package/lib/dist/extraction/specs/markdown-spec-extractor.js.map +1 -1
  36. package/lib/dist/extraction/wasm/tree-sitter-pascal.wasm.gz +0 -0
  37. package/lib/dist/extraction/wasm/tree-sitter-scala.wasm.gz +0 -0
  38. package/lib/dist/graph/spec-coverage.d.ts +86 -0
  39. package/lib/dist/graph/spec-coverage.d.ts.map +1 -0
  40. package/lib/dist/graph/spec-coverage.js +152 -0
  41. package/lib/dist/graph/spec-coverage.js.map +1 -0
  42. package/lib/dist/index.d.ts +81 -6
  43. package/lib/dist/index.d.ts.map +1 -1
  44. package/lib/dist/index.js +178 -21
  45. package/lib/dist/index.js.map +1 -1
  46. package/lib/dist/installer/index.d.ts +33 -8
  47. package/lib/dist/installer/index.d.ts.map +1 -1
  48. package/lib/dist/installer/index.js +50 -50
  49. package/lib/dist/installer/index.js.map +1 -1
  50. package/lib/dist/installer/init-offer.d.ts +14 -9
  51. package/lib/dist/installer/init-offer.d.ts.map +1 -1
  52. package/lib/dist/installer/init-offer.js +13 -9
  53. package/lib/dist/installer/init-offer.js.map +1 -1
  54. package/lib/dist/installer/install-defaults.d.ts +62 -0
  55. package/lib/dist/installer/install-defaults.d.ts.map +1 -0
  56. package/lib/dist/installer/install-defaults.js +67 -0
  57. package/lib/dist/installer/install-defaults.js.map +1 -0
  58. package/lib/dist/installer/targets/claude.d.ts +14 -0
  59. package/lib/dist/installer/targets/claude.d.ts.map +1 -1
  60. package/lib/dist/installer/targets/claude.js +64 -0
  61. package/lib/dist/installer/targets/claude.js.map +1 -1
  62. package/lib/dist/installer/targets/shared.js +4 -4
  63. package/lib/dist/installer/targets/shared.js.map +1 -1
  64. package/lib/dist/mcp/fitness-tool.d.ts +5 -6
  65. package/lib/dist/mcp/fitness-tool.d.ts.map +1 -1
  66. package/lib/dist/mcp/fitness-tool.js +0 -16
  67. package/lib/dist/mcp/fitness-tool.js.map +1 -1
  68. package/lib/dist/mcp/health-tool.d.ts +26 -0
  69. package/lib/dist/mcp/health-tool.d.ts.map +1 -0
  70. package/lib/dist/mcp/health-tool.js +50 -0
  71. package/lib/dist/mcp/health-tool.js.map +1 -0
  72. package/lib/dist/mcp/maintainability-tool.d.ts +5 -7
  73. package/lib/dist/mcp/maintainability-tool.d.ts.map +1 -1
  74. package/lib/dist/mcp/maintainability-tool.js +0 -16
  75. package/lib/dist/mcp/maintainability-tool.js.map +1 -1
  76. package/lib/dist/mcp/model-context.d.ts +13 -2
  77. package/lib/dist/mcp/model-context.d.ts.map +1 -1
  78. package/lib/dist/mcp/model-context.js +39 -12
  79. package/lib/dist/mcp/model-context.js.map +1 -1
  80. package/lib/dist/mcp/proxy.d.ts.map +1 -1
  81. package/lib/dist/mcp/proxy.js +4 -1
  82. package/lib/dist/mcp/proxy.js.map +1 -1
  83. package/lib/dist/mcp/server-instructions.d.ts +1 -1
  84. package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
  85. package/lib/dist/mcp/server-instructions.js +5 -4
  86. package/lib/dist/mcp/server-instructions.js.map +1 -1
  87. package/lib/dist/mcp/spec-tools.d.ts.map +1 -1
  88. package/lib/dist/mcp/spec-tools.js +213 -28
  89. package/lib/dist/mcp/spec-tools.js.map +1 -1
  90. package/lib/dist/mcp/tools.d.ts +12 -8
  91. package/lib/dist/mcp/tools.d.ts.map +1 -1
  92. package/lib/dist/mcp/tools.js +89 -48
  93. package/lib/dist/mcp/tools.js.map +1 -1
  94. package/lib/dist/resolution/spec-link-resolver.d.ts +44 -2
  95. package/lib/dist/resolution/spec-link-resolver.d.ts.map +1 -1
  96. package/lib/dist/resolution/spec-link-resolver.js +132 -0
  97. package/lib/dist/resolution/spec-link-resolver.js.map +1 -1
  98. package/lib/dist/resolution/test-title-links.d.ts +62 -0
  99. package/lib/dist/resolution/test-title-links.d.ts.map +1 -0
  100. package/lib/dist/resolution/test-title-links.js +108 -0
  101. package/lib/dist/resolution/test-title-links.js.map +1 -0
  102. package/lib/dist/search/query-parser.d.ts.map +1 -1
  103. package/lib/dist/search/query-parser.js +6 -1
  104. package/lib/dist/search/query-parser.js.map +1 -1
  105. package/lib/dist/server/project-registry.js +1 -1
  106. package/lib/dist/server/routes/claude.js +9 -36
  107. package/lib/dist/server/routes/graph.js +53 -7
  108. package/lib/dist/server/routes/mcp.js +4 -3
  109. package/lib/dist/server/routes/projects.js +4 -4
  110. package/lib/dist/server/routes/spec.js +49 -7
  111. package/lib/dist/server/server.js +29 -17
  112. package/lib/dist/skills/spec-author/SKILL.md +164 -0
  113. package/lib/dist/skills/spec-author/references/format.md +210 -0
  114. package/lib/dist/skills/spec-author/references/gap-questions.md +152 -0
  115. package/lib/dist/skills/spec-author/references/quality-rubric.md +125 -0
  116. package/lib/dist/skills/spec-author/references/review-checklist.md +175 -0
  117. package/lib/dist/spec-lint/lint.d.ts +82 -0
  118. package/lib/dist/spec-lint/lint.d.ts.map +1 -0
  119. package/lib/dist/spec-lint/lint.js +430 -0
  120. package/lib/dist/spec-lint/lint.js.map +1 -0
  121. package/lib/dist/statusline/index.js.map +1 -1
  122. package/lib/dist/statusline/render.d.ts +1 -1
  123. package/lib/dist/statusline/render.d.ts.map +1 -1
  124. package/lib/dist/statusline/render.js +3 -1
  125. package/lib/dist/statusline/render.js.map +1 -1
  126. package/lib/dist/ui/assets/index-BzuUWUAE.js +50 -0
  127. package/lib/dist/ui/index.html +1 -1
  128. package/lib/dist/verify/report-ingest.d.ts +88 -0
  129. package/lib/dist/verify/report-ingest.d.ts.map +1 -0
  130. package/lib/dist/verify/report-ingest.js +269 -0
  131. package/lib/dist/verify/report-ingest.js.map +1 -0
  132. package/lib/dist/workflows/defaults/spec-fix.yaml +103 -12
  133. package/lib/dist/workflows/defaults/spec-implement-mixed.yaml +264 -21
  134. package/lib/dist/workflows/defaults/spec-implement.yaml +260 -19
  135. package/lib/dist/workflows/defaults/spec-verify.yaml +60 -9
  136. package/lib/node_modules/.package-lock.json +1 -1
  137. package/lib/package.json +7 -3
  138. package/package.json +1 -1
  139. package/lib/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  140. package/lib/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
  141. package/lib/dist/server/ingest/impact-query.js +0 -343
  142. package/lib/dist/server/routes/events.js +0 -152
  143. package/lib/dist/ui/assets/index-CjjaftDw.js +0 -50
@@ -15,6 +15,7 @@ exports.formatStaleFooter = formatStaleFooter;
15
15
  exports.integrationEnabled = integrationEnabled;
16
16
  exports.toolIntegration = toolIntegration;
17
17
  exports.filterIntegrationTools = filterIntegrationTools;
18
+ exports.applyLiteTierTrim = applyLiteTierTrim;
18
19
  exports.getStaticTools = getStaticTools;
19
20
  const directory_1 = require("../directory");
20
21
  const statusline_1 = require("../statusline");
@@ -411,6 +412,7 @@ const projectPathProperty = {
411
412
  const spec_tools_1 = require("./spec-tools");
412
413
  const maintainability_tool_1 = require("./maintainability-tool");
413
414
  const fitness_tool_1 = require("./fitness-tool");
415
+ const health_tool_1 = require("./health-tool");
414
416
  const designer_tools_1 = require("./designer-tools");
415
417
  const jira_tools_1 = require("./jira-tools");
416
418
  exports.tools = [
@@ -549,7 +551,7 @@ exports.tools = [
549
551
  },
550
552
  {
551
553
  name: 'specship_status',
552
- description: 'Index health check (files / nodes / edges). Skip unless debugging.',
554
+ description: 'Index health check (files / nodes / edges) AND server identity — package version, install method (bundle/npm/unknown), the install serving this session, and node version. Works with no project open (identity only). Skip unless debugging or asked which SpecShip is running.',
553
555
  inputSchema: {
554
556
  type: 'object',
555
557
  properties: {
@@ -557,14 +559,6 @@ exports.tools = [
557
559
  },
558
560
  },
559
561
  },
560
- {
561
- name: 'specship_version',
562
- description: 'Identify the running SpecShip MCP server: package version, install method (bundle/npm/unknown), install dir, node version, and project root (if bound). Zero-arg, no index required — safe to call before any project is open.',
563
- inputSchema: {
564
- type: 'object',
565
- properties: {},
566
- },
567
- },
568
562
  {
569
563
  name: 'specship_files',
570
564
  description: 'Indexed file tree with language + symbol counts. Faster than Glob for project layout.',
@@ -600,8 +594,10 @@ exports.tools = [
600
594
  },
601
595
  // Spec-layer tools (v5): see ./spec-tools.ts for handlers.
602
596
  ...spec_tools_1.specToolDefinitions,
603
- ...maintainability_tool_1.maintainabilityToolDefinitions,
604
- ...fitness_tool_1.fitnessToolDefinitions,
597
+ // Code health: one tool for maintainability + architecture fitness
598
+ // (REQ-SURF-007). The two former tools still execute for clients holding a
599
+ // cached list, but they are off the menu.
600
+ ...health_tool_1.healthToolDefinitions,
605
601
  // Designer tools: claude.ai/design driving, vendored from @pro-vi/designer.
606
602
  // See ./designer-tools.ts for handlers. Drives a debug Chrome over CDP.
607
603
  ...designer_tools_1.designerToolDefinitions,
@@ -629,19 +625,54 @@ function filterIntegrationTools(list, env = process.env) {
629
625
  return integ === null || integrationEnabled(integ, env);
630
626
  });
631
627
  }
628
+ /**
629
+ * Lite-tier menu trim (LOWMODEL-DOC, REQ-LOWMODEL-004): small-model tool
630
+ * choice degrades with menu size, so the code-graph group trims to the core
631
+ * three; spec/link tools and enabled integrations are untouched. Composes
632
+ * with the tiny-repo gate and SPECSHIP_MCP_TOOLS as an intersection.
633
+ * Schemas never vary — only the list; `execute()` still answers a
634
+ * trimmed-away tool for clients that cached the full list (A2).
635
+ *
636
+ * Needs only a project-root hint, NOT an open DB — tier detection reads the
637
+ * session model marker file. That is what lets the proxy's connect-time
638
+ * static list trim too (A4); `hint` may be any path at or under the project
639
+ * (the nearest `.specship/` root wins).
640
+ */
641
+ const LITE_CORE_TOOLS = new Set(['specship_explore', 'specship_search', 'specship_node']);
642
+ // `specship_status` is deliberately NOT in this group (REQ-SURF-006.A2): it
643
+ // carries the server-identity answer, so the lite tier must keep it.
644
+ const CODE_GRAPH_GROUP = new Set([
645
+ 'specship_explore', 'specship_search', 'specship_node',
646
+ 'specship_callers', 'specship_callees', 'specship_impact',
647
+ 'specship_files',
648
+ 'specship_health',
649
+ ]);
650
+ function applyLiteTierTrim(list, hint) {
651
+ if (!hint)
652
+ return list;
653
+ const root = (0, directory_1.findNearestSpecShipRoot)(hint);
654
+ if (!root || (0, model_context_1.detectModelTier)(root) !== 'lite')
655
+ return list;
656
+ return list.filter(t => !CODE_GRAPH_GROUP.has(t.name) || LITE_CORE_TOOLS.has(t.name));
657
+ }
632
658
  /**
633
659
  * Allowlist-filtered tool definitions WITHOUT an engine — the static surface the
634
660
  * proxy answers `tools/list` with before any project is open. Mirrors
635
661
  * `ToolHandler.getTools()` in the no-SpecShip case (the dynamic per-repo budget
636
662
  * note in a description only adds once `cg` is loaded; the schemas are static).
663
+ * When a project-root hint is given, the lite-tier trim applies here too
664
+ * (REQ-LOWMODEL-004.A4) — the marker file needs no DB open.
637
665
  */
638
- function getStaticTools() {
666
+ function getStaticTools(projectRootHint) {
639
667
  const base = filterIntegrationTools(exports.tools);
640
668
  const raw = process.env.SPECSHIP_MCP_TOOLS;
641
- if (!raw || !raw.trim())
642
- return base;
643
- const allow = new Set(raw.split(',').map(s => s.trim().replace(/^specship_/, '')).filter(Boolean));
644
- return allow.size ? base.filter(t => allow.has(t.name.replace(/^specship_/, ''))) : base;
669
+ let visible = base;
670
+ if (raw && raw.trim()) {
671
+ const allow = new Set(raw.split(',').map(s => s.trim().replace(/^specship_/, '')).filter(Boolean));
672
+ if (allow.size)
673
+ visible = base.filter(t => allow.has(t.name.replace(/^specship_/, '')));
674
+ }
675
+ return applyLiteTierTrim(visible, projectRootHint ?? null);
645
676
  }
646
677
  /**
647
678
  * Tool handler that executes tools against a SpecShip instance
@@ -772,29 +803,18 @@ class ToolHandler {
772
803
  'specship_explore',
773
804
  'specship_search',
774
805
  'specship_node',
775
- 'specship_version',
806
+ // Identity probe — folded into status (REQ-SURF-006), which therefore
807
+ // survives the tiny-repo trim the way specship_version used to.
808
+ 'specship_status',
776
809
  ]);
777
810
  if (stats.fileCount < TINY_REPO_FILE_THRESHOLD) {
778
811
  // Designer tools are not code-graph tools — the tiny-repo flow-question
779
812
  // economics that justify trimming don't apply, so they always survive.
780
813
  visible = visible.filter(t => TINY_REPO_CORE_TOOLS.has(t.name) || t.name.startsWith('designer_'));
781
814
  }
782
- // Haiku-tier menu trim (LOWMODEL-DOC, REQ-LOWMODEL-004): small-model
783
- // tool choice degrades with menu size, so the code-graph group trims
784
- // to the core three; spec/link tools and enabled integrations are
785
- // untouched. Composes with the tiny-repo gate as an intersection.
786
- // Schemas never vary — only the list; `execute()` still answers a
787
- // trimmed-away tool for clients that cached the full list (A2).
788
- if ((0, model_context_1.detectModelTier)(this.cg.getProjectRoot()) === 'haiku') {
789
- const HAIKU_CORE = new Set(['specship_explore', 'specship_search', 'specship_node']);
790
- const CODE_GRAPH_GROUP = new Set([
791
- 'specship_explore', 'specship_search', 'specship_node',
792
- 'specship_callers', 'specship_callees', 'specship_impact',
793
- 'specship_files', 'specship_status',
794
- 'specship_maintainability', 'specship_fitness',
795
- ]);
796
- visible = visible.filter(t => !CODE_GRAPH_GROUP.has(t.name) || HAIKU_CORE.has(t.name));
797
- }
815
+ // Lite-tier menu trim — shared with the proxy's static list (A4);
816
+ // see applyLiteTierTrim above for the full contract.
817
+ visible = applyLiteTierTrim(visible, this.cg.getProjectRoot());
798
818
  return visible.map(tool => {
799
819
  if (tool.name === 'specship_explore') {
800
820
  return {
@@ -982,11 +1002,11 @@ class ToolHandler {
982
1002
  /**
983
1003
  * Model-aware compaction (MODCTX-DOC, REQ-MODCTX-002/003). Resolves the
984
1004
  * session's model tier (status-line marker / SPECSHIP_MODEL; SPECSHIP_COMPACT=0
985
- * disables) and, on haiku/sonnet, compresses the response's prose
1005
+ * disables) and, on the lite/standard tiers, compresses the response's prose
986
1006
  * scaffolding — fenced code stays byte-verbatim. Full tier is identity.
987
1007
  */
988
1008
  /**
989
- * Tier-change listeners (LOWMODEL-DOC, REQ-LOWMODEL-004.A3): the haiku
1009
+ * Tier-change listeners (LOWMODEL-DOC, REQ-LOWMODEL-004.A3): the lite-tier
990
1010
  * menu trim changes `tools/list`, so a mid-session /model switch must ride
991
1011
  * an MCP `notifications/tools/list_changed`. Sessions subscribe here; the
992
1012
  * change is detected on the next code-graph call (the same funnel that
@@ -1166,11 +1186,13 @@ class ToolHandler {
1166
1186
  // its own verbose worktree warning but still flows through the
1167
1187
  // staleness wrapper so its pending-files section stays consistent
1168
1188
  // with what the read tools surface.
1169
- // specship_version (REQ-MCPVER-001): zero-arg identity probe. Answered
1170
- // before the worktree/staleness/compaction wrappers so it works with no
1171
- // project open and never touches the DB.
1189
+ // specship_version (REQ-MCPVER-001): zero-arg identity probe, folded into
1190
+ // specship_status (REQ-SURF-006) and off the menu. Still answered here for
1191
+ // clients holding a cached tool list. Runs before the
1192
+ // worktree/staleness/compaction wrappers so it works with no project open
1193
+ // and never touches the DB.
1172
1194
  if (toolName === 'specship_version') {
1173
- return this.handleVersion();
1195
+ return this.textResult(this.identityBlock());
1174
1196
  }
1175
1197
  let result;
1176
1198
  switch (toolName) {
@@ -1212,6 +1234,11 @@ class ToolHandler {
1212
1234
  case 'specship_drifted':
1213
1235
  result = await (0, spec_tools_1.handleSpecshipDrifted)(this.getSpecShip(args.projectPath), args);
1214
1236
  break;
1237
+ case 'specship_health':
1238
+ result = await (0, health_tool_1.handleSpecshipHealth)(this.getSpecShip(args.projectPath), args);
1239
+ break;
1240
+ // Folded into specship_health (REQ-SURF-007) and off the menu; still
1241
+ // answered for clients holding a cached tool list.
1215
1242
  case 'specship_maintainability':
1216
1243
  result = await (0, maintainability_tool_1.handleSpecshipMaintainability)(this.getSpecShip(args.projectPath), args);
1217
1244
  break;
@@ -1336,7 +1363,7 @@ class ToolHandler {
1336
1363
  }
1337
1364
  const withWorktree = this.withWorktreeNotice(result, args.projectPath);
1338
1365
  const withStaleness = this.withStalenessNotice(withWorktree, args.projectPath);
1339
- // Model-aware compaction (MODCTX-DOC): on haiku/sonnet sessions the
1366
+ // Model-aware compaction (MODCTX-DOC): on lite/standard sessions the
1340
1367
  // prose scaffolding compresses; code stays byte-verbatim. Only the
1341
1368
  // code-graph tools reach this funnel — designer/jira returned above
1342
1369
  // (REQ-MODCTX-004).
@@ -1765,7 +1792,7 @@ class ToolHandler {
1765
1792
  out.push('## Flow (call path among the symbols you queried)', '');
1766
1793
  for (let i = 0; i < best.length; i++) {
1767
1794
  const step = best[i];
1768
- if (tier === 'haiku') {
1795
+ if (tier === 'lite') {
1769
1796
  // LOWMODEL-DOC REQ-LOWMODEL-003: small models don't synthesize
1770
1797
  // the flow from evidence — render each hop as ONE explicit line
1771
1798
  // with its mechanism inline. Additive formatting only; the code
@@ -3232,12 +3259,13 @@ class ToolHandler {
3232
3259
  return lines.join('\n');
3233
3260
  }
3234
3261
  /**
3235
- * Handle specship_version (REQ-MCPVER-001). Identifies the running MCP
3236
- * server process — the version an agent's tools are being served by,
3237
- * how it was installed, node version, and (if bound) the project root.
3238
- * Zero-arg, synchronous, never touches the DB, safe with no project.
3262
+ * Server identity (REQ-MCPVER-001, folded into specship_status by
3263
+ * REQ-SURF-006). Identifies the running MCP server process — the version an
3264
+ * agent's tools are being served by, how it was installed, node version, and
3265
+ * (if bound) the project root. Synchronous, never touches the DB, safe with
3266
+ * no project open.
3239
3267
  */
3240
- handleVersion() {
3268
+ identityBlock() {
3241
3269
  const binDirname = (0, path_1.dirname)(__filename);
3242
3270
  const installDir = (0, updater_1.resolveInstallDir)();
3243
3271
  const installMethod = (0, updater_1.detectInstallMethod)(binDirname, installDir);
@@ -3265,13 +3293,24 @@ class ToolHandler {
3265
3293
  `**node:** ${process.version}`,
3266
3294
  `**projectRoot:** ${projectRoot ?? 'null'}`,
3267
3295
  ];
3268
- return this.textResult(lines.join('\n'));
3296
+ return lines.join('\n');
3269
3297
  }
3270
3298
  /**
3271
3299
  * Handle specship_status
3272
3300
  */
3273
3301
  async handleStatus(args) {
3274
- let cg = this.getSpecShip(args.projectPath);
3302
+ // Server identity leads the response (REQ-SURF-006.A1) and is answerable
3303
+ // with no project open, so a status call on an unindexed directory still
3304
+ // tells the agent which SpecShip is serving it.
3305
+ const identity = this.identityBlock();
3306
+ let cg;
3307
+ try {
3308
+ cg = this.getSpecShip(args.projectPath);
3309
+ }
3310
+ catch (err) {
3311
+ const detail = err instanceof Error ? err.message : String(err);
3312
+ return this.textResult(`${identity}\n\n## SpecShip Status\n\n${detail}`);
3313
+ }
3275
3314
  // Same trick as withStalenessNotice — when an explicit projectPath
3276
3315
  // resolves to the same project as the default session cg, prefer the
3277
3316
  // default so getPendingFiles() (only populated by the default's watcher)
@@ -3292,6 +3331,8 @@ class ToolHandler {
3292
3331
  // one-liner via withWorktreeNotice. Both share the cached detection.
3293
3332
  const mismatch = this.worktreeMismatchFor(args.projectPath);
3294
3333
  const lines = [
3334
+ identity,
3335
+ '',
3295
3336
  '## SpecShip Status',
3296
3337
  '',
3297
3338
  ];