@shrkcrft/cli 0.1.0-alpha.2 → 0.1.0-alpha.20

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 (228) hide show
  1. package/dist/audit/knowledge-audit-llm.d.ts +19 -0
  2. package/dist/audit/knowledge-audit-llm.d.ts.map +1 -0
  3. package/dist/audit/knowledge-audit-llm.js +164 -0
  4. package/dist/audit/knowledge-audit.d.ts +61 -0
  5. package/dist/audit/knowledge-audit.d.ts.map +1 -0
  6. package/dist/audit/knowledge-audit.js +203 -0
  7. package/dist/audit/knowledge-fix-plan-llm.d.ts +11 -0
  8. package/dist/audit/knowledge-fix-plan-llm.d.ts.map +1 -0
  9. package/dist/audit/knowledge-fix-plan-llm.js +141 -0
  10. package/dist/audit/knowledge-fix-plan.d.ts +41 -0
  11. package/dist/audit/knowledge-fix-plan.d.ts.map +1 -0
  12. package/dist/audit/knowledge-fix-plan.js +125 -0
  13. package/dist/audit/pipeline-audit-llm.d.ts +11 -0
  14. package/dist/audit/pipeline-audit-llm.d.ts.map +1 -0
  15. package/dist/audit/pipeline-audit-llm.js +134 -0
  16. package/dist/audit/pipeline-audit.d.ts +69 -0
  17. package/dist/audit/pipeline-audit.d.ts.map +1 -0
  18. package/dist/audit/pipeline-audit.js +166 -0
  19. package/dist/audit/templates-audit-llm.d.ts +19 -0
  20. package/dist/audit/templates-audit-llm.d.ts.map +1 -0
  21. package/dist/audit/templates-audit-llm.js +207 -0
  22. package/dist/audit/templates-audit.d.ts +63 -0
  23. package/dist/audit/templates-audit.d.ts.map +1 -0
  24. package/dist/audit/templates-audit.js +171 -0
  25. package/dist/audit/templates-fix-plan-llm.d.ts +19 -0
  26. package/dist/audit/templates-fix-plan-llm.d.ts.map +1 -0
  27. package/dist/audit/templates-fix-plan-llm.js +162 -0
  28. package/dist/audit/templates-fix-plan.d.ts +37 -0
  29. package/dist/audit/templates-fix-plan.d.ts.map +1 -0
  30. package/dist/audit/templates-fix-plan.js +174 -0
  31. package/dist/command-registry.d.ts +28 -0
  32. package/dist/command-registry.d.ts.map +1 -1
  33. package/dist/command-registry.js +91 -1
  34. package/dist/commands/ai-status.command.d.ts +19 -0
  35. package/dist/commands/ai-status.command.d.ts.map +1 -0
  36. package/dist/commands/ai-status.command.js +94 -0
  37. package/dist/commands/api-diff.command.d.ts +11 -0
  38. package/dist/commands/api-diff.command.d.ts.map +1 -0
  39. package/dist/commands/api-diff.command.js +144 -0
  40. package/dist/commands/apply.command.d.ts.map +1 -1
  41. package/dist/commands/apply.command.js +10 -2
  42. package/dist/commands/arch.command.d.ts +9 -0
  43. package/dist/commands/arch.command.d.ts.map +1 -0
  44. package/dist/commands/arch.command.js +186 -0
  45. package/dist/commands/ask.command.d.ts.map +1 -1
  46. package/dist/commands/ask.command.js +10 -9
  47. package/dist/commands/cache-align.command.d.ts +12 -0
  48. package/dist/commands/cache-align.command.d.ts.map +1 -0
  49. package/dist/commands/cache-align.command.js +78 -0
  50. package/dist/commands/check.command.d.ts.map +1 -1
  51. package/dist/commands/check.command.js +19 -2
  52. package/dist/commands/code-intel.command.d.ts +18 -0
  53. package/dist/commands/code-intel.command.d.ts.map +1 -0
  54. package/dist/commands/code-intel.command.js +146 -0
  55. package/dist/commands/codemod.command.d.ts.map +1 -1
  56. package/dist/commands/codemod.command.js +27 -6
  57. package/dist/commands/command-catalog.d.ts +15 -3
  58. package/dist/commands/command-catalog.d.ts.map +1 -1
  59. package/dist/commands/command-catalog.js +387 -34
  60. package/dist/commands/commands.command.d.ts.map +1 -1
  61. package/dist/commands/commands.command.js +4 -4
  62. package/dist/commands/completion.command.d.ts +10 -0
  63. package/dist/commands/completion.command.d.ts.map +1 -0
  64. package/dist/commands/completion.command.js +121 -0
  65. package/dist/commands/compress.command.d.ts +8 -0
  66. package/dist/commands/compress.command.d.ts.map +1 -0
  67. package/dist/commands/compress.command.js +147 -0
  68. package/dist/commands/constructs.command.d.ts.map +1 -1
  69. package/dist/commands/constructs.command.js +89 -23
  70. package/dist/commands/context.command.d.ts.map +1 -1
  71. package/dist/commands/context.command.js +121 -1
  72. package/dist/commands/contract-gate.command.d.ts.map +1 -1
  73. package/dist/commands/contract-gate.command.js +5 -1
  74. package/dist/commands/delegate.command.d.ts +65 -0
  75. package/dist/commands/delegate.command.d.ts.map +1 -0
  76. package/dist/commands/delegate.command.js +657 -0
  77. package/dist/commands/deps-audit.command.d.ts +23 -0
  78. package/dist/commands/deps-audit.command.d.ts.map +1 -0
  79. package/dist/commands/deps-audit.command.js +270 -0
  80. package/dist/commands/dev.command.d.ts.map +1 -1
  81. package/dist/commands/dev.command.js +5 -1
  82. package/dist/commands/diff-check.command.d.ts +30 -0
  83. package/dist/commands/diff-check.command.d.ts.map +1 -0
  84. package/dist/commands/diff-check.command.js +210 -0
  85. package/dist/commands/doctor.command.d.ts.map +1 -1
  86. package/dist/commands/doctor.command.js +162 -10
  87. package/dist/commands/export.command.d.ts.map +1 -1
  88. package/dist/commands/export.command.js +76 -3
  89. package/dist/commands/framework.command.d.ts +12 -0
  90. package/dist/commands/framework.command.d.ts.map +1 -0
  91. package/dist/commands/framework.command.js +180 -0
  92. package/dist/commands/gate.command.d.ts +15 -0
  93. package/dist/commands/gate.command.d.ts.map +1 -0
  94. package/dist/commands/gate.command.js +300 -0
  95. package/dist/commands/gen.command.d.ts.map +1 -1
  96. package/dist/commands/gen.command.js +13 -1
  97. package/dist/commands/graph-code-subverbs.d.ts +33 -0
  98. package/dist/commands/graph-code-subverbs.d.ts.map +1 -0
  99. package/dist/commands/graph-code-subverbs.js +1366 -0
  100. package/dist/commands/graph.command.d.ts.map +1 -1
  101. package/dist/commands/graph.command.js +31 -2
  102. package/dist/commands/help.command.d.ts +4 -3
  103. package/dist/commands/help.command.d.ts.map +1 -1
  104. package/dist/commands/help.command.js +86 -18
  105. package/dist/commands/helper.command.js +1 -1
  106. package/dist/commands/impact.command.d.ts.map +1 -1
  107. package/dist/commands/impact.command.js +171 -1
  108. package/dist/commands/import.command.d.ts.map +1 -1
  109. package/dist/commands/import.command.js +121 -5
  110. package/dist/commands/ingest.command.d.ts.map +1 -1
  111. package/dist/commands/ingest.command.js +5 -1
  112. package/dist/commands/init.command.d.ts.map +1 -1
  113. package/dist/commands/init.command.js +174 -7
  114. package/dist/commands/knowledge-author.command.d.ts.map +1 -1
  115. package/dist/commands/knowledge-author.command.js +9 -0
  116. package/dist/commands/knowledge-propose.command.d.ts.map +1 -1
  117. package/dist/commands/knowledge-propose.command.js +4 -2
  118. package/dist/commands/knowledge.command.d.ts.map +1 -1
  119. package/dist/commands/knowledge.command.js +26 -3
  120. package/dist/commands/migrate.command.d.ts +13 -0
  121. package/dist/commands/migrate.command.d.ts.map +1 -0
  122. package/dist/commands/migrate.command.js +152 -0
  123. package/dist/commands/move-plan.command.d.ts +23 -0
  124. package/dist/commands/move-plan.command.d.ts.map +1 -0
  125. package/dist/commands/move-plan.command.js +360 -0
  126. package/dist/commands/packs-new.d.ts +1 -1
  127. package/dist/commands/packs-new.d.ts.map +1 -1
  128. package/dist/commands/packs-new.js +5 -36
  129. package/dist/commands/packs.command.d.ts.map +1 -1
  130. package/dist/commands/packs.command.js +2 -10
  131. package/dist/commands/plan-context.command.d.ts +11 -0
  132. package/dist/commands/plan-context.command.d.ts.map +1 -0
  133. package/dist/commands/plan-context.command.js +85 -0
  134. package/dist/commands/preflight.command.d.ts.map +1 -1
  135. package/dist/commands/preflight.command.js +15 -0
  136. package/dist/commands/profiles.command.js +4 -4
  137. package/dist/commands/recommend.command.d.ts +6 -0
  138. package/dist/commands/recommend.command.d.ts.map +1 -1
  139. package/dist/commands/recommend.command.js +119 -5
  140. package/dist/commands/release.command.js +13 -13
  141. package/dist/commands/rule-graph-subverbs.d.ts +3 -0
  142. package/dist/commands/rule-graph-subverbs.d.ts.map +1 -0
  143. package/dist/commands/rule-graph-subverbs.js +132 -0
  144. package/dist/commands/rules.command.d.ts.map +1 -1
  145. package/dist/commands/rules.command.js +20 -3
  146. package/dist/commands/scaffold-validate.command.d.ts +22 -0
  147. package/dist/commands/scaffold-validate.command.d.ts.map +1 -0
  148. package/dist/commands/scaffold-validate.command.js +215 -0
  149. package/dist/commands/search-structural.command.d.ts +18 -0
  150. package/dist/commands/search-structural.command.d.ts.map +1 -0
  151. package/dist/commands/search-structural.command.js +376 -0
  152. package/dist/commands/search.command.js +1 -1
  153. package/dist/commands/smart-context.command.d.ts +67 -0
  154. package/dist/commands/smart-context.command.d.ts.map +1 -0
  155. package/dist/commands/smart-context.command.js +4728 -0
  156. package/dist/commands/spike.command.d.ts +22 -0
  157. package/dist/commands/spike.command.d.ts.map +1 -0
  158. package/dist/commands/spike.command.js +235 -0
  159. package/dist/commands/surface.command.d.ts +1 -0
  160. package/dist/commands/surface.command.d.ts.map +1 -1
  161. package/dist/commands/surface.command.js +10 -3
  162. package/dist/commands/task-context.command.d.ts.map +1 -1
  163. package/dist/commands/task-context.command.js +5 -17
  164. package/dist/commands/task.command.d.ts.map +1 -1
  165. package/dist/commands/task.command.js +8 -2
  166. package/dist/commands/template-quality.command.d.ts.map +1 -1
  167. package/dist/commands/template-quality.command.js +39 -3
  168. package/dist/commands/templates.command.d.ts.map +1 -1
  169. package/dist/commands/templates.command.js +37 -2
  170. package/dist/commands/tests.command.d.ts.map +1 -1
  171. package/dist/commands/tests.command.js +13 -2
  172. package/dist/commands/watch.command.d.ts +26 -0
  173. package/dist/commands/watch.command.d.ts.map +1 -0
  174. package/dist/commands/watch.command.js +456 -0
  175. package/dist/dashboard/code-intelligence-data.d.ts +33 -0
  176. package/dist/dashboard/code-intelligence-data.d.ts.map +1 -0
  177. package/dist/dashboard/code-intelligence-data.js +329 -0
  178. package/dist/dashboard/dashboard-api-server.d.ts.map +1 -1
  179. package/dist/dashboard/dashboard-api-server.js +256 -2
  180. package/dist/dashboard/knowledge-ask.d.ts +4 -0
  181. package/dist/dashboard/knowledge-ask.d.ts.map +1 -0
  182. package/dist/dashboard/knowledge-ask.js +112 -0
  183. package/dist/env/load-dotenv.d.ts +15 -0
  184. package/dist/env/load-dotenv.d.ts.map +1 -0
  185. package/dist/env/load-dotenv.js +70 -0
  186. package/dist/export/claude-commands-export.d.ts +60 -0
  187. package/dist/export/claude-commands-export.d.ts.map +1 -0
  188. package/dist/export/claude-commands-export.js +276 -0
  189. package/dist/export/export-formats.d.ts +1 -1
  190. package/dist/export/export-formats.d.ts.map +1 -1
  191. package/dist/export/export-formats.js +139 -12
  192. package/dist/index.d.ts +3 -0
  193. package/dist/index.d.ts.map +1 -1
  194. package/dist/index.js +3 -0
  195. package/dist/init/init-templates.d.ts.map +1 -1
  196. package/dist/init/init-templates.js +133 -113
  197. package/dist/init/paths-advisory.d.ts +20 -0
  198. package/dist/init/paths-advisory.d.ts.map +1 -0
  199. package/dist/init/paths-advisory.js +88 -0
  200. package/dist/main.d.ts.map +1 -1
  201. package/dist/main.js +331 -17
  202. package/dist/output/ccr-store-config.d.ts +18 -0
  203. package/dist/output/ccr-store-config.d.ts.map +1 -0
  204. package/dist/output/ccr-store-config.js +41 -0
  205. package/dist/output/format-output.d.ts.map +1 -1
  206. package/dist/output/format-output.js +6 -1
  207. package/dist/output/output-compression.d.ts +15 -0
  208. package/dist/output/output-compression.d.ts.map +1 -0
  209. package/dist/output/output-compression.js +60 -0
  210. package/dist/output/resolve-compress-type.d.ts +22 -0
  211. package/dist/output/resolve-compress-type.d.ts.map +1 -0
  212. package/dist/output/resolve-compress-type.js +21 -0
  213. package/dist/output/watch-loop.d.ts +9 -1
  214. package/dist/output/watch-loop.d.ts.map +1 -1
  215. package/dist/output/watch-loop.js +13 -3
  216. package/dist/schemas/json-schemas.d.ts +384 -36
  217. package/dist/schemas/json-schemas.d.ts.map +1 -1
  218. package/dist/schemas/json-schemas.js +247 -36
  219. package/dist/surface/profiles.d.ts.map +1 -1
  220. package/dist/surface/profiles.js +54 -9
  221. package/dist/surface/surface-config-writer.d.ts.map +1 -1
  222. package/dist/surface/surface-config-writer.js +23 -11
  223. package/dist/validation/run-validation-loop.d.ts.map +1 -1
  224. package/dist/validation/run-validation-loop.js +5 -1
  225. package/package.json +35 -21
  226. package/dist/commands/plugin.command.d.ts +0 -11
  227. package/dist/commands/plugin.command.d.ts.map +0 -1
  228. package/dist/commands/plugin.command.js +0 -394
