spec-cat 0.1.13 → 0.1.14

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 (221) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{CPqjerP3.js → C9YFwlVG.js} +1 -1
  3. package/.output/public/_nuxt/CkZELJoz.js +122 -0
  4. package/.output/public/_nuxt/CpSdCo6F.js +1 -0
  5. package/.output/public/_nuxt/{Djrn6aq0.js → CwGiOvuj.js} +2 -2
  6. package/.output/public/_nuxt/{dYG8t45S.js → Cy9osphj.js} +1 -1
  7. package/.output/public/_nuxt/D14Nt8oq.js +1 -0
  8. package/.output/public/_nuxt/DQ8x7AHg.js +1 -0
  9. package/.output/public/_nuxt/{ASOk6VwA.js → Do9K5d62.js} +1 -1
  10. package/.output/public/_nuxt/DqVSe5UI.js +1 -0
  11. package/.output/public/_nuxt/builds/latest.json +1 -1
  12. package/.output/public/_nuxt/builds/meta/c4ed4e48-2de2-41d6-b09b-c785eac1d36d.json +1 -0
  13. package/.output/public/_nuxt/builds/meta/dev.json +1 -0
  14. package/.output/public/_nuxt/entry.CJqUIF8E.css +1 -0
  15. package/.output/public/_nuxt/{DqCsQSnP.js → vkftdPXk.js} +1 -1
  16. package/.output/server/chunks/_/aiProviderRegistry.mjs +36 -0
  17. package/.output/server/chunks/_/aiProviderRegistry.mjs.map +1 -0
  18. package/.output/server/chunks/_/aiProviderSelection.mjs +76 -0
  19. package/.output/server/chunks/_/aiProviderSelection.mjs.map +1 -0
  20. package/.output/server/chunks/_/chat.mjs.map +1 -1
  21. package/.output/server/chunks/_/claude.mjs +163 -0
  22. package/.output/server/chunks/_/claude.mjs.map +1 -0
  23. package/.output/server/chunks/_/claudeProvider.mjs +6 -6
  24. package/.output/server/chunks/_/claudeService.mjs +85 -0
  25. package/.output/server/chunks/_/claudeService.mjs.map +1 -0
  26. package/.output/server/chunks/_/codexProvider.mjs +1 -21
  27. package/.output/server/chunks/_/codexProvider.mjs.map +1 -1
  28. package/.output/server/chunks/_/git.mjs +1 -1
  29. package/.output/server/chunks/_/providerProcessError.mjs +1 -1
  30. package/.output/server/chunks/_/skillRegistry.mjs +249 -0
  31. package/.output/server/chunks/_/skillRegistry.mjs.map +1 -0
  32. package/.output/server/chunks/_/validateWorktree.mjs +27 -3
  33. package/.output/server/chunks/_/validateWorktree.mjs.map +1 -1
  34. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  35. package/.output/server/chunks/build/client.precomputed.mjs.map +1 -1
  36. package/.output/server/chunks/nitro/nitro.mjs +704 -1869
  37. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  38. package/.output/server/chunks/routes/_ws.mjs +4 -3
  39. package/.output/server/chunks/routes/_ws.mjs.map +1 -1
  40. package/.output/server/chunks/routes/api/ai/providers.get.mjs +3 -5
  41. package/.output/server/chunks/routes/api/ai/providers.get.mjs.map +1 -1
  42. package/.output/server/chunks/routes/api/chat/compare.get.mjs +2 -5
  43. package/.output/server/chunks/routes/api/chat/compare.get.mjs.map +1 -1
  44. package/.output/server/chunks/routes/api/chat/context.get.mjs +2 -5
  45. package/.output/server/chunks/routes/api/chat/context.get.mjs.map +1 -1
  46. package/.output/server/chunks/routes/api/chat/finalize.post.mjs +3 -2
  47. package/.output/server/chunks/routes/api/chat/finalize.post.mjs.map +1 -1
  48. package/.output/server/chunks/routes/api/chat/generate-commit-message.post.mjs +6 -3
  49. package/.output/server/chunks/routes/api/chat/generate-commit-message.post.mjs.map +1 -1
  50. package/.output/server/chunks/routes/api/chat/preview-sync.post.mjs +2 -3
  51. package/.output/server/chunks/routes/api/chat/preview-sync.post.mjs.map +1 -1
  52. package/.output/server/chunks/routes/api/chat/preview.delete.mjs +2 -3
  53. package/.output/server/chunks/routes/api/chat/preview.delete.mjs.map +1 -1
  54. package/.output/server/chunks/routes/api/chat/preview.post.mjs +2 -3
  55. package/.output/server/chunks/routes/api/chat/preview.post.mjs.map +1 -1
  56. package/.output/server/chunks/routes/api/chat/rebase.post.mjs +2 -3
  57. package/.output/server/chunks/routes/api/chat/rebase.post.mjs.map +1 -1
  58. package/.output/server/chunks/routes/api/chat/worktree-commit.post.mjs +4 -3
  59. package/.output/server/chunks/routes/api/chat/worktree-commit.post.mjs.map +1 -1
  60. package/.output/server/chunks/routes/api/chat/worktree.delete.mjs +1 -2
  61. package/.output/server/chunks/routes/api/chat/worktree.delete.mjs.map +1 -1
  62. package/.output/server/chunks/routes/api/chat/worktree.post.mjs +4 -8
  63. package/.output/server/chunks/routes/api/chat/worktree.post.mjs.map +1 -1
  64. package/.output/server/chunks/routes/api/chat.post.mjs +4 -5
  65. package/.output/server/chunks/routes/api/chat.post.mjs.map +1 -1
  66. package/.output/server/chunks/routes/api/conversations/_conversationId/archive.post.mjs +1 -2
  67. package/.output/server/chunks/routes/api/conversations/_conversationId/archive.post.mjs.map +1 -1
  68. package/.output/server/chunks/routes/api/conversations/archives/_archiveId/restore.post.mjs +2 -3
  69. package/.output/server/chunks/routes/api/conversations/archives/_archiveId/restore.post.mjs.map +1 -1
  70. package/.output/server/chunks/routes/api/conversations/archives/_archiveId_.delete.mjs +2 -5
  71. package/.output/server/chunks/routes/api/conversations/archives/_archiveId_.delete.mjs.map +1 -1
  72. package/.output/server/chunks/routes/api/conversations/archives.get.mjs +2 -5
  73. package/.output/server/chunks/routes/api/conversations/archives.get.mjs.map +1 -1
  74. package/.output/server/chunks/routes/api/conversations/update.post.mjs +2 -5
  75. package/.output/server/chunks/routes/api/conversations/update.post.mjs.map +1 -1
  76. package/.output/server/chunks/routes/api/conversations.get.mjs +2 -5
  77. package/.output/server/chunks/routes/api/conversations.get.mjs.map +1 -1
  78. package/.output/server/chunks/routes/api/conversations.post.mjs +2 -5
  79. package/.output/server/chunks/routes/api/conversations.post.mjs.map +1 -1
  80. package/.output/server/chunks/routes/api/cwd.get.mjs +2 -5
  81. package/.output/server/chunks/routes/api/cwd.get.mjs.map +1 -1
  82. package/.output/server/chunks/routes/api/git/branch-rename.post.mjs +2 -5
  83. package/.output/server/chunks/routes/api/git/branch-rename.post.mjs.map +1 -1
  84. package/.output/server/chunks/routes/api/git/branch.delete.mjs +2 -5
  85. package/.output/server/chunks/routes/api/git/branch.delete.mjs.map +1 -1
  86. package/.output/server/chunks/routes/api/git/branches.get.mjs +2 -5
  87. package/.output/server/chunks/routes/api/git/branches.get.mjs.map +1 -1
  88. package/.output/server/chunks/routes/api/git/checkout.post.mjs +2 -5
  89. package/.output/server/chunks/routes/api/git/checkout.post.mjs.map +1 -1
  90. package/.output/server/chunks/routes/api/git/cherry-pick.post.mjs +2 -5
  91. package/.output/server/chunks/routes/api/git/cherry-pick.post.mjs.map +1 -1
  92. package/.output/server/chunks/routes/api/git/clean.post.mjs +2 -5
  93. package/.output/server/chunks/routes/api/git/clean.post.mjs.map +1 -1
  94. package/.output/server/chunks/routes/api/git/commit/_id_.get.mjs +2 -5
  95. package/.output/server/chunks/routes/api/git/commit/_id_.get.mjs.map +1 -1
  96. package/.output/server/chunks/routes/api/git/commit.post.mjs +2 -5
  97. package/.output/server/chunks/routes/api/git/commit.post.mjs.map +1 -1
  98. package/.output/server/chunks/routes/api/git/diff.get.mjs +2 -5
  99. package/.output/server/chunks/routes/api/git/diff.get.mjs.map +1 -1
  100. package/.output/server/chunks/routes/api/git/fetch.post.mjs +2 -5
  101. package/.output/server/chunks/routes/api/git/fetch.post.mjs.map +1 -1
  102. package/.output/server/chunks/routes/api/git/file-diff.get.mjs +2 -5
  103. package/.output/server/chunks/routes/api/git/file-diff.get.mjs.map +1 -1
  104. package/.output/server/chunks/routes/api/git/graph.get.mjs +2 -5
  105. package/.output/server/chunks/routes/api/git/graph.get.mjs.map +1 -1
  106. package/.output/server/chunks/routes/api/git/log.get.mjs +2 -5
  107. package/.output/server/chunks/routes/api/git/log.get.mjs.map +1 -1
  108. package/.output/server/chunks/routes/api/git/merge-base.get.mjs +2 -5
  109. package/.output/server/chunks/routes/api/git/merge-base.get.mjs.map +1 -1
  110. package/.output/server/chunks/routes/api/git/merge.post.mjs +2 -5
  111. package/.output/server/chunks/routes/api/git/merge.post.mjs.map +1 -1
  112. package/.output/server/chunks/routes/api/git/pull.post.mjs +2 -5
  113. package/.output/server/chunks/routes/api/git/pull.post.mjs.map +1 -1
  114. package/.output/server/chunks/routes/api/git/push.post.mjs +2 -5
  115. package/.output/server/chunks/routes/api/git/push.post.mjs.map +1 -1
  116. package/.output/server/chunks/routes/api/git/rebase.post.mjs +2 -5
  117. package/.output/server/chunks/routes/api/git/rebase.post.mjs.map +1 -1
  118. package/.output/server/chunks/routes/api/git/remote.delete.mjs +2 -5
  119. package/.output/server/chunks/routes/api/git/remote.delete.mjs.map +1 -1
  120. package/.output/server/chunks/routes/api/git/remote.post.mjs +2 -5
  121. package/.output/server/chunks/routes/api/git/remote.post.mjs.map +1 -1
  122. package/.output/server/chunks/routes/api/git/remote.put.mjs +2 -5
  123. package/.output/server/chunks/routes/api/git/remote.put.mjs.map +1 -1
  124. package/.output/server/chunks/routes/api/git/remotes.get.mjs +2 -5
  125. package/.output/server/chunks/routes/api/git/remotes.get.mjs.map +1 -1
  126. package/.output/server/chunks/routes/api/git/reset.post.mjs +2 -5
  127. package/.output/server/chunks/routes/api/git/reset.post.mjs.map +1 -1
  128. package/.output/server/chunks/routes/api/git/revert.post.mjs +2 -5
  129. package/.output/server/chunks/routes/api/git/revert.post.mjs.map +1 -1
  130. package/.output/server/chunks/routes/api/git/show.get.mjs +2 -5
  131. package/.output/server/chunks/routes/api/git/show.get.mjs.map +1 -1
  132. package/.output/server/chunks/routes/api/git/stage.post.mjs +2 -5
  133. package/.output/server/chunks/routes/api/git/stage.post.mjs.map +1 -1
  134. package/.output/server/chunks/routes/api/git/stash-apply.post.mjs +2 -5
  135. package/.output/server/chunks/routes/api/git/stash-apply.post.mjs.map +1 -1
  136. package/.output/server/chunks/routes/api/git/stash-branch.post.mjs +2 -5
  137. package/.output/server/chunks/routes/api/git/stash-branch.post.mjs.map +1 -1
  138. package/.output/server/chunks/routes/api/git/stash-drop.post.mjs +2 -5
  139. package/.output/server/chunks/routes/api/git/stash-drop.post.mjs.map +1 -1
  140. package/.output/server/chunks/routes/api/git/stash-pop.post.mjs +2 -5
  141. package/.output/server/chunks/routes/api/git/stash-pop.post.mjs.map +1 -1
  142. package/.output/server/chunks/routes/api/git/stash.get.mjs +2 -5
  143. package/.output/server/chunks/routes/api/git/stash.get.mjs.map +1 -1
  144. package/.output/server/chunks/routes/api/git/stash.post.mjs +2 -5
  145. package/.output/server/chunks/routes/api/git/stash.post.mjs.map +1 -1
  146. package/.output/server/chunks/routes/api/git/state.get.mjs +2 -5
  147. package/.output/server/chunks/routes/api/git/state.get.mjs.map +1 -1
  148. package/.output/server/chunks/routes/api/git/status.get.mjs +2 -5
  149. package/.output/server/chunks/routes/api/git/status.get.mjs.map +1 -1
  150. package/.output/server/chunks/routes/api/git/tag/_name_.get.mjs +2 -5
  151. package/.output/server/chunks/routes/api/git/tag/_name_.get.mjs.map +1 -1
  152. package/.output/server/chunks/routes/api/git/tag-push.post.mjs +2 -5
  153. package/.output/server/chunks/routes/api/git/tag-push.post.mjs.map +1 -1
  154. package/.output/server/chunks/routes/api/git/tag.delete.mjs +2 -5
  155. package/.output/server/chunks/routes/api/git/tag.delete.mjs.map +1 -1
  156. package/.output/server/chunks/routes/api/git/tag.post.mjs +2 -5
  157. package/.output/server/chunks/routes/api/git/tag.post.mjs.map +1 -1
  158. package/.output/server/chunks/routes/api/git/unstage.post.mjs +2 -5
  159. package/.output/server/chunks/routes/api/git/unstage.post.mjs.map +1 -1
  160. package/.output/server/chunks/routes/api/index.get.mjs +4 -5
  161. package/.output/server/chunks/routes/api/index.get.mjs.map +1 -1
  162. package/.output/server/chunks/routes/api/index.get2.mjs +2 -3
  163. package/.output/server/chunks/routes/api/index.get2.mjs.map +1 -1
  164. package/.output/server/chunks/routes/api/index.post.mjs +2 -3
  165. package/.output/server/chunks/routes/api/index.post.mjs.map +1 -1
  166. package/.output/server/chunks/routes/api/rebase/abort.post.mjs +2 -3
  167. package/.output/server/chunks/routes/api/rebase/abort.post.mjs.map +1 -1
  168. package/.output/server/chunks/routes/api/rebase/ai-resolve.post.mjs +7 -5
  169. package/.output/server/chunks/routes/api/rebase/ai-resolve.post.mjs.map +1 -1
  170. package/.output/server/chunks/routes/api/rebase/conflicts.get.mjs +1 -2
  171. package/.output/server/chunks/routes/api/rebase/conflicts.get.mjs.map +1 -1
  172. package/.output/server/chunks/routes/api/rebase/continue-sync.post.mjs +2 -3
  173. package/.output/server/chunks/routes/api/rebase/continue-sync.post.mjs.map +1 -1
  174. package/.output/server/chunks/routes/api/rebase/continue.post.mjs +1 -2
  175. package/.output/server/chunks/routes/api/rebase/continue.post.mjs.map +1 -1
  176. package/.output/server/chunks/routes/api/rebase/resolve.put.mjs +1 -2
  177. package/.output/server/chunks/routes/api/rebase/resolve.put.mjs.map +1 -1
  178. package/.output/server/chunks/routes/api/repository/status.get.mjs +2 -5
  179. package/.output/server/chunks/routes/api/repository/status.get.mjs.map +1 -1
  180. package/.output/server/chunks/routes/api/settings.get.mjs +4 -7
  181. package/.output/server/chunks/routes/api/settings.get.mjs.map +1 -1
  182. package/.output/server/chunks/routes/api/settings.post.mjs +4 -5
  183. package/.output/server/chunks/routes/api/settings.post.mjs.map +1 -1
  184. package/.output/server/chunks/routes/api/skills/_skillId/prompt.post.mjs +8 -6
  185. package/.output/server/chunks/routes/api/skills/_skillId/prompt.post.mjs.map +1 -1
  186. package/.output/server/chunks/routes/api/specs/_featureId/_...filename_.get.mjs +1 -4
  187. package/.output/server/chunks/routes/api/specs/_featureId/_...filename_.get.mjs.map +1 -1
  188. package/.output/server/chunks/routes/api/specs/_featureId/_...filename_.put.mjs +1 -4
  189. package/.output/server/chunks/routes/api/specs/_featureId/_...filename_.put.mjs.map +1 -1
  190. package/.output/server/chunks/routes/api/specs/features.get.mjs +1 -4
  191. package/.output/server/chunks/routes/api/specs/features.get.mjs.map +1 -1
  192. package/.output/server/chunks/routes/api/specs/reindex.post.mjs +2 -5
  193. package/.output/server/chunks/routes/api/specs/reindex.post.mjs.map +1 -1
  194. package/.output/server/chunks/routes/api/specs/search.get.mjs +2 -5
  195. package/.output/server/chunks/routes/api/specs/search.get.mjs.map +1 -1
  196. package/.output/server/chunks/routes/api/specs/status.get.mjs +2 -5
  197. package/.output/server/chunks/routes/api/specs/status.get.mjs.map +1 -1
  198. package/.output/server/chunks/routes/api/worktrees/_name/switch.post.mjs +2 -3
  199. package/.output/server/chunks/routes/api/worktrees/_name/switch.post.mjs.map +1 -1
  200. package/.output/server/chunks/routes/api/worktrees/_name_.delete.mjs +1 -2
  201. package/.output/server/chunks/routes/api/worktrees/_name_.delete.mjs.map +1 -1
  202. package/.output/server/chunks/routes/git-watcher-ws.mjs +2 -5
  203. package/.output/server/chunks/routes/git-watcher-ws.mjs.map +1 -1
  204. package/.output/server/chunks/routes/renderer.mjs +2 -5
  205. package/.output/server/index.mjs +2 -5
  206. package/.output/server/index.mjs.map +1 -1
  207. package/.output/server/package.json +1 -1
  208. package/package.json +1 -1
  209. package/.output/public/_nuxt/B24bRLVA.js +0 -1
  210. package/.output/public/_nuxt/B3SzeM5g.js +0 -1
  211. package/.output/public/_nuxt/D3Ay6Tay.js +0 -126
  212. package/.output/public/_nuxt/DN_vgzh9.js +0 -1
  213. package/.output/public/_nuxt/afuUTAOf.js +0 -1
  214. package/.output/public/_nuxt/builds/meta/a94a9679-4171-4043-b507-a48b9a35f087.json +0 -1
  215. package/.output/public/_nuxt/entry.qjEvbHpP.css +0 -1
  216. package/.output/server/chunks/routes/api/auto-mode/status.get.mjs +0 -35
  217. package/.output/server/chunks/routes/api/auto-mode/status.get.mjs.map +0 -1
  218. package/.output/server/chunks/routes/api/auto-mode/toggle.post.mjs +0 -45
  219. package/.output/server/chunks/routes/api/auto-mode/toggle.post.mjs.map +0 -1
  220. package/.output/server/chunks/routes/auto-mode-ws.mjs +0 -65
  221. package/.output/server/chunks/routes/auto-mode-ws.mjs.map +0 -1
