@specship/specship-darwin-arm64 0.29.0 → 0.30.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 (289) hide show
  1. package/bin/specship +1 -1
  2. package/lib/dist/.claude-plugin/plugin.json +15 -3
  3. package/lib/dist/activation/cheatsheet.d.ts +10 -7
  4. package/lib/dist/activation/cheatsheet.d.ts.map +1 -1
  5. package/lib/dist/activation/cheatsheet.js +21 -5
  6. package/lib/dist/activation/cheatsheet.js.map +1 -1
  7. package/lib/dist/activation/hook-output.d.ts +75 -2
  8. package/lib/dist/activation/hook-output.d.ts.map +1 -1
  9. package/lib/dist/activation/hook-output.js +114 -3
  10. package/lib/dist/activation/hook-output.js.map +1 -1
  11. package/lib/dist/activation/search-intercept.d.ts +20 -7
  12. package/lib/dist/activation/search-intercept.d.ts.map +1 -1
  13. package/lib/dist/activation/search-intercept.js +27 -5
  14. package/lib/dist/activation/search-intercept.js.map +1 -1
  15. package/lib/dist/activation/steering.d.ts +7 -4
  16. package/lib/dist/activation/steering.d.ts.map +1 -1
  17. package/lib/dist/activation/steering.js +10 -8
  18. package/lib/dist/activation/steering.js.map +1 -1
  19. package/lib/dist/agents/detect.d.ts +32 -0
  20. package/lib/dist/agents/detect.d.ts.map +1 -0
  21. package/lib/dist/agents/detect.js +54 -0
  22. package/lib/dist/agents/detect.js.map +1 -0
  23. package/lib/dist/agents/recent-project.d.ts +18 -0
  24. package/lib/dist/agents/recent-project.d.ts.map +1 -0
  25. package/lib/dist/agents/recent-project.js +92 -0
  26. package/lib/dist/agents/recent-project.js.map +1 -0
  27. package/lib/dist/analytics/canonical-tools.d.ts +23 -0
  28. package/lib/dist/analytics/canonical-tools.d.ts.map +1 -0
  29. package/lib/dist/analytics/canonical-tools.js +36 -0
  30. package/lib/dist/analytics/canonical-tools.js.map +1 -0
  31. package/lib/dist/analytics/canonical-tools.json +16 -0
  32. package/lib/dist/analytics/specship-impact.d.ts +3 -2
  33. package/lib/dist/analytics/specship-impact.d.ts.map +1 -1
  34. package/lib/dist/analytics/specship-impact.js +6 -4
  35. package/lib/dist/analytics/specship-impact.js.map +1 -1
  36. package/lib/dist/bin/specship.js +215 -170
  37. package/lib/dist/bin/specship.js.map +1 -1
  38. package/lib/dist/bin/uninstall.js +2 -2
  39. package/lib/dist/bin/uninstall.js.map +1 -1
  40. package/lib/dist/claudemd/audit.d.ts +12 -3
  41. package/lib/dist/claudemd/audit.d.ts.map +1 -1
  42. package/lib/dist/claudemd/audit.js +65 -22
  43. package/lib/dist/claudemd/audit.js.map +1 -1
  44. package/lib/dist/commands/specship/spec.md +9 -0
  45. package/lib/dist/db/migrations.d.ts +1 -1
  46. package/lib/dist/db/migrations.d.ts.map +1 -1
  47. package/lib/dist/db/migrations.js +18 -4
  48. package/lib/dist/db/migrations.js.map +1 -1
  49. package/lib/dist/db/schema.sql +8 -0
  50. package/lib/dist/db/spec-queries.d.ts +13 -1
  51. package/lib/dist/db/spec-queries.d.ts.map +1 -1
  52. package/lib/dist/db/spec-queries.js +21 -0
  53. package/lib/dist/db/spec-queries.js.map +1 -1
  54. package/lib/dist/enforce/changed-files.d.ts +7 -0
  55. package/lib/dist/enforce/changed-files.d.ts.map +1 -1
  56. package/lib/dist/enforce/changed-files.js +17 -0
  57. package/lib/dist/enforce/changed-files.js.map +1 -1
  58. package/lib/dist/enforce/enforce.d.ts +35 -1
  59. package/lib/dist/enforce/enforce.d.ts.map +1 -1
  60. package/lib/dist/enforce/enforce.js +66 -2
  61. package/lib/dist/enforce/enforce.js.map +1 -1
  62. package/lib/dist/extraction/index.d.ts +50 -4
  63. package/lib/dist/extraction/index.d.ts.map +1 -1
  64. package/lib/dist/extraction/index.js +105 -13
  65. package/lib/dist/extraction/index.js.map +1 -1
  66. package/lib/dist/extraction/parse-warnings.d.ts +16 -0
  67. package/lib/dist/extraction/parse-warnings.d.ts.map +1 -0
  68. package/lib/dist/extraction/parse-warnings.js +30 -0
  69. package/lib/dist/extraction/parse-warnings.js.map +1 -0
  70. package/lib/dist/extraction/tree-sitter.d.ts +27 -0
  71. package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
  72. package/lib/dist/extraction/tree-sitter.js +168 -1
  73. package/lib/dist/extraction/tree-sitter.js.map +1 -1
  74. package/lib/dist/health/smoke-check.js +1 -1
  75. package/lib/dist/health/smoke-check.js.map +1 -1
  76. package/lib/dist/hooks/hooks.json +16 -1
  77. package/lib/dist/index.d.ts +63 -3
  78. package/lib/dist/index.d.ts.map +1 -1
  79. package/lib/dist/index.js +235 -9
  80. package/lib/dist/index.js.map +1 -1
  81. package/lib/dist/installer/agent-record.d.ts +80 -0
  82. package/lib/dist/installer/agent-record.d.ts.map +1 -0
  83. package/lib/dist/installer/agent-record.js +351 -0
  84. package/lib/dist/installer/agent-record.js.map +1 -0
  85. package/lib/dist/installer/auto-migrate.d.ts +56 -0
  86. package/lib/dist/installer/auto-migrate.d.ts.map +1 -0
  87. package/lib/dist/installer/auto-migrate.js +328 -0
  88. package/lib/dist/installer/auto-migrate.js.map +1 -0
  89. package/lib/dist/installer/index.d.ts +37 -8
  90. package/lib/dist/installer/index.d.ts.map +1 -1
  91. package/lib/dist/installer/index.js +156 -46
  92. package/lib/dist/installer/index.js.map +1 -1
  93. package/lib/dist/installer/install-defaults.d.ts +4 -3
  94. package/lib/dist/installer/install-defaults.d.ts.map +1 -1
  95. package/lib/dist/installer/install-defaults.js +6 -5
  96. package/lib/dist/installer/install-defaults.js.map +1 -1
  97. package/lib/dist/installer/{config-writer.d.ts → targets/claude-config-writer.d.ts} +1 -1
  98. package/lib/dist/installer/targets/claude-config-writer.d.ts.map +1 -0
  99. package/lib/dist/installer/{config-writer.js → targets/claude-config-writer.js} +7 -6
  100. package/lib/dist/installer/targets/claude-config-writer.js.map +1 -0
  101. package/lib/dist/installer/targets/claude-projects.d.ts +9 -0
  102. package/lib/dist/installer/targets/claude-projects.d.ts.map +1 -0
  103. package/lib/dist/installer/targets/claude-projects.js +151 -0
  104. package/lib/dist/installer/targets/claude-projects.js.map +1 -0
  105. package/lib/dist/installer/targets/claude.d.ts +28 -1
  106. package/lib/dist/installer/targets/claude.d.ts.map +1 -1
  107. package/lib/dist/installer/targets/claude.js +39 -20
  108. package/lib/dist/installer/targets/claude.js.map +1 -1
  109. package/lib/dist/installer/targets/feature-parity.d.ts +28 -0
  110. package/lib/dist/installer/targets/feature-parity.d.ts.map +1 -0
  111. package/lib/dist/installer/targets/feature-parity.js +32 -0
  112. package/lib/dist/installer/targets/feature-parity.js.map +1 -0
  113. package/lib/dist/installer/{gemini-commands.d.ts → targets/gemini-commands.d.ts} +7 -3
  114. package/lib/dist/installer/targets/gemini-commands.d.ts.map +1 -0
  115. package/lib/dist/installer/{gemini-commands.js → targets/gemini-commands.js} +35 -14
  116. package/lib/dist/installer/targets/gemini-commands.js.map +1 -0
  117. package/lib/dist/installer/targets/gemini-projects.d.ts +11 -0
  118. package/lib/dist/installer/targets/gemini-projects.d.ts.map +1 -0
  119. package/lib/dist/installer/targets/gemini-projects.js +84 -0
  120. package/lib/dist/installer/targets/gemini-projects.js.map +1 -0
  121. package/lib/dist/installer/targets/gemini.d.ts +94 -8
  122. package/lib/dist/installer/targets/gemini.d.ts.map +1 -1
  123. package/lib/dist/installer/targets/gemini.js +392 -33
  124. package/lib/dist/installer/targets/gemini.js.map +1 -1
  125. package/lib/dist/installer/targets/registry.d.ts +8 -1
  126. package/lib/dist/installer/targets/registry.d.ts.map +1 -1
  127. package/lib/dist/installer/targets/registry.js +14 -5
  128. package/lib/dist/installer/targets/registry.js.map +1 -1
  129. package/lib/dist/installer/targets/shared.d.ts +44 -1
  130. package/lib/dist/installer/targets/shared.d.ts.map +1 -1
  131. package/lib/dist/installer/targets/shared.js +130 -3
  132. package/lib/dist/installer/targets/shared.js.map +1 -1
  133. package/lib/dist/installer/targets/types.d.ts +23 -1
  134. package/lib/dist/installer/targets/types.d.ts.map +1 -1
  135. package/lib/dist/jira/auto-publish.d.ts +22 -2
  136. package/lib/dist/jira/auto-publish.d.ts.map +1 -1
  137. package/lib/dist/jira/auto-publish.js +54 -9
  138. package/lib/dist/jira/auto-publish.js.map +1 -1
  139. package/lib/dist/jira/board-first.d.ts +15 -2
  140. package/lib/dist/jira/board-first.d.ts.map +1 -1
  141. package/lib/dist/jira/board-first.js +16 -0
  142. package/lib/dist/jira/board-first.js.map +1 -1
  143. package/lib/dist/jira/ci-publish.d.ts +72 -0
  144. package/lib/dist/jira/ci-publish.d.ts.map +1 -0
  145. package/lib/dist/jira/ci-publish.js +162 -0
  146. package/lib/dist/jira/ci-publish.js.map +1 -0
  147. package/lib/dist/jira/publish.d.ts +23 -0
  148. package/lib/dist/jira/publish.d.ts.map +1 -1
  149. package/lib/dist/jira/publish.js +0 -0
  150. package/lib/dist/jira/publish.js.map +1 -1
  151. package/lib/dist/jira/regression-pack.d.ts.map +1 -1
  152. package/lib/dist/jira/regression-pack.js +7 -1
  153. package/lib/dist/jira/regression-pack.js.map +1 -1
  154. package/lib/dist/jira/repo-config.d.ts.map +1 -1
  155. package/lib/dist/jira/repo-config.js +8 -0
  156. package/lib/dist/jira/repo-config.js.map +1 -1
  157. package/lib/dist/jira/types.d.ts +8 -0
  158. package/lib/dist/jira/types.d.ts.map +1 -1
  159. package/lib/dist/jira/types.js.map +1 -1
  160. package/lib/dist/knowledge/enforce.d.ts.map +1 -1
  161. package/lib/dist/knowledge/enforce.js +6 -1
  162. package/lib/dist/knowledge/enforce.js.map +1 -1
  163. package/lib/dist/mcp/jira-tools.d.ts +5 -0
  164. package/lib/dist/mcp/jira-tools.d.ts.map +1 -1
  165. package/lib/dist/mcp/jira-tools.js +59 -4
  166. package/lib/dist/mcp/jira-tools.js.map +1 -1
  167. package/lib/dist/mcp/proxy.d.ts.map +1 -1
  168. package/lib/dist/mcp/proxy.js +2 -1
  169. package/lib/dist/mcp/proxy.js.map +1 -1
  170. package/lib/dist/mcp/server-instructions.d.ts +16 -10
  171. package/lib/dist/mcp/server-instructions.d.ts.map +1 -1
  172. package/lib/dist/mcp/server-instructions.js +69 -20
  173. package/lib/dist/mcp/server-instructions.js.map +1 -1
  174. package/lib/dist/mcp/session.d.ts +11 -0
  175. package/lib/dist/mcp/session.d.ts.map +1 -1
  176. package/lib/dist/mcp/session.js +43 -1
  177. package/lib/dist/mcp/session.js.map +1 -1
  178. package/lib/dist/mcp/tools.d.ts.map +1 -1
  179. package/lib/dist/mcp/tools.js +8 -0
  180. package/lib/dist/mcp/tools.js.map +1 -1
  181. package/lib/dist/reflect/apply.d.ts +2 -2
  182. package/lib/dist/reflect/apply.d.ts.map +1 -1
  183. package/lib/dist/reflect/apply.js +6 -5
  184. package/lib/dist/reflect/apply.js.map +1 -1
  185. package/lib/dist/reflect/miner.d.ts.map +1 -1
  186. package/lib/dist/reflect/miner.js +28 -15
  187. package/lib/dist/reflect/miner.js.map +1 -1
  188. package/lib/dist/reflect/session-outcomes.d.ts.map +1 -1
  189. package/lib/dist/reflect/session-outcomes.js +8 -3
  190. package/lib/dist/reflect/session-outcomes.js.map +1 -1
  191. package/lib/dist/reflect/targets.d.ts.map +1 -1
  192. package/lib/dist/reflect/targets.js +25 -5
  193. package/lib/dist/reflect/targets.js.map +1 -1
  194. package/lib/dist/reflect/types.d.ts +7 -0
  195. package/lib/dist/reflect/types.d.ts.map +1 -1
  196. package/lib/dist/resolution/spec-link-resolver.d.ts +14 -2
  197. package/lib/dist/resolution/spec-link-resolver.d.ts.map +1 -1
  198. package/lib/dist/resolution/spec-link-resolver.js +13 -3
  199. package/lib/dist/resolution/spec-link-resolver.js.map +1 -1
  200. package/lib/dist/server/canonical-tools.js +50 -0
  201. package/lib/dist/server/cli.js +2 -2
  202. package/lib/dist/server/host-profiles.js +39 -0
  203. package/lib/dist/server/ingest/index.js +2 -1
  204. package/lib/dist/server/ingest/ingestor.js +195 -76
  205. package/lib/dist/server/ingest/project-paths.js +8 -2
  206. package/lib/dist/server/ingest/recorded-projects.js +43 -0
  207. package/lib/dist/server/ingest/specship-classify.js +7 -2
  208. package/lib/dist/server/ingest/transcripts/claude-jsonl.js +54 -0
  209. package/lib/dist/server/ingest/transcripts/claude.js +64 -0
  210. package/lib/dist/server/ingest/transcripts/gemini.js +469 -0
  211. package/lib/dist/server/ingest/transcripts/index.js +14 -0
  212. package/lib/dist/server/ingest/{parser.js → transcripts/shared.js} +3 -49
  213. package/lib/dist/server/ingest/transcripts/types.js +4 -0
  214. package/lib/dist/server/ingest/watcher.js +31 -30
  215. package/lib/dist/server/routes/claude.js +27 -10
  216. package/lib/dist/server/routes/graph.js +64 -3
  217. package/lib/dist/server/routes/mcp.js +57 -15
  218. package/lib/dist/server/routes/memory.js +54 -35
  219. package/lib/dist/server/routes/projects.js +78 -7
  220. package/lib/dist/server/routes/spec.js +125 -0
  221. package/lib/dist/server/server.js +8 -2
  222. package/lib/dist/skills/spec-author/SKILL.md +1 -1
  223. package/lib/dist/skills/spec-author/references/gap-questions.md +1 -1
  224. package/lib/dist/spec-lint/lint.d.ts +26 -1
  225. package/lib/dist/spec-lint/lint.d.ts.map +1 -1
  226. package/lib/dist/spec-lint/lint.js +96 -7
  227. package/lib/dist/spec-lint/lint.js.map +1 -1
  228. package/lib/dist/sync/worktree.d.ts +48 -0
  229. package/lib/dist/sync/worktree.d.ts.map +1 -1
  230. package/lib/dist/sync/worktree.js +109 -0
  231. package/lib/dist/sync/worktree.js.map +1 -1
  232. package/lib/dist/ui/assets/bricolage-latin-C23fTOVi.woff2 +0 -0
  233. package/lib/dist/ui/assets/bricolage-latin-ext-B82pxkPf.woff2 +0 -0
  234. package/lib/dist/ui/assets/index-54vorjyq.css +1 -0
  235. package/lib/dist/ui/assets/index-BZQonCVb.js +52 -0
  236. package/lib/dist/ui/assets/space-grotesk-latin-DPT1xrvW.woff2 +0 -0
  237. package/lib/dist/ui/assets/space-grotesk-latin-ext-wJGaI8U0.woff2 +0 -0
  238. package/lib/dist/ui/index.html +2 -2
  239. package/lib/dist/update/updater.d.ts +6 -0
  240. package/lib/dist/update/updater.d.ts.map +1 -1
  241. package/lib/dist/update/updater.js +13 -1
  242. package/lib/dist/update/updater.js.map +1 -1
  243. package/lib/dist/workflows/agents/claude.d.ts +9 -0
  244. package/lib/dist/workflows/agents/claude.d.ts.map +1 -1
  245. package/lib/dist/workflows/agents/claude.js +22 -3
  246. package/lib/dist/workflows/agents/claude.js.map +1 -1
  247. package/lib/dist/workflows/agents/gemini-version.d.ts +18 -0
  248. package/lib/dist/workflows/agents/gemini-version.d.ts.map +1 -0
  249. package/lib/dist/workflows/agents/gemini-version.js +81 -0
  250. package/lib/dist/workflows/agents/gemini-version.js.map +1 -0
  251. package/lib/dist/workflows/agents/gemini.d.ts +1 -1
  252. package/lib/dist/workflows/agents/gemini.d.ts.map +1 -1
  253. package/lib/dist/workflows/agents/gemini.js +12 -2
  254. package/lib/dist/workflows/agents/gemini.js.map +1 -1
  255. package/lib/dist/workflows/agents/index.d.ts +2 -0
  256. package/lib/dist/workflows/agents/index.d.ts.map +1 -1
  257. package/lib/dist/workflows/agents/index.js +5 -0
  258. package/lib/dist/workflows/agents/index.js.map +1 -1
  259. package/lib/dist/workflows/agents/types.d.ts +13 -0
  260. package/lib/dist/workflows/agents/types.d.ts.map +1 -1
  261. package/lib/dist/workflows/agents/types.js.map +1 -1
  262. package/lib/dist/workflows/condition-evaluator.d.ts +8 -0
  263. package/lib/dist/workflows/condition-evaluator.d.ts.map +1 -1
  264. package/lib/dist/workflows/condition-evaluator.js +7 -0
  265. package/lib/dist/workflows/condition-evaluator.js.map +1 -1
  266. package/lib/dist/workflows/defaults/claude-design-implement.yaml +11 -11
  267. package/lib/dist/workflows/defaults/spec-author.yaml +9 -9
  268. package/lib/dist/workflows/defaults/spec-fix.yaml +8 -8
  269. package/lib/dist/workflows/defaults/spec-implement.yaml +38 -23
  270. package/lib/dist/workflows/defaults/spec-relink.yaml +5 -5
  271. package/lib/dist/workflows/defaults/spec-verify.yaml +3 -3
  272. package/lib/dist/workflows/executor.d.ts +7 -0
  273. package/lib/dist/workflows/executor.d.ts.map +1 -1
  274. package/lib/dist/workflows/executor.js +22 -5
  275. package/lib/dist/workflows/executor.js.map +1 -1
  276. package/lib/node_modules/.package-lock.json +1 -1
  277. package/lib/package.json +3 -2
  278. package/package.json +1 -1
  279. package/lib/dist/installer/config-writer.d.ts.map +0 -1
  280. package/lib/dist/installer/config-writer.js.map +0 -1
  281. package/lib/dist/installer/gemini-commands.d.ts.map +0 -1
  282. package/lib/dist/installer/gemini-commands.js.map +0 -1
  283. package/lib/dist/ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  284. package/lib/dist/ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  285. package/lib/dist/ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  286. package/lib/dist/ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  287. package/lib/dist/ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  288. package/lib/dist/ui/assets/index-BzuUWUAE.js +0 -50
  289. package/lib/dist/ui/assets/index-ezwX2EfG.css +0 -1