@@ -1,11 +1,28 @@
1
1
  import { aggregateActionHints, KnowledgeType } from '@shrkcrft/knowledge';
2
2
  import { priorityWeight } from '@shrkcrft/knowledge';
3
- const DEFAULT_OUTPUT_PATH = {
4
- 'agents-md': 'AGENTS.md',
5
- 'claude-md': 'CLAUDE.md',
6
- 'cursor-rules': '.cursor/rules/sharkcraft.mdc',
7
- 'copilot-instructions': '.github/copilot-instructions.md',
8
- };
3
+ function projectSlug(name) {
4
+ if (!name)
5
+ return 'project';
6
+ return (name
7
+ .toLowerCase()
8
+ .replace(/[^a-z0-9]+/g, '-')
9
+ .replace(/^-+|-+$/g, '')
10
+ .slice(0, 48) || 'project');
11
+ }
12
+ function defaultOutputFor(format, inspection) {
13
+ switch (format) {
14
+ case 'agents-md':
15
+ return 'AGENTS.md';
16
+ case 'claude-md':
17
+ return 'CLAUDE.md';
18
+ case 'claude-skill':
19
+ return `.claude/skills/${projectSlug(inspection.config?.projectName)}/SKILL.md`;
20
+ case 'cursor-rules':
21
+ return '.cursor/rules/sharkcraft.mdc';
22
+ case 'copilot-instructions':
23
+ return '.github/copilot-instructions.md';
24
+ }
25
+ }
9
26
  function selectTopByPriority(entries, limit) {
10
27
  return [...entries]
11
28
  .sort((a, b) => priorityWeight(b.priority) - priorityWeight(a.priority))
@@ -100,23 +117,131 @@ function renderBody(inspection, options) {
100
117
  }
101
118
  return sections.join('\n\n');
102
119
  }