@@ -0,0 +1,249 @@
1
+ import { readFile, readdir } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ import { parse } from 'yaml';
5
+
6
+ const REQUIRED_FIELDS = ["id", "name", "description", "icon", "prerequisites", "promptTemplate"];
7
+ const BUILTIN_SKILLS = {
8
+ "better-spec": {
9
+ id: "better-spec",
10
+ name: "Better Spec",
11
+ description: "Validates spec documents against What/How/Track separation principle",
12
+ icon: "DocumentCheckIcon",
13
+ prerequisites: ["spec.md"],
14
+ promptTemplate: `You are a document architect specializing in software specification quality and structure. Your task is to ensure that spec documents for feature **{{featureId}}** follow a clear role-separation principle.
15
+
16
+ ## Feature Context
17
+
18
+ - **Feature ID**: {{featureId}}
19
+ - **Specs Directory**: {{specsDir}}
20
+ - **Available Documents**: {{availableDocuments}}
21
+
22
+ Read the available documents from the specs directory before proceeding with the analysis.
23
+
24
+ ## Core Principle
25
+
26
+ Spec documents MUST be separated into **three clear roles**:
27
+
28
+ | Document | Role | Question | Includes | Excludes |
29
+ |----------|------|----------|----------|----------|
30
+ | **spec.md** | What | "What are we building?" | User stories, acceptance criteria, requirements, success metrics, entity definitions | Tech stack, implementation methods, file paths, code examples |
31
+ | **plan.md** | How | "How are we building it?" | Technical context, architecture decisions, file structure, implementation approach, design artifact references | Detailed implementation steps, checkboxes, progress tracking |
32
+ | **tasks.md** | Track | "What have we completed?" | Implementation task list, dependencies, checkboxes, progress, execution order | Requirements definitions, design decisions |
33
+
34
+ ## Validation Process
35
+
36
+ ### 1. spec.md Validation (What Document)
37
+
38
+ **Correct content:**
39
+ - User Stories (User Story N - Title)
40
+ - Acceptance Scenarios (Given/When/Then)
41
+ - Functional Requirements (FR-XXX)
42
+ - Key Entities (entity definitions)
43
+ - Success Criteria
44
+ - Edge Cases
45
+ - Assumptions
46
+
47
+ **Violations (should be in plan.md):**
48
+ - Technical Context (tech stack, versions)
49
+ - Project/Source Structure (file paths, directory structure)
50
+ - Implementation Approach
51
+ - Database schema details (column types, indexes)
52
+ - API endpoint path details (\`/api/v1/xxx\`)
53
+ - Code examples or snippets
54
+
55
+ ### 2. plan.md Validation (How Document)
56
+
57
+ **Correct content:**
58
+ - Summary (feature overview)
59
+ - Technical Context (tech stack, dependencies, constraints)
60
+ - Constitution Check
61
+ - Project Structure (source code structure)
62
+ - Implementation Approach
63
+ - Key Design Decisions
64
+ - Generated Artifacts references (research.md, data-model.md, contracts/)
65
+
66
+ **Violations from spec.md (should reference, not copy):**
67
+ - Full User Story copies
68
+ - Acceptance Scenarios duplication
69
+ - Functional Requirements restatement
70
+
71
+ **Violations for tasks.md (should be in tasks.md):**
72
+ - \`- [ ]\` or \`- [x]\` checkboxes
73
+ - Detailed implementation steps (T001, T002...)
74
+ - Progress indicators
75
+
76
+ ### 3. tasks.md Validation (Track Document)
77
+
78
+ **Correct content:**
79
+ - Task list (T001, T002...)
80
+ - Checkboxes (\`- [ ]\`, \`- [x]\`)
81
+ - Phase divisions (Phase 1: Setup, Phase 2: Implementation)
82
+ - Dependency markers ([P] = parallel, [US1] = User Story 1)
83
+ - File path mentions (files to modify)
84
+ - Checkpoints
85
+ - Summary tables
86
+
87
+ **Violations:**
88
+ - Detailed requirements (should reference spec.md)
89
+ - Design decision rationale (should reference plan.md)
90
+ - Constitution Check duplication
91
+
92
+ ### 4. Cross-Document Consistency
93
+
94
+ **Reference integrity:**
95
+ - spec.md User Stories \u2192 tasks.md [US1], [US2] tags mapping
96
+ - spec.md FR-XXX \u2192 tasks.md corresponding implementation tasks
97
+ - plan.md file structure \u2192 tasks.md file paths match
98
+
99
+ ## Exceptions
100
+
101
+ The following are NOT considered violations:
102
+ 1. **spec.md Key Entities mentioning basic field types** \u2014 entity definitions are part of "What"
103
+ 2. **plan.md Summary briefly referencing spec content** \u2014 minimal context summaries are allowed
104
+ 3. **tasks.md mentioning file paths for implementation** \u2014 essential information for task execution
105
+
106
+ ## Report Format
107
+
108
+ Produce a structured validation report with:
109
+ 1. Summary (documents checked, issues found, severity)
110
+ 2. Per-document validation (correct structure, violations with line references)
111
+ 3. Cross-document consistency check
112
+ 4. Aggressive remediation actions (what to move where, with exact replacement text)
113
+ 5. Priority-ordered fix plan that resolves "critical" issues first
114
+
115
+ For each violation, include:
116
+ - The problematic section/line
117
+ - What the issue is
118
+ - Where the content should go
119
+ - Why the move is necessary
120
+ - Exact patch-ready replacement text (not only high-level suggestions)
121
+
122
+ ## Enforcement Mode
123
+
124
+ - Prefer direct rewrites over passive recommendations.
125
+ - When a section violates role boundaries, provide concrete edited content for the target document.
126
+ - If multiple fixes are possible, choose the option with highest FR traceability and lowest ambiguity.
127
+ - Do not defer obvious fixes; produce immediately applicable edits.
128
+
129
+ ## Completion Rules
130
+
131
+ - Never end by asking whether to proceed with fixes.
132
+ - Do not output "Would you like me to...?" style follow-up questions.
133
+ - If fixes are identifiable, apply them immediately with concrete patch-ready edits in the current run.
134
+ - Finish with "Applied Changes" and "Remaining Blockers" (if any), not a permission request.
135
+
136
+ **Goal**: Each document should be faithful to its role only, so anyone reading a document gets exactly the information they expect:
137
+ - Reading spec.md \u2192 understand **what** this feature is
138
+ - Reading plan.md \u2192 understand **how** this feature is built
139
+ - Reading tasks.md \u2192 understand **where** progress stands`
140
+ }
141
+ };
142
+ function parseSkillFile(content, filename) {
143
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
144
+ if (!match) {
145
+ console.warn(`[skills] Skipping ${filename}: missing YAML frontmatter`);
146
+ return null;
147
+ }
148
+ let frontmatter;
149
+ try {
150
+ frontmatter = parse(match[1]);
151
+ } catch {
152
+ console.warn(`[skills] Skipping ${filename}: invalid YAML frontmatter`);
153
+ return null;
154
+ }
155
+ if (!frontmatter || typeof frontmatter !== "object") {
156
+ console.warn(`[skills] Skipping ${filename}: empty YAML frontmatter`);
157
+ return null;
158
+ }
159
+ const promptTemplate = match[2].trim();
160
+ if (!promptTemplate) {
161
+ console.warn(`[skills] Skipping ${filename}: empty prompt template body`);
162
+ return null;
163
+ }
164
+ const skill = {
165
+ id: String(frontmatter.id || ""),
166
+ name: String(frontmatter.name || ""),
167
+ description: String(frontmatter.description || ""),
168
+ icon: String(frontmatter.icon || ""),
169
+ prerequisites: Array.isArray(frontmatter.prerequisites) ? frontmatter.prerequisites.map(String) : [],
170
+ promptTemplate
171
+ };
172
+ const missing = REQUIRED_FIELDS.filter((field) => {
173
+ if (field === "prerequisites") return false;
174
+ if (field === "promptTemplate") return false;
175
+ return !skill[field];
176
+ });
177
+ if (missing.length > 0) {
178
+ console.warn(`[skills] Skipping ${filename}: missing required fields: ${missing.join(", ")}`);
179
+ return null;
180
+ }
181
+ return skill;
182
+ }
183
+ async function loadSkills(projectDir) {
184
+ const skillsDir = join(projectDir, "skills");
185
+ if (!existsSync(skillsDir)) {
186
+ return Object.values(BUILTIN_SKILLS);
187
+ }
188
+ let entries;
189
+ try {
190
+ entries = await readdir(skillsDir);
191
+ } catch {
192
+ console.warn("[skills] Failed to read skills directory");
193
+ return Object.values(BUILTIN_SKILLS);
194
+ }
195
+ const mdFiles = entries.filter((f) => f.endsWith(".md"));
196
+ const skills = [];
197
+ const seenIds = /* @__PURE__ */ new Set();
198
+ for (const filename of mdFiles) {
199
+ const filepath = join(skillsDir, filename);
200
+ let content;
201
+ try {
202
+ content = await readFile(filepath, "utf-8");
203
+ } catch {
204
+ console.warn(`[skills] Skipping ${filename}: failed to read file`);
205
+ continue;
206
+ }
207
+ if (!content.trim()) {
208
+ console.warn(`[skills] Skipping ${filename}: empty file`);
209
+ continue;
210
+ }
211
+ const skill = parseSkillFile(content, filename);
212
+ if (!skill) continue;
213
+ if (seenIds.has(skill.id)) {
214
+ console.warn(`[skills] Skipping ${filename}: duplicate skill ID "${skill.id}"`);
215
+ continue;
216
+ }
217
+ seenIds.add(skill.id);
218
+ skills.push(skill);
219
+ }
220
+ for (const [id, skill] of Object.entries(BUILTIN_SKILLS)) {
221
+ if (!seenIds.has(id)) {
222
+ skills.push(skill);
223
+ }
224
+ }
225
+ return skills;
226
+ }
227
+ async function loadSkill(projectDir, skillId) {
228
+ var _a, _b, _c, _d, _e;
229
+ const filepath = join(projectDir, "skills", `${skillId}.md`);
230
+ if (!existsSync(filepath)) {
231
+ return (_a = BUILTIN_SKILLS[skillId]) != null ? _a : null;
232
+ }
233
+ let content;
234
+ try {
235
+ content = await readFile(filepath, "utf-8");
236
+ } catch {
237
+ return (_b = BUILTIN_SKILLS[skillId]) != null ? _b : null;
238
+ }
239
+ if (!content.trim()) {
240
+ return (_c = BUILTIN_SKILLS[skillId]) != null ? _c : null;
241
+ }
242
+ return (_e = (_d = parseSkillFile(content, `${skillId}.md`)) != null ? _d : BUILTIN_SKILLS[skillId]) != null ? _e : null;
243
+ }
244
+ function renderPrompt(skill, context) {
245
+ return skill.promptTemplate.replace(/\{\{featureId\}\}/g, context.featureId).replace(/\{\{specsDir\}\}/g, resolve(context.specsDir)).replace(/\{\{availableDocuments\}\}/g, context.availableDocuments.join(", "));
246
+ }
247
+
248
+ export { loadSkills as a, loadSkill as l, renderPrompt as r };
249
+ //# sourceMappingURL=skillRegistry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skillRegistry.mjs","sources":["../../../../server/utils/skillRegistry.ts"],"names":["parseYaml"],"mappings":"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"}
@@ -1,13 +1,37 @@
1
1
  import { c as createError } from '../nitro/nitro.mjs';