@@ -16,10 +16,85 @@ import { writeSseHead } from './sse.js';
16
16
  import { promises as fs, watch } from 'node:fs';
17
17
  import os from 'node:os';
18
18
  import path from 'node:path';
19
- import { createSlugResolver } from '../ingest/project-paths.js';
19
+ import { createSlugResolver, encodeProjectSlug } from '../ingest/project-paths.js';
20
+ import { recordedProjects } from '../ingest/recorded-projects.js';
21
+ import { transcriptAdapters } from '../ingest/transcripts/index.js';
22
+ import { CLAUDE_PROFILE } from '../host-profiles.js';
20
23
  const projectsBus = new EventEmitter();
21
24
  projectsBus.setMaxListeners(0); // many SSE subscribers + internal
22
25
  export async function enumerate(claudeRoot, resolverOpts) {
26
+ const fromTranscripts = await enumerateTranscriptProjects(claudeRoot, resolverOpts);
27
+ // Projects any agent has SpecShip installed in (REQ-AGENTSWITCH-011) — the
28
+ // only source for an agent whose session folders cannot be mapped back to a
29
+ // path. Listed once: a project already found above keeps that entry.
30
+ const seen = new Set(fromTranscripts.map((p) => p.path));
31
+ // Agents that keep their own project list (REQ-AGENTSWITCH-019.A1).
32
+ const fromAgents = [];
33
+ const home = resolverOpts?.home ?? os.homedir();
34
+ for (const adapter of transcriptAdapters()) {
35
+ let found = [];
36
+ try {
37
+ found = adapter.listProjects?.(home) ?? [];
38
+ }
39
+ catch { /* one agent's files never block another's */ }
40
+ for (const p of found) {
41
+ if (seen.has(p.path))
42
+ continue;
43
+ seen.add(p.path);
44
+ fromAgents.push({ ...(await projectState(p.path)), slug: encodeProjectSlug(p.path), path: p.path, sessionCount: p.sessionCount, lastModifiedMs: p.lastModifiedMs, driftCount: null });
45
+ }
46
+ }
47
+ const fromRecord = [];
48
+ for (const rec of recordedProjects(resolverOpts?.recordPath)) {
49
+ if (seen.has(rec.path))
50
+ continue;
51
+ seen.add(rec.path);
52
+ let exists = false;
53
+ let initialized = false;
54
+ try {
55
+ exists = (await fs.stat(rec.path)).isDirectory();
56
+ }
57
+ catch { /* gone */ }
58
+ if (exists) {
59
+ try {
60
+ initialized = (await fs.stat(path.join(rec.path, '.specship'))).isDirectory();
61
+ }
62
+ catch { /* not initialized */ }
63
+ }
64
+ fromRecord.push({
65
+ slug: encodeProjectSlug(rec.path),
66
+ path: rec.path,
67
+ exists,
68
+ initialized,
69
+ sessionCount: 0,
70
+ lastModifiedMs: rec.recordedAtMs,
71
+ driftCount: null,
72
+ });
73
+ }
74
+ return [...fromTranscripts, ...fromAgents, ...fromRecord].sort(byRecency);
75
+ }
76
+ async function projectState(p) {
77
+ let exists = false;
78
+ let initialized = false;
79
+ try {
80
+ exists = (await fs.stat(p)).isDirectory();
81
+ }
82
+ catch { /* gone */ }
83
+ if (exists) {
84
+ try {
85
+ initialized = (await fs.stat(path.join(p, '.specship'))).isDirectory();
86
+ }
87
+ catch { /* not initialized */ }
88
+ }
89
+ return { exists, initialized };
90
+ }
91
+ /** Recent activity first; ties broken by path. */
92
+ function byRecency(a, b) {
93
+ if (b.lastModifiedMs !== a.lastModifiedMs)
94
+ return b.lastModifiedMs - a.lastModifiedMs;
95
+ return a.path.localeCompare(b.path);
96
+ }
97
+ async function enumerateTranscriptProjects(claudeRoot, resolverOpts) {
23
98
  let entries;
24
99
  try {
25
100
  entries = await fs.readdir(claudeRoot, { withFileTypes: true });
@@ -71,11 +146,7 @@ export async function enumerate(claudeRoot, resolverOpts) {
71
146
  out.push({ slug, path: decoded, exists, initialized, sessionCount, lastModifiedMs, driftCount: null });
72
147
  }
73
148
  // Recent activity first; ties broken by path.
74
- out.sort((a, b) => {
75
- if (b.lastModifiedMs !== a.lastModifiedMs)
76
- return b.lastModifiedMs - a.lastModifiedMs;
77
- return a.path.localeCompare(b.path);
78
- });
149
+ out.sort(byRecency);
79
150
  return out;
80
151
  }
81
152
  /**
@@ -167,7 +238,7 @@ function stopWatcher() {
167
238
  }
168
239
  // --- Route registration -----------------------------------------------------
169
240
  export async function registerProjectsRoutes(app) {
170
- const claudeRoot = path.join(os.homedir(), '.claude', 'projects');
241
+ const claudeRoot = path.join(os.homedir(), CLAUDE_PROFILE.configDir, 'projects');
171
242
  startWatcher(claudeRoot, false);
172
243
  app.addHook('onClose', async () => { stopWatcher(); });
173
244
  const driftSource = (slug) => app.projects.getBySlug(slug);
@@ -7,6 +7,7 @@
7
7
  * boot-time primary). Returns 409 / `no_project` when neither is selectable.
8
8
  */
9
9
  import * as fs from 'node:fs';
10
+ import * as os from 'node:os';
10
11
  import * as path from 'node:path';
11
12
  /**
12
13
  * Resolve a project-relative path to an absolute path under the project
@@ -85,6 +86,119 @@ function atomicWriteFile(targetPath, content) {
85
86
  fs.writeFileSync(tmp, content, 'utf-8');
86
87
  fs.renameSync(tmp, targetPath);
87
88
  }
89
+ const PLAN_DRIFT_STATES = ['drifted', 'broken', 'orphaned'];
90
+ const metaString = (meta, key) => {
91
+ const v = meta?.[key];
92
+ return typeof v === 'string' && v.trim() ? v.trim() : null;
93
+ };
94
+ /**
95
+ * The JIRA base URL for issue links — and ONLY that. Reads
96
+ * `SPECSHIP_JIRA_BASE_URL`, else the `baseUrl` field of the user-level JIRA
97
+ * config (`SPECSHIP_JIRA_CONFIG` or `~/.specship/jira.json`). That file also
98
+ * holds credentials; nothing but `baseUrl` is ever read out of the parsed
99
+ * object, returned or logged. No JIRA request is made (REQ-DASHSIMPLE-003.A4).
100
+ */
101
+ export function readJiraBaseUrl() {
102
+ const fromEnv = process.env.SPECSHIP_JIRA_BASE_URL;
103
+ let base = fromEnv && fromEnv.trim() ? fromEnv.trim() : null;
104
+ if (!base) {
105
+ const file = process.env.SPECSHIP_JIRA_CONFIG ?? path.join(os.homedir(), '.specship', 'jira.json');
106
+ try {
107
+ const parsed = JSON.parse(fs.readFileSync(file, 'utf-8'));
108
+ const v = parsed && typeof parsed === 'object' ? parsed.baseUrl : undefined;
109
+ if (typeof v === 'string' && v.trim())
110
+ base = v.trim();
111
+ }
112
+ catch { /* absent or malformed → no links, plain-text keys */ }
113
+ }
114
+ if (!base || !/^https?:\/\//i.test(base))
115
+ return null;
116
+ return base.replace(/\/+$/, '');
117
+ }
118
+ const byFileOrder = (a, b) => a.sourcePath < b.sourcePath ? -1 : a.sourcePath > b.sourcePath ? 1 : (a.startLine ?? 0) - (b.startLine ?? 0);
119
+ /**
120
+ * Epic → story → task from the indexed specs alone (REQ-DASHSIMPLE-003).
121
+ * `epicKey` and `jira_issue_<REQ>` come from each document's stored metadata
122
+ * (its frontmatter, as indexed) — the spec files are not re-parsed here.
123
+ * Documents sharing an `epicKey` merge into one epic in file order; a document
124
+ * without one is its own group titled after the document.
125
+ */
126
+ // @implements REQ-DASHSIMPLE-003
127
+ export function buildPlan(cg, jiraBaseUrl) {
128
+ const sq = cg.getSpecQueries();
129
+ const all = sq.getAllSpecs();
130
+ const coverage = new Map(cg.getSpecCoverage().requirements.map((r) => [r.specId, r]));
131
+ const docs = all.filter((s) => s.kind === 'document').sort(byFileOrder);
132
+ const docIds = new Set(docs.map((d) => d.id));
133
+ const reqsByDoc = new Map();
134
+ const looseByFile = new Map();
135
+ for (const s of all) {
136
+ if (s.kind !== 'requirement')
137
+ continue;
138
+ if (s.parentId && docIds.has(s.parentId)) {
139
+ const arr = reqsByDoc.get(s.parentId) ?? [];
140
+ arr.push(s);
141
+ reqsByDoc.set(s.parentId, arr);
142
+ }
143
+ else {
144
+ // A requirement outside any document still belongs in the plan.
145
+ const arr = looseByFile.get(s.sourcePath) ?? [];
146
+ arr.push(s);
147
+ looseByFile.set(s.sourcePath, arr);
148
+ }
149
+ }
150
+ const story = (s, meta) => {
151
+ const cov = coverage.get(s.id) ?? null;
152
+ return {
153
+ specId: s.id,
154
+ title: s.title,
155
+ body: s.body ?? '',
156
+ jiraKey: metaString(meta, `jira_issue_${s.id}`),
157
+ coverage: cov,
158
+ tasks: (cov?.criteria ?? []).map((c) => ({ specId: c.specId, title: c.title, verdict: c.verdict })),
159
+ };
160
+ };
161
+ const entries = [];
162
+ for (const d of docs) {
163
+ const reqs = (reqsByDoc.get(d.id) ?? []).sort(byFileOrder);
164
+ entries.push({
165
+ key: metaString(d.metadata, 'epicKey'),
166
+ title: d.title,
167
+ sourcePath: d.sourcePath,
168
+ startLine: d.startLine,
169
+ doc: { id: d.id, title: d.title, stories: reqs.map((r) => story(r, d.metadata)) },
170
+ });
171
+ }
172
+ for (const [file, reqs] of looseByFile) {
173
+ entries.push({
174
+ key: null, title: file, sourcePath: file,
175
+ doc: { id: file, title: file, stories: reqs.sort(byFileOrder).map((r) => story(r, undefined)) },
176
+ });
177
+ }
178
+ entries.sort(byFileOrder);
179
+ const epics = [];
180
+ const byKey = new Map();
181
+ for (const e of entries) {
182
+ if (e.key) {
183
+ const hit = byKey.get(e.key);
184
+ if (hit) {
185
+ hit.docs.push(e.doc);
186
+ continue;
187
+ }
188
+ const epic = { key: e.key, title: e.title, docs: [e.doc] };
189
+ byKey.set(e.key, epic);
190
+ epics.push(epic);
191
+ }
192
+ else {
193
+ epics.push({ key: null, title: e.title, docs: [e.doc] });
194
+ }
195
+ }
196
+ const titles = new Map(all.map((s) => [s.id, s.title]));
197
+ const driftLinks = sq
198
+ .getLinksByState([...PLAN_DRIFT_STATES])
199
+ .map((l) => ({ ...l, specTitle: titles.get(l.specId) ?? null }));
200
+ return { jiraBaseUrl, epics, driftLinks };
201
+ }
88
202
  async function resolveCg(app, req, reply) {
89
203
  const cg = await app.activeCg(req);
90
204
  if (!cg) {
@@ -148,6 +262,17 @@ export async function registerSpecRoutes(app) {
148
262
  const scope = req.query.spec && req.query.spec.length > 0 ? req.query.spec : undefined;
149
263
  return cg.getSpecCoverage(scope);
150
264
  });
265
+ /**
266
+ * GET /api/spec/plan — epic → story → task for the Plan reader
267
+ * (REQ-DASHSIMPLE-003). Read-only, no JIRA call; the only JIRA config field
268
+ * it exposes is the base URL.
269
+ */
270
+ app.get('/api/spec/plan', async (req, reply) => {
271
+ const cg = await resolveCg(app, req, reply);
272
+ if (!cg)
273
+ return;
274
+ return buildPlan(cg, readJiraBaseUrl());
275
+ });
151
276
  app.get('/api/spec/:id', async (req, reply) => {
152
277
  const cg = await resolveCg(app, req, reply);
153
278
  if (!cg)
@@ -190,10 +190,16 @@ export async function createServer(options) {
190
190
  const primaryPath = options.projectRoot ?? null;
191
191
  const isPrimary = primaryPath ? primaryProjectMatcher(primaryPath) : () => false;
192
192
  const resolveGraph = (projectPath) => primaryPath && isPrimary(projectPath) ? primaryCg : null;
193
- watcher = startWatcher(dbHandle, { verbose, resolveGraph });
193
+ // projectPaths lets hash-keyed transcripts (Gemini CLI) resolve to the
194
+ // primary project's real path (REQ-AGENTSWITCH-004).
195
+ watcher = startWatcher(dbHandle, {
196
+ verbose,
197
+ resolveGraph,
198
+ projectPaths: primaryPath ? [primaryPath] : [],
199
+ });
194
200
  ownedWatcher = true;
195
201
  if (verbose)
196
- console.error('[specship-server] JSONL ingest watcher started');
202
+ console.error('[specship-server] transcript ingest watcher started');
197
203
  // The specship-impact boot backfill is gone with the engine it fed
198
204
  // (REQ-SURF-005) — nothing reads displaced_files/resolution any more.
199
205
  // Re-cost prompts ingested while their model family was unpriced,
@@ -132,7 +132,7 @@ Next steps:
132
132
 
133
133
  ## When to use the workflow instead of the skill directly
134
134
 
135
- This skill is the **lightweight path** — runs conversationally in Claude Code, no formal approval gates. For team contexts that want the same discipline `spec-implement` enforces, point the user at:
135
+ This skill is the **lightweight path** — runs conversationally in your coding agent, no formal approval gates. For team contexts that want the same discipline `spec-implement` enforces, point the user at:
136
136
 
137
137
  ```
138
138
  specship workflow run spec-author --input DESCRIPTION="..."
@@ -102,7 +102,7 @@ In SpecShip itself (and in any project whose `CLAUDE.md` states equivalents), th
102
102
  | Surface the spec touches | What the spec must account for |
103
103
  |---|---|
104
104
  | **MCP tools** (`src/mcp/`) — new tool, changed output, changed budget | Explore budgets are **monotonic**: a change may not shrink what a given budget returns. And `src/mcp/server-instructions.ts` is the **single source of truth** for agent-facing tool guidance — a spec that changes how the agent should use a tool must say that file is updated, not that guidance is duplicated elsewhere. |
105
- | **Installer** (`src/installer/`) — new asset, new target, changed layout | Name **which targets** are affected (Claude Code is the only default target; Gemini CLI is opt-in and MCP-entry-only). Say how **markers** are handled, so install is idempotent and uninstall fully reverses. Require a **CHANGELOG entry** — installer regressions break every new install silently. |
105
+ | **Installer** (`src/installer/`) — new asset, new target, changed layout | Name **which targets** are affected (Claude Code and Gemini CLI both get the full surface — MCP entry, steering, hooks, commands, skills, subagent — except the Claude-only status line; `specship install` with no target wires the agent it runs under). Say how **markers** are handled, so install is idempotent and uninstall fully reverses. Require a **CHANGELOG entry** — installer regressions break every new install silently. |
106
106
  | **Retrieval** — anything that changes how an answer is assembled | The budget is **tool-call count + wall-clock latency**, not tokens. A flow question must still resolve in 1–5 specship calls with zero Read/Grep. An acceptance bullet that lets the answer get slower or need more calls is a regression, however good the output looks. |
107
107
  | **Extraction** (`src/extraction/`) — new language, new node/edge type | Use the **exact `NodeKind` / `EdgeKind` strings** from `src/types.ts`; inventing a kind silently drops the data. Any new SQL or grammar `.wasm` must be added to **`copy-assets`** or it won't ship in the package. |
108
108
 
@@ -20,7 +20,7 @@ export type LintSeverity = 'error' | 'warning';
20
20
  * code (`spec_missing_id`, `spec_stranded_id`, `spec_bare_path_ref`,
21
21
  * `spec_acceptance_parent_mismatch`) so one vocabulary spans both layers.
22
22
  */
23
- export type LintCode = 'spec_duplicate_id' | 'spec_orphan_acceptance_parent' | 'spec_requirement_without_acceptance' | 'spec_needs_review_marker' | 'spec_unknown_evidence_kind' | 'spec_external_fact_missing_provenance' | 'spec_malformed_enforced_rule' | 'spec_no_negative_case' | 'spec_missing_non_goals' | 'spec_missing_test_plan' | 'spec_requirement_without_rfc2119' | string;
23
+ export type LintCode = 'spec_duplicate_id' | 'spec_duplicate_id_cross_file' | 'spec_orphan_acceptance_parent' | 'spec_requirement_without_acceptance' | 'spec_needs_review_marker' | 'spec_unknown_evidence_kind' | 'spec_external_fact_missing_provenance' | 'spec_malformed_enforced_rule' | 'spec_no_negative_case' | 'spec_missing_non_goals' | 'spec_missing_test_plan' | 'spec_requirement_without_rfc2119' | string;
24
24
  export interface LintFinding {
25
25
  code: LintCode;
26
26
  severity: LintSeverity;
@@ -47,6 +47,31 @@ export interface LintReport {
47
47
  /** The exit-code predicate (A3): errors fail, warnings alone do not. */
48
48
  hasErrors: boolean;
49
49
  }
50
+ /**
51
+ * Every `<!-- id: X -->` declaration in a spec file, in line order (1-indexed).
52
+ * A brief or design transcript declares nothing — it is not a spec, so its
53
+ * markers (quoted from elsewhere) must not collide with real ones.
54
+ */
55
+ export declare function collectIdDeclarations(filePath: string, source: string): Array<{
56
+ id: string;
57
+ line: number;
58
+ }>;
59
+ /** Where one id is declared: a project-relative file and a 1-indexed line. */
60
+ export interface IdDeclarationSite {
61
+ filePath: string;
62
+ line: number;
63
+ }
64
+ /**
65
+ * Ids declared in more than one spec file (REQ-MULTIDEV-001). The persistence
66
+ * layer upserts by id, so after a merge where two branches picked the same id
67
+ * in different files, one section silently replaces the other. Repeats inside a
68
+ * single file are `spec_duplicate_id`'s job and are not reported here.
69
+ *
70
+ * Emits one error per colliding id per declaring file, anchored at that file's
71
+ * first declaration, with every `path:line` listed (sorted) in the message.
72
+ * Callers decide which of the returned findings belong to a linted file.
73
+ */
74
+ export declare function findCrossFileDuplicates(decls: Map<string, IdDeclarationSite[]>): LintFinding[];
50
75
  /**
51
76
  * Lint one spec file's source. `filePath` is used verbatim in findings, so
52
77
  * callers should pass a project-relative path.
@@ -1 +1 @@
1
- {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/spec-lint/lint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/C;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAEhB,mBAAmB,GACnB,+BAA+B,GAC/B,qCAAqC,GACrC,0BAA0B,GAC1B,4BAA4B,GAC5B,uCAAuC,GACvC,8BAA8B,GAE9B,uBAAuB,GACvB,wBAAwB,GACxB,wBAAwB,GACxB,kCAAkC,GAElC,MAAM,CAAC;AAEX,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,SAAS,EAAE,OAAO,CAAC;CACpB;AAkHD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CA2K9E;AA+DD,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CAmEhF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAc3D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,WAAgB,GACxB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAQtC"}
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/spec-lint/lint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/C;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAEhB,mBAAmB,GACnB,8BAA8B,GAC9B,+BAA+B,GAC/B,qCAAqC,GACrC,0BAA0B,GAC1B,4BAA4B,GAC5B,uCAAuC,GACvC,8BAA8B,GAE9B,uBAAuB,GACvB,wBAAwB,GACxB,wBAAwB,GACxB,kCAAkC,GAElC,MAAM,CAAC;AAEX,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,4EAA4E;IAC5E,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,SAAS,EAAE,OAAO,CAAC;CACpB;AAkHD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAS3G;AAED,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,GAAG,WAAW,EAAE,CAkB9F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAwK9E;AA+DD,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,WAAgB,GAAG,UAAU,CA0GhF;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAc3D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,WAAgB,GACxB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAQtC"}
@@ -49,6 +49,8 @@ var __importStar = (this && this.__importStar) || (function () {
49
49
  };
50
50
  })();
51
51
  Object.defineProperty(exports, "__esModule", { value: true });
52
+ exports.collectIdDeclarations = collectIdDeclarations;
53
+ exports.findCrossFileDuplicates = findCrossFileDuplicates;
52
54
  exports.lintSpecSource = lintSpecSource;
53
55
  exports.lintSpecs = lintSpecs;
54
56
  exports.formatLintReport = formatLintReport;
@@ -152,6 +154,54 @@ function lintDomainFact(specs, source, add) {
152
154
  });
153
155
  }
154
156
  }
157
+ /**
158
+ * Every `<!-- id: X -->` declaration in a spec file, in line order (1-indexed).
159
+ * A brief or design transcript declares nothing — it is not a spec, so its
160
+ * markers (quoted from elsewhere) must not collide with real ones.
161
+ */
162
+ function collectIdDeclarations(filePath, source) {
163
+ if (isNonSpecArtifact(filePath))
164
+ return [];
165
+ const out = [];
166
+ const lines = source.split(/\r?\n/);
167
+ for (let i = 0; i < lines.length; i++) {
168
+ const id = (lines[i] ?? '').match(ID_COMMENT_LINE)?.[1];
169
+ if (id)
170
+ out.push({ id, line: i + 1 });
171
+ }
172
+ return out;
173
+ }
174
+ /**
175
+ * Ids declared in more than one spec file (REQ-MULTIDEV-001). The persistence
176
+ * layer upserts by id, so after a merge where two branches picked the same id
177
+ * in different files, one section silently replaces the other. Repeats inside a
178
+ * single file are `spec_duplicate_id`'s job and are not reported here.
179
+ *
180
+ * Emits one error per colliding id per declaring file, anchored at that file's
181
+ * first declaration, with every `path:line` listed (sorted) in the message.
182
+ * Callers decide which of the returned findings belong to a linted file.
183
+ */
184
+ function findCrossFileDuplicates(decls) {
185
+ const out = [];
186
+ for (const [id, sites] of decls) {
187
+ const byFile = new Map();
188
+ for (const s of sites) {
189
+ const first = byFile.get(s.filePath);
190
+ if (first === undefined || s.line < first)
191
+ byFile.set(s.filePath, s.line);
192
+ }
193
+ if (byFile.size < 2)
194
+ continue;
195
+ const listed = [...sites]
196
+ .sort((a, b) => a.filePath.localeCompare(b.filePath) || a.line - b.line)
197
+ .map((s) => `${s.filePath}:${s.line}`);
198
+ const message = `ID ${id} is declared in ${byFile.size} files: ${listed.join(', ')}. Ids are global — the index keeps only one of these sections, so rename all but one.`;
199
+ for (const [filePath, line] of byFile) {
200
+ out.push({ code: 'spec_duplicate_id_cross_file', severity: 'error', filePath, line, specId: id, message });
201
+ }
202
+ }
203
+ return out;
204
+ }
155
205
  /**
156
206
  * Lint one spec file's source. `filePath` is used verbatim in findings, so
157
207
  * callers should pass a project-relative path.
@@ -180,23 +230,19 @@ function lintSpecSource(filePath, source) {
180
230
  // 2. Duplicate ids within the file (A1). The persistence layer upserts by id,
181
231
  // so the LAST occurrence wins and the earlier section silently vanishes.
182
232
  const seen = new Map();
183
- for (let i = 0; i < lines.length; i++) {
184
- const m = (lines[i] ?? '').match(ID_COMMENT_LINE);
185
- const id = m?.[1];
186
- if (!id)
187
- continue;
233
+ for (const { id, line } of collectIdDeclarations(filePath, source)) {
188
234
  const first = seen.get(id);
189
235
  if (first !== undefined) {
190
236
  add({
191
237
  code: 'spec_duplicate_id',
192
238
  severity: 'error',
193
- line: i + 1,
239
+ line,
194
240
  specId: id,
195
241
  message: `Duplicate id ${id} (first declared on line ${first}). The last occurrence overwrites earlier ones, so the earlier section is lost.`,
196
242
  });
197
243
  }
198
244
  else {
199
- seen.set(id, i + 1);
245
+ seen.set(id, line);
200
246
  }
201
247
  }
202
248
  // A domain fact keeps the extractor's verdict (its frontmatter can genuinely
@@ -388,6 +434,16 @@ function collectSpecFiles(target, out) {
388
434
  function lintSpecs(paths, options = {}) {
389
435
  const projectRoot = options.projectRoot ?? process.cwd();
390
436
  const files = [];
437
+ const decls = new Map();
438
+ const recordDeclarations = (rel, source) => {
439
+ for (const { id, line } of collectIdDeclarations(rel, source)) {
440
+ const sites = decls.get(id);
441
+ if (sites)
442
+ sites.push({ filePath: rel, line });
443
+ else
444
+ decls.set(id, [{ filePath: rel, line }]);
445
+ }
446
+ };
391
447
  const targets = paths.length > 0 ? paths : [path.join(projectRoot, 'specs')];
392
448
  const absFiles = [];
393
449
  for (const target of targets) {
@@ -433,6 +489,7 @@ function lintSpecs(paths, options = {}) {
433
489
  continue;
434
490
  }
435
491
  const findings = lintSpecSource(rel, source);
492
+ recordDeclarations(rel, source);
436
493
  files.push({
437
494
  filePath: rel,
438
495
  findings,
@@ -440,6 +497,38 @@ function lintSpecs(paths, options = {}) {
440
497
  warningCount: findings.filter((f) => f.severity === 'warning').length,
441
498
  });
442
499
  }
500
+ // Cross-file duplicate ids (REQ-MULTIDEV-001). The rest of the checkout's
501
+ // specs/ is scanned for declarations even when only a subset was linted
502
+ // (A4), so a linted file colliding with an unlinted one still fails; the
503
+ // unlinted file only contributes sites and gets no report entry.
504
+ const linted = new Set(absFiles);
505
+ const corpus = [];
506
+ collectSpecFiles(path.join(projectRoot, 'specs'), corpus);
507
+ for (const abs of [...new Set(corpus)].sort()) {
508
+ if (linted.has(abs))
509
+ continue;
510
+ let source;
511
+ try {
512
+ source = fs.readFileSync(abs, 'utf-8');
513
+ }
514
+ catch {
515
+ continue;
516
+ }
517
+ recordDeclarations(path.relative(projectRoot, abs) || abs, source);
518
+ }
519
+ const reportsByPath = new Map(files.map((f) => [f.filePath, f]));
520
+ const touched = new Set();
521
+ for (const finding of findCrossFileDuplicates(decls)) {
522
+ const report = reportsByPath.get(finding.filePath);
523
+ if (!report)
524
+ continue; // an unlinted file — named in the message only
525
+ report.findings.push(finding);
526
+ touched.add(report);
527
+ }
528
+ for (const report of touched) {
529
+ report.findings = sortFindings(report.findings);
530
+ report.errorCount = report.findings.filter((f) => f.severity === 'error').length;
531
+ }
443
532
  files.sort((a, b) => a.filePath.localeCompare(b.filePath));
444
533
  const errorCount = files.reduce((n, f) => n + f.errorCount, 0);
445
534
  const warningCount = files.reduce((n, f) => n + f.warningCount, 0);
@@ -1 +1 @@
1
- {"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/spec-lint/lint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/spec-lint/lint.ts"],"names":[],"mappings":"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"}
@@ -51,4 +51,52 @@ export declare function worktreeMismatchWarning(m: WorktreeIndexMismatch): strin
51
51
  * the agent is already reading — a multi-line block would bury the result.
52
52
  */
53
53
  export declare function worktreeMismatchNotice(m: WorktreeIndexMismatch): string;
54
+ /**
55
+ * The checkout's current HEAD: commit sha plus branch name (`null` on a
56
+ * detached HEAD). Returns null outside a git repo, when git is missing, or
57
+ * when the repo has no commit yet. Never throws.
58
+ */
59
+ export declare function readGitHead(dir: string): {
60
+ branch: string | null;
61
+ commit: string;
62
+ } | null;
63
+ /**
64
+ * Fingerprint of the uncommitted tracked state under `dir` (outside
65
+ * `.specship/`): a hash over `git status --porcelain --untracked-files=no`
66
+ * plus `git diff HEAD`. Two calls return the same value exactly when the
67
+ * working tree's tracked changes are identical — so an index synced after an
68
+ * edit is fresh until the edits change again. Null when git can't answer.
69
+ */
70
+ export declare function uncommittedTrackedFingerprint(dir: string): string | null;
71
+ export type IndexStaleReason = 'commit-moved' | 'uncommitted-changes';
72
+ export interface IndexFreshness {
73
+ /** Branch the index was built on; null when built on a detached HEAD. */
74
+ indexedBranch: string | null;
75
+ indexedCommit: string;
76
+ /** Branch currently checked out; null on a detached HEAD. */
77
+ headBranch: string | null;
78
+ headCommit: string;
79
+ stale: boolean;
80
+ reasons: IndexStaleReason[];
81
+ }
82
+ /**
83
+ * Pure staleness verdict. `worktreeChanged` is true when the checkout's
84
+ * uncommitted tracked changes differ from those present at index time.
85
+ */
86
+ export declare function computeIndexFreshness(recorded: {
87
+ branch: string | null;
88
+ commit: string;
89
+ }, head: {
90
+ branch: string | null;
91
+ commit: string;
92
+ }, worktreeChanged: boolean): IndexFreshness;
93
+ /** One-line staleness notice naming `specship sync` as the fix. */
94
+ export declare function indexStaleNotice(f: IndexFreshness): string;
95
+ /** `ref (branch)` / `ref (detached)` label for human output. */
96
+ export declare function formatRevision(branch: string | null, commit: string): string;
97
+ /**
98
+ * The `specship status --json` fields for a freshness verdict. Empty when
99
+ * freshness is null (no git / nothing recorded), so the keys are absent.
100
+ */
101
+ export declare function indexFreshnessJsonFields(f: IndexFreshness | null): Record<string, unknown>;
54
102
  //# sourceMappingURL=worktree.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/sync/worktree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY1D;AAED,MAAM,WAAW,qBAAqB;IACpC,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,qBAAqB,GAAG,IAAI,CAa9B;AAED,gEAAgE;AAChE,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM,CASxE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAOvE"}
1
+ {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/sync/worktree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY1D;AAED,MAAM,WAAW,qBAAqB;IACpC,qDAAqD;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,qBAAqB,GAAG,IAAI,CAa9B;AAED,gEAAgE;AAChE,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM,CASxE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAOvE;AAwBD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMzF;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOxE;AAED,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG,qBAAqB,CAAC;AAEtE,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACnD,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC/C,eAAe,EAAE,OAAO,GACvB,cAAc,CAYhB;AAED,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAU1D;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAU1F"}