120
+ /**
121
+ * Filter rules / paths to the high-signal subset for an inlined skill.
122
+ *
123
+ * Every rule the skill carries pays in Claude's context every time the
124
+ * skill is loaded. Low-priority items dilute the signal of the
125
+ * load-bearing ones (`Critical` safety + `High` architecture). We keep
126
+ * only Critical + High by default, falling back to "all" only if the
127
+ * filtered list is empty (e.g. a repo with no high-priority entries
128
+ * yet shouldn't ship an empty skill).
129
+ */
130
+ function filterHighSignal(entries) {
131
+ const filtered = entries.filter((e) => {
132
+ const p = String(e.priority).toLowerCase();
133
+ return p === 'critical' || p === 'high';
134
+ });
135
+ return filtered.length > 0 ? filtered : [...entries];
136
+ }
137
+ /**
138
+ * Render the body in tight, decision-driving form for the Claude Code
139
+ * Skill format. Skills get loaded into Claude's prompt when the skill's
140
+ * `description` matches the current task, so the body must be short and
141
+ * directly actionable — no preamble, no metadata about generation, no
142
+ * pipelines (Claude can run `shrk task` for those when needed).
143
+ *
144
+ * Sections:
145
+ * 1. Where files belong (path conventions, top N) — most-leveraged signal.
146
+ * 2. Rules to follow (Critical + High only) — pads context otherwise.
147
+ * 3. Do / Don't — forbidden actions and verification commands.
148
+ * 4. How to write code in this repo — the gen → review → apply loop
149
+ * verbatim, since Claude needs to know shrk is the write path.
150
+ */
151
+ function renderSkillBody(inspection, options) {
152
+ const { rules: allRules, paths: allPaths } = gatherRulesAndPaths(inspection, {
153
+ ...options,
154
+ // Pull more upfront, then filter down to high-signal — keeps the
155
+ // softcap-at-15 default but the inlined skill stays terse.
156
+ maxRules: options.maxRules ?? 24,
157
+ maxPaths: options.maxPaths ?? 18,
158
+ });
159
+ // Skills are inlined into the prompt — every entry costs Claude
160
+ // context. Only ship the items the user said are load-bearing.
161
+ const rules = filterHighSignal(allRules).slice(0, options.maxRules ?? 12);
162
+ const paths = filterHighSignal(allPaths).slice(0, options.maxPaths ?? 10);
163
+ const sections = [];
164
+ if (inspection.config?.description) {
165
+ sections.push(`## About this codebase\n\n${inspection.config.description}`);
166
+ }
167
+ const pathsBody = renderPathsSection(paths);
168
+ if (pathsBody) {
169
+ sections.push(`## Where files belong\n\nWhen creating or moving a file, place it according to these conventions:\n\n${pathsBody}`);
170
+ }
171
+ const rulesBody = renderRulesSection(rules);
172
+ if (rulesBody) {
173
+ sections.push(`## Rules this codebase follows\n\nApply these whenever you generate, modify, or review code:\n\n${rulesBody}`);
174
+ }
175
+ const agg = aggregateActionHints(inspection.knowledgeEntries);
176
+ const doDont = [];
177
+ if (agg.forbiddenActions.length) {
178
+ doDont.push('**Do not:**');
179
+ for (const f of agg.forbiddenActions.slice(0, 8))
180
+ doDont.push(`- ${f}`);
181
+ doDont.push('');
182
+ }
183
+ if (agg.verificationCommands.length) {
184
+ doDont.push('**Verify changes with:**');
185
+ for (const c of agg.verificationCommands.slice(0, 6))
186
+ doDont.push(`- \`${c}\``);
187
+ }
188
+ if (doDont.length) {
189
+ sections.push(`## Do / Don't\n\n${doDont.join('\n').trim()}`);
190
+ }
191
+ sections.push(`## How to write code in this repo\n\n` +
192
+ `This repository uses [SharkCraft](https://github.com/shrkcrft/sharkcraft) to gate writes — the CLI is the only write path, and writes go through a plan → review → apply loop.\n\n` +
193
+ `1. **Get a task packet** before non-trivial work: \`shrk task "<one-sentence task>"\` returns the focused rules, paths, templates, and verification commands for that task.\n` +
194
+ `2. **Scaffold via templates** instead of writing files freehand: \`shrk gen <template-id> <name> --dry-run --save-plan plan.json\` produces a signed plan.\n` +
195
+ `3. **Apply the plan** through the CLI: \`shrk apply plan.json --verify-signature\` — never write through MCP.\n` +
196
+ `4. **Check the result**: \`shrk check boundaries\` + the verification commands listed above.\n\n` +
197
+ `For ad-hoc questions about the codebase, query the MCP server (\`shrk mcp serve\`) or run \`shrk context --task "<query>"\` for token-budgeted context.`);
198
+ return sections.join('\n\n');
199
+ }
200
+ /**
201
+ * Build the YAML frontmatter for a Claude Code Skill. The `description`
202
+ * field is what Claude uses to decide whether to load this skill — keep
203
+ * it specific (project name + what's covered) so it doesn't trigger on
204
+ * unrelated tasks.
205
+ */
206
+ function renderSkillFrontmatter(inspection) {
207
+ const slug = projectSlug(inspection.config?.projectName);
208
+ const projectName = inspection.config?.projectName ?? slug;
209
+ const description = `Codebase rules, path conventions, and review gates for ${projectName}. ` +
210
+ `Use this skill whenever generating, modifying, or reviewing code in this repository — ` +
211
+ `it tells you the per-file path conventions, the architecture boundaries, the verification commands, ` +
212
+ `and the safe write path (CLI plan → review → apply).`;
213
+ return `---\nname: ${slug}\ndescription: ${JSON.stringify(description)}\n---`;
214
+ }
103
215
  export function renderExport(inspection, options) {
104
- const body = renderBody(inspection, options);
105
- const suggestedPath = DEFAULT_OUTPUT_PATH[options.format];
216
+ const suggestedPath = defaultOutputFor(options.format, inspection);
106
217
  let content = '';
107
218
  switch (options.format) {
108
- case 'agents-md':
219
+ case 'agents-md': {
220
+ const body = renderBody(inspection, options);
109
221
  content = `# Agents Guide\n\n${PREAMBLE}\n\n${body}\n`;
110
222
  break;
111
- case 'claude-md':
223
+ }
224
+ case 'claude-md': {
225
+ const body = renderBody(inspection, options);
112
226
  content = `# CLAUDE.md\n\n${PREAMBLE}\n\nThis file is read by Claude Code (claude.ai/code) at session start. Treat it as a compatibility view of the project's SharkCraft knowledge — use the MCP server (\`shrk mcp serve\`) for the live, queryable source of truth.\n\n${body}\n`;
113
227
  break;
228
+ }
229
+ case 'claude-skill': {
230
+ // Claude Code Skill: YAML frontmatter declares when to load this,
231
+ // body is tight decision-driving content. No preamble, no boilerplate
232
+ // — every token in here costs Claude context when loaded.
233
+ const frontmatter = renderSkillFrontmatter(inspection);
234
+ const projectName = inspection.config?.projectName ?? 'this codebase';
235
+ const body = renderSkillBody(inspection, options);
236
+ content = `${frontmatter}\n\n# ${projectName} — codebase guide\n\n${body}\n`;
237
+ break;
238
+ }
114
239
  case 'cursor-rules':
115
240
  // Cursor MDC frontmatter: leave alwaysApply off so the user can tune.
116
- content = `---\ndescription: SharkCraft project rules (auto-generated)\nalwaysApply: false\n---\n\n${PREAMBLE}\n\n${body}\n`;
241
+ content = `---\ndescription: SharkCraft project rules (auto-generated)\nalwaysApply: false\n---\n\n${PREAMBLE}\n\n${renderBody(inspection, options)}\n`;
117
242
  break;
118
243
  case 'copilot-instructions':
119
- content = `# Copilot instructions\n\n${PREAMBLE}\n\n${body}\n`;
244
+ content = `# Copilot instructions\n\n${PREAMBLE}\n\n${renderBody(inspection, options)}\n`;
120
245
  break;
121
246
  }
122
247
  return { format: options.format, suggestedPath, content };
@@ -124,12 +249,14 @@ export function renderExport(inspection, options) {
124
249
  export function isExportFormat(value) {
125
250
  return (value === 'agents-md' ||
126
251
  value === 'claude-md' ||
252
+ value === 'claude-skill' ||
127
253
  value === 'cursor-rules' ||
128
254
  value === 'copilot-instructions');
129
255
  }
130
256
  export const ALL_EXPORT_FORMATS = Object.freeze([
131
257
  'agents-md',
132
258
  'claude-md',
259
+ 'claude-skill',
133
260
  'cursor-rules',
134
261
  'copilot-instructions',
135
262
  ]);
package/dist/index.d.ts CHANGED
@@ -17,6 +17,9 @@ export { packsListCommand, packsGetCommand, packsInspectCommand, packsDoctorComm
17
17
  export { pipelinesListCommand, pipelinesGetCommand, pipelinesContextCommand, pipelinesPlanCommand, pipelinesScriptCommand, pipelinesNextCommand, } from './commands/pipelines.command.js';
18
18
  export { schemasListCommand, schemasGetCommand, schemasWriteCommand, } from './commands/schemas.command.js';
19
19
  export { versionCommand } from './commands/version.command.js';
20
+ export { compressCommand, expandCommand } from './commands/compress.command.js';
21
+ export { alignCommand, unalignCommand } from './commands/cache-align.command.js';
20
22
  export { makeHelpCommand } from './commands/help.command.js';
21
23
  export { buildRegistry, runCli } from './main.js';
24
+ export { buildWatchPlan, maybeRunInWatchMode, runWatchLoop, } from './output/watch-loop.js';
22
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,YAAY,GACb,MAAM,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -17,5 +17,8 @@ export { packsListCommand, packsGetCommand, packsInspectCommand, packsDoctorComm
17
17
  export { pipelinesListCommand, pipelinesGetCommand, pipelinesContextCommand, pipelinesPlanCommand, pipelinesScriptCommand, pipelinesNextCommand, } from "./commands/pipelines.command.js";
18
18
  export { schemasListCommand, schemasGetCommand, schemasWriteCommand, } from "./commands/schemas.command.js";
19
19
  export { versionCommand } from "./commands/version.command.js";
20
+ export { compressCommand, expandCommand } from "./commands/compress.command.js";
21
+ export { alignCommand, unalignCommand } from "./commands/cache-align.command.js";
20
22
  export { makeHelpCommand } from "./commands/help.command.js";
21
23
  export { buildRegistry, runCli } from "./main.js";
24
+ export { buildWatchPlan, maybeRunInWatchMode, runWatchLoop, } from "./output/watch-loop.js";
@@ -1 +1 @@
1
- {"version":3,"file":"init-templates.d.ts","sourceRoot":"","sources":["../../src/init/init-templates.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EA4Z1C,CAAC"}
1
+ {"version":3,"file":"init-templates.d.ts","sourceRoot":"","sources":["../../src/init/init-templates.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAUD,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EA2W1C,CAAC"}
@@ -1,9 +1,18 @@
1
+ // Self-contained scaffolding for `shrk init --legacy`. Every generated
2
+ // `sharkcraft/*.ts` file must work in a brand-new downstream repo where
3
+ // no `@shrkcrft/*` packages are installed beyond the CLI itself. The
4
+ // loaders (knowledge / templates / pipelines / path-conventions) are
5
+ // shape-agnostic — they accept any object with the required string
6
+ // fields — so each emitted file declares its own minimal helpers +
7
+ // enum-like constants inline.
1
8
  export const INIT_FILES = [
2
9
  {
3
10
  relativePath: 'sharkcraft.config.ts',
4
- content: `import { defineSharkCraftConfig } from '@shrkcrft/config';
11
+ content: `// Generated by \`shrk init --legacy\`. Plain default export — no
12
+ // @shrkcrft/* import required. The config loader validates this object
13
+ // by shape (zod), so the literal works without a helper call.
5
14
 
6
- export default defineSharkCraftConfig({
15
+ export default {
7
16
  projectName: 'my-project',
8
17
  description: 'A SharkCraft-powered repository.',
9
18
  knowledgeFiles: ['knowledge.ts'],
@@ -13,12 +22,36 @@ export default defineSharkCraftConfig({
13
22
  docsFiles: ['docs/overview.md', 'docs/architecture.md', 'docs/quick-start.md'],
14
23
  defaultMaxTokens: 4000,
15
24
  defaultScope: ['typescript'],
16
- });
25
+ };
17
26
  `,
18
27
  },
19
28
  {
20
29
  relativePath: 'knowledge.ts',
21
- content: `import { defineKnowledgeEntry, KnowledgeType, KnowledgePriority } from '@shrkcrft/knowledge';
30
+ content: `// Local helpers keep this file self-contained (no @shrkcrft/* imports).
31
+ // The knowledge loader is shape-agnostic; it accepts any object whose
32
+ // \`id\`, \`title\`, and \`content\` are strings.
33
+
34
+ const KnowledgePriority = {
35
+ Critical: 'critical',
36
+ High: 'high',
37
+ Medium: 'medium',
38
+ Low: 'low',
39
+ } as const;
40
+
41
+ const KnowledgeType = {
42
+ Rule: 'rule',
43
+ Path: 'path',
44
+ Template: 'template',
45
+ Architecture: 'architecture',
46
+ Technical: 'technical',
47
+ Convention: 'convention',
48
+ Workflow: 'workflow',
49
+ Warning: 'warning',
50
+ } as const;
51
+
52
+ function defineKnowledgeEntry<T>(entry: T): T {
53
+ return entry;
54
+ }
22
55
 
23
56
  export const projectOverview = defineKnowledgeEntry({
24
57
  id: 'project.overview',
@@ -67,8 +100,20 @@ export default [projectOverview, aiAgentBriefing, generationSafety];
67
100
  },
68
101
  {
69
102
  relativePath: 'rules.ts',
70
- content: `import { defineRule } from '@shrkcrft/rules';
71
- import { KnowledgePriority } from '@shrkcrft/knowledge';
103
+ content: `// Local helpers keep this file self-contained (no @shrkcrft/* imports).
104
+
105
+ const KnowledgePriority = {
106
+ Critical: 'critical',
107
+ High: 'high',
108
+ Medium: 'medium',
109
+ Low: 'low',
110
+ } as const;
111
+
112
+ const KnowledgeType = { Rule: 'rule' } as const;
113
+
114
+ function defineRule<T>(rule: T): T {
115
+ return { ...rule, type: KnowledgeType.Rule } as T;
116
+ }
72
117
 
73
118
  export const tsNamingClasses = defineRule({
74
119
  id: 'typescript.naming.classes',
@@ -142,81 +187,15 @@ export default [
142
187
  },
143
188
  {
144
189
  relativePath: 'paths.ts',
145
- content: `import { definePathConvention } from '@shrkcrft/paths';
146
- import { KnowledgePriority } from '@shrkcrft/knowledge';
147
-
148
- export const appSrc = definePathConvention({
149
- id: 'app.src',
150
- title: 'Application source root',
151
- path: 'src',
152
- description: 'All application source lives here.',
153
- priority: KnowledgePriority.Critical,
154
- scope: ['typescript'],
155
- tags: ['source-path', 'root'],
156
- appliesWhen: ['generate-code'],
157
- });
158
-
159
- export const services = definePathConvention({
160
- id: 'app.services',
161
- title: 'Application services',
162
- path: 'src/services',
163
- description: 'Application services live here.',
164
- priority: KnowledgePriority.High,
165
- scope: ['typescript', 'backend'],
166
- tags: ['service', 'source-path'],
167
- appliesWhen: ['generate-service', 'create-business-logic'],
168
- });
169
-
170
- export const utils = definePathConvention({
171
- id: 'app.utils',
172
- title: 'Utilities',
173
- path: 'src/utils',
174
- description: 'Pure functions, no side effects.',
175
- priority: KnowledgePriority.Medium,
176
- scope: ['typescript'],
177
- tags: ['util', 'source-path'],
178
- appliesWhen: ['generate-utility'],
179
- });
180
-
181
- export const features = definePathConvention({
182
- id: 'app.features',
183
- title: 'Feature folders',
184
- path: 'src/features',
185
- description: 'Vertical feature slices. Use this for end-to-end features.',
186
- priority: KnowledgePriority.Medium,
187
- scope: ['typescript'],
188
- tags: ['feature', 'source-path'],
189
- appliesWhen: ['generate-feature'],
190
- });
191
-
192
- export const tests = definePathConvention({
193
- id: 'app.tests',
194
- title: 'Test files',
195
- path: 'tests',
196
- description: 'Test files (or co-located *.spec.ts next to the unit under test).',
197
- priority: KnowledgePriority.Medium,
198
- scope: ['typescript', 'testing'],
199
- tags: ['test', 'source-path'],
200
- appliesWhen: ['generate-test'],
201
- });
202
-
203
- export const docs = definePathConvention({
204
- id: 'app.docs',
205
- title: 'Documentation',
206
- path: 'docs',
207
- description: 'Long-form human-readable docs (optional).',
208
- priority: KnowledgePriority.Low,
209
- scope: ['typescript'],
210
- tags: ['docs'],
211
- appliesWhen: ['add-docs'],
212
- });
213
-
214
- export default [appSrc, services, utils, features, tests, docs];
215
- `,
190
+ content: PATHS_PLACEHOLDER_CONTENT(),
216
191
  },
217
192
  {
218
193
  relativePath: 'templates.ts',
219
- content: `import { defineTemplate } from '@shrkcrft/templates';
194
+ content: `// Local helpers keep this file self-contained (no @shrkcrft/* imports).
195
+
196
+ function defineTemplate<T>(template: T): T {
197
+ return template;
198
+ }
220
199
 
221
200
  export const tsService = defineTemplate({
222
201
  id: 'typescript.service',
@@ -229,8 +208,8 @@ export const tsService = defineTemplate({
229
208
  { name: 'name', required: true, description: 'kebab-case file name (e.g. user-profile)' },
230
209
  { name: 'className', required: true, description: 'PascalCase class name (e.g. UserProfileService)' },
231
210
  ],
232
- targetPath: ({ name }) => \`src/services/\${name}.service.ts\`,
233
- content: ({ className }) => \`export class \${className} {
211
+ targetPath: ({ name }: { name: string }) => \`src/services/\${name}.service.ts\`,
212
+ content: ({ className }: { className: string }) => \`export class \${className} {
234
213
  constructor() {}
235
214
 
236
215
  init(): void {
@@ -253,42 +232,14 @@ export const tsUtility = defineTemplate({
253
232
  { name: 'name', required: true, description: 'kebab-case file name' },
254
233
  { name: 'camel', required: true, description: 'camelCase function name' },
255
234
  ],
256
- targetPath: ({ name }) => \`src/utils/\${name}.ts\`,
257
- content: ({ camel }) => \`export function \${camel}(input: unknown): unknown {
235
+ targetPath: ({ name }: { name: string }) => \`src/utils/\${name}.ts\`,
236
+ content: ({ camel }: { camel: string }) => \`export function \${camel}(input: unknown): unknown {
258
237
  return input;
259
238
  }
260
239
  \`,
261
240
  postGenerationNotes: ['Keep utilities pure. No side effects, no shared mutable state.'],
262
241
  });
263
242
 
264
- export const tsFeatureFolder = defineTemplate({
265
- id: 'typescript.feature',
266
- name: 'TypeScript Feature folder',
267
- description: 'Creates a vertical feature slice (index + service + types).',
268
- tags: ['typescript', 'feature'],
269
- scope: ['typescript'],
270
- appliesWhen: ['generate-feature'],
271
- variables: [
272
- { name: 'name', required: true },
273
- { name: 'pascal', required: true },
274
- ],
275
- files: ({ name, pascal }) => [
276
- {
277
- targetPath: \`src/features/\${name}/index.ts\`,
278
- content: \`export * from './\${name}.service.ts';\nexport * from './\${name}.types.ts';\n\`,
279
- },
280
- {
281
- targetPath: \`src/features/\${name}/\${name}.service.ts\`,
282
- content: \`import type { I\${pascal}Config } from './\${name}.types.ts';\n\nexport class \${pascal}Service {\n constructor(private readonly config: I\${pascal}Config) {}\n}\n\`,
283
- },
284
- {
285
- targetPath: \`src/features/\${name}/\${name}.types.ts\`,
286
- content: \`export interface I\${pascal}Config {\n enabled: boolean;\n}\n\`,
287
- },
288
- ],
289
- postGenerationNotes: ['Add tests under tests/<feature> or co-located *.spec.ts.'],
290
- });
291
-
292
243
  export const tsTest = defineTemplate({
293
244
  id: 'typescript.test',
294
245
  name: 'TypeScript Test File',
@@ -300,11 +251,18 @@ export const tsTest = defineTemplate({
300
251
  { name: 'name', required: true },
301
252
  { name: 'pascal', required: true },
302
253
  ],
303
- targetPath: ({ name }) => \`tests/\${name}.spec.ts\`,
304
- content: ({ pascal }) => \`import { describe, expect, test } from 'bun:test';\n\ndescribe('\${pascal}', () => {\n test('placeholder', () => {\n expect(true).toBe(true);\n });\n});\n\`,
254
+ targetPath: ({ name }: { name: string }) => \`tests/\${name}.spec.ts\`,
255
+ content: ({ pascal }: { pascal: string }) => \`import { describe, expect, test } from 'bun:test';
256
+
257
+ describe('\${pascal}', () => {
258
+ test('placeholder', () => {
259
+ expect(true).toBe(true);
260
+ });
261
+ });
262
+ \`,
305
263
  });
306
264
 
307
- export default [tsService, tsUtility, tsFeatureFolder, tsTest];
265
+ export default [tsService, tsUtility, tsTest];
308
266
  `,
309
267
  },
310
268
  {
@@ -411,3 +369,65 @@ Lower-priority work for SharkCraft-powered knowledge in this repo.
411
369
  `,
412
370
  },
413
371
  ];
372
+ function PATHS_PLACEHOLDER_CONTENT() {
373
+ // The legacy seed ships generic path examples. The modern preset path
374
+ // (`shrk init --preset <id>`) is workspace-aware. To avoid emitting
375
+ // broken defaults like `src/services/` in repos that don't have them,
376
+ // the legacy seed now ships *commented* examples plus an `// TODO:`
377
+ // marker the human is expected to fill in. The runner-instructions in
378
+ // docs/onboarding.md describe how to derive paths from the live repo.
379
+ return `// Local helpers — keep this file self-contained (no @shrkcrft/* imports).
380
+
381
+ const KnowledgePriority = {
382
+ Critical: 'critical',
383
+ High: 'high',
384
+ Medium: 'medium',
385
+ Low: 'low',
386
+ } as const;
387
+
388
+ const KnowledgeType = { Path: 'path' } as const;
389
+
390
+ function definePathConvention<T>(convention: T): T {
391
+ return { ...convention, type: KnowledgeType.Path } as T;
392
+ }
393
+
394
+ // TODO: replace the examples below with real path conventions for this
395
+ // repository. Run \`shrk onboard --dry-run\` to see what the inference
396
+ // engine detects from the workspace.
397
+
398
+ export const appSrc = definePathConvention({
399
+ id: 'app.src',
400
+ title: 'Application source root',
401
+ path: 'src',
402
+ description: 'All application source lives here. Adjust to match this repo.',
403
+ priority: KnowledgePriority.Critical,
404
+ scope: ['typescript'],
405
+ tags: ['source-path', 'root'],
406
+ appliesWhen: ['generate-code'],
407
+ });
408
+
409
+ export const tests = definePathConvention({
410
+ id: 'app.tests',
411
+ title: 'Test files',
412
+ path: 'tests',
413
+ description: 'Test files. Many repos co-locate \`*.spec.ts\` next to the unit under test instead — pick one.',
414
+ priority: KnowledgePriority.Medium,
415
+ scope: ['typescript', 'testing'],
416
+ tags: ['test', 'source-path'],
417
+ appliesWhen: ['generate-test'],
418
+ });
419
+
420
+ export const docs = definePathConvention({
421
+ id: 'app.docs',
422
+ title: 'Documentation',
423
+ path: 'docs',
424
+ description: 'Long-form human-readable docs (optional).',
425
+ priority: KnowledgePriority.Low,
426
+ scope: ['typescript'],
427
+ tags: ['docs'],
428
+ appliesWhen: ['add-docs'],
429
+ });
430
+
431
+ export default [appSrc, tests, docs];
432
+ `;
433
+ }
@@ -0,0 +1,20 @@
1
+ export interface IPathsAdvisory {
2
+ missingPaths: readonly string[];
3
+ existingPaths: readonly string[];
4
+ /** True when an advisory comment was prepended to the file. */
5
+ annotated: boolean;
6
+ pathsFile: string;
7
+ }
8
+ /**
9
+ * Scan the generated `sharkcraft/paths.ts` for `path: '<x>'` references
10
+ * and check each `<x>` against the live workspace. When any path is
11
+ * missing, prepend a clearly-labeled comment block listing the missing
12
+ * paths so the user knows which defaults to adjust.
13
+ *
14
+ * Idempotent — if the file already starts with the advisory marker,
15
+ * it is left untouched. Non-destructive — never edits, comments, or
16
+ * removes the original entries. The user is expected to revise them
17
+ * based on the advisory + `shrk onboard --dry-run` output.
18
+ */
19
+ export declare function annotatePathsAgainstDisk(cwd: string, sharkcraftDir: string): IPathsAdvisory;
20
+ //# sourceMappingURL=paths-advisory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths-advisory.d.ts","sourceRoot":"","sources":["../../src/init/paths-advisory.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,+DAA+D;IAC/D,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,GACpB,cAAc,CAwChB"}
@@ -0,0 +1,88 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import * as nodePath from 'node:path';
3
+ const ADVISORY_MARKER = '// ⚠️ Workspace-shape advisory (added by `shrk init`):';
4
+ /**
5
+ * Scan the generated `sharkcraft/paths.ts` for `path: '<x>'` references
6
+ * and check each `<x>` against the live workspace. When any path is
7
+ * missing, prepend a clearly-labeled comment block listing the missing
8
+ * paths so the user knows which defaults to adjust.
9
+ *
10
+ * Idempotent — if the file already starts with the advisory marker,
11
+ * it is left untouched. Non-destructive — never edits, comments, or
12
+ * removes the original entries. The user is expected to revise them
13
+ * based on the advisory + `shrk onboard --dry-run` output.
14
+ */
15
+ export function annotatePathsAgainstDisk(cwd, sharkcraftDir) {
16
+ const pathsFile = nodePath.join(sharkcraftDir, 'paths.ts');
17
+ if (!existsSync(pathsFile)) {
18
+ return { missingPaths: [], existingPaths: [], annotated: false, pathsFile };
19
+ }
20
+ const original = readFileSync(pathsFile, 'utf8');
21
+ if (original.startsWith(ADVISORY_MARKER)) {
22
+ // Already annotated. Re-derive sets for caller diagnostics.
23
+ return classifyOnly(cwd, pathsFile, original);
24
+ }
25
+ const { existing, missing } = classifyPathReferences(cwd, original);
26
+ if (missing.length === 0) {
27
+ return {
28
+ missingPaths: [],
29
+ existingPaths: existing,
30
+ annotated: false,
31
+ pathsFile,
32
+ };
33
+ }
34
+ const lines = [
35
+ ADVISORY_MARKER,
36
+ '//',
37
+ '// The following paths referenced below do NOT exist in this repository:',
38
+ ...missing.map((p) => `// - ${p}`),
39
+ '//',
40
+ '// They are conservative defaults from the chosen preset. Adjust them to',
41
+ '// match your actual layout. Run `shrk onboard --dry-run` to see what',
42
+ '// the inference engine detects from your workspace.',
43
+ '//',
44
+ '',
45
+ ];
46
+ writeFileSync(pathsFile, lines.join('\n') + original, 'utf8');
47
+ return {
48
+ missingPaths: missing,
49
+ existingPaths: existing,
50
+ annotated: true,
51
+ pathsFile,
52
+ };
53
+ }
54
+ function classifyOnly(cwd, pathsFile, original) {
55
+ const { existing, missing } = classifyPathReferences(cwd, original);
56
+ return {
57
+ missingPaths: missing,
58
+ existingPaths: existing,
59
+ annotated: false,
60
+ pathsFile,
61
+ };
62
+ }
63
+ function classifyPathReferences(cwd, source) {
64
+ // Match `path: '<x>'` / `path: "<x>"`. Ignore obvious code-context
65
+ // references (e.g. inside template literals); we only consume the
66
+ // first plain-string occurrence per entry.
67
+ const re = /\bpath\s*:\s*['"]([^'"\n]+)['"]/g;
68
+ const seen = new Set();
69
+ let m;
70
+ while ((m = re.exec(source)) !== null) {
71
+ if (m[1])
72
+ seen.add(m[1]);
73
+ }
74
+ const existing = [];
75
+ const missing = [];
76
+ for (const p of [...seen].sort()) {
77
+ if (isReachable(cwd, p))
78
+ existing.push(p);
79
+ else
80
+ missing.push(p);
81
+ }
82
+ return { existing, missing };
83
+ }
84
+ function isReachable(cwd, p) {
85
+ // Absolute or rooted-relative — resolve as-is.
86
+ const full = nodePath.isAbsolute(p) ? p : nodePath.resolve(cwd, p);
87
+ return existsSync(full);
88
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,OAAO,EACL,eAAe,EAIhB,MAAM,uBAAuB,CAAC;AAyV/B,wBAAgB,aAAa,IAAI,eAAe,CA2V/C;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BrE;AA6FD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CA4CxE"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAwX/B,wBAAgB,aAAa,IAAI,eAAe,CA4X/C;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BrE;AAsHD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAoDxE"}