2
- import { existsSync } from 'node:fs';
2
+ import { existsSync, realpathSync } from 'node:fs';
3
+ import { resolve, basename } from 'node:path';
3
4
 
5
+ const ALLOWED_ROOT_PREFIXES = ["/tmp/", "/private/tmp/"];
6
+ const ALLOWED_WORKTREE_NAME_PATTERNS = [
7
+ /^sc-[a-z0-9-]+$/,
8
+ // Chat worktrees: sc-<conversationId> or sc-<featureId>-<conversationId>
9
+ /^[a-z0-9][a-z0-9-]*-[a-z0-9]{8}$/
10
+ // Feature worktrees: <feature-or-branch-name>-<randomId>
11
+ ];
12
+ function hasAllowedRootPrefix(path) {
13
+ return ALLOWED_ROOT_PREFIXES.some((prefix) => path.startsWith(prefix));
14
+ }
15
+ function hasAllowedWorktreeName(path) {
16
+ const dirName = basename(path);
17
+ return ALLOWED_WORKTREE_NAME_PATTERNS.some((pattern) => pattern.test(dirName));
18
+ }
4
19
  function validateWorktreePath(worktreePath) {
5
- if (!worktreePath.startsWith("/tmp/sc-")) {
20
+ const normalizedInputPath = resolve(worktreePath);
21
+ if (!hasAllowedRootPrefix(normalizedInputPath) || !hasAllowedWorktreeName(normalizedInputPath)) {
6
22
  throw createError({ statusCode: 403, message: "Invalid worktree path" });
7
23
  }
8
- if (!existsSync(worktreePath)) {
24
+ if (!existsSync(normalizedInputPath)) {
9
25
  throw createError({ statusCode: 404, message: "Worktree not found" });
10
26
  }
27
+ let normalizedRealPath = normalizedInputPath;
28
+ try {
29
+ normalizedRealPath = realpathSync(normalizedInputPath);
30
+ } catch {
31
+ }
32
+ if (!hasAllowedRootPrefix(normalizedRealPath) || !hasAllowedWorktreeName(normalizedRealPath)) {
33
+ throw createError({ statusCode: 403, message: "Invalid worktree path" });
34
+ }
11
35
  }
12
36
  function validateFilePath(filePath) {
13
37
  if (filePath.includes("..") || filePath.startsWith("/")) {
@@ -1 +1 @@
1
- {"version":3,"file":"validateWorktree.mjs","sources":["../../../../server/utils/validateWorktree.ts"],"names":[],"mappings":";;;AAEA,SAAA,qBAAA,YAAA,EAAA;AACA,EAAA,IAAA,CAAA,YAAA,CAAA,UAAA,CAAA,UAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,yBAAA,CAAA;AAAA,EACA;AACA,EAAA,IAAA,CAAA,UAAA,CAAA,YAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,sBAAA,CAAA;AAAA,EACA;AACA;AAEA,SAAA,iBAAA,QAAA,EAAA;AACA,EAAA,IAAA,SAAA,QAAA,CAAA,IAAA,KAAA,QAAA,CAAA,UAAA,CAAA,GAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,qBAAA,CAAA;AAAA,EACA;AACA;;;;"}
1
+ {"version":3,"file":"validateWorktree.mjs","sources":["../../../../server/utils/validateWorktree.ts"],"names":[],"mappings":";;;;AAGA,MAAA,qBAAA,GAAA,CAAA,OAAA,EAAA,eAAA,CAAA;AACA,MAAA,8BAAA,GAAA;AAAA,EACA,iBAAA;AAAA;AAAA,EACA;AAAA;AACA,CAAA;AAEA,SAAA,qBAAA,IAAA,EAAA;AACA,EAAA,OAAA,sBAAA,IAAA,CAAA,CAAA,MAAA,KAAA,IAAA,CAAA,UAAA,CAAA,MAAA,CAAA,CAAA;AACA;AAEA,SAAA,uBAAA,IAAA,EAAA;AACA,EAAA,MAAA,OAAA,GAAA,SAAA,IAAA,CAAA;AACA,EAAA,OAAA,+BAAA,IAAA,CAAA,CAAA,OAAA,KAAA,OAAA,CAAA,IAAA,CAAA,OAAA,CAAA,CAAA;AACA;AAEA,SAAA,qBAAA,YAAA,EAAA;AACA,EAAA,MAAA,mBAAA,GAAA,QAAA,YAAA,CAAA;AACA,EAAA,IAAA,CAAA,oBAAA,CAAA,mBAAA,KAAA,CAAA,sBAAA,CAAA,mBAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,yBAAA,CAAA;AAAA,EACA;AAEA,EAAA,IAAA,CAAA,UAAA,CAAA,mBAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,sBAAA,CAAA;AAAA,EACA;AAGA,EAAA,IAAA,kBAAA,GAAA,mBAAA;AACA,EAAA,IAAA;AACA,IAAA,kBAAA,GAAA,aAAA,mBAAA,CAAA;AAAA,EACA,CAAA,CAAA,MAAA;AAAA,EAEA;AAEA,EAAA,IAAA,CAAA,oBAAA,CAAA,kBAAA,KAAA,CAAA,sBAAA,CAAA,kBAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,yBAAA,CAAA;AAAA,EACA;AACA;AAEA,SAAA,iBAAA,QAAA,EAAA;AACA,EAAA,IAAA,SAAA,QAAA,CAAA,IAAA,KAAA,QAAA,CAAA,UAAA,CAAA,GAAA,CAAA,EAAA;AACA,IAAA,MAAA,YAAA,EAAA,UAAA,EAAA,GAAA,EAAA,OAAA,EAAA,qBAAA,CAAA;AAAA,EACA;AACA;;;;"}