@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
@@ -6,6 +6,7 @@ import { listBuiltInSurfaceProfiles, suggestSurfaceProfile } from '@shrkcrft/ins
6
6
  import { INIT_FILES } from "../init/init-templates.js";
7
7
  import { buildDetectedBlock, renderDetectedBlockText } from "../init/detected-block.js";
8
8
  import { ensureSharkcraftGitignore, renderGitignorePatch } from "../init/gitignore.js";
9
+ import { annotatePathsAgainstDisk } from "../init/paths-advisory.js";
9
10
  import { applySurfaceTextEdit } from "../surface/surface-config-writer.js";
10
11
  import { flagBool, flagString, resolveCwd } from "../command-registry.js";
11
12
  import { bullet, header } from "../output/format-output.js";
@@ -133,6 +134,11 @@ async function applyPresetInit(cwd, mode) {
133
134
  source: 'override',
134
135
  });
135
136
  }
137
+ // Workspace-shape advisory: when the preset emits path conventions
138
+ // that don't exist in this repo (common with generic presets in
139
+ // framework-specific repos), annotate paths.ts so the user knows
140
+ // which defaults to fix.
141
+ const pathsAdvisory = annotatePathsAgainstDisk(cwd, plan.sharkcraftDir);
136
142
  process.stdout.write(header('SharkCraft initialized'));
137
143
  process.stdout.write(`Preset: ${preset.id} — ${preset.title}\n`);
138
144
  process.stdout.write(`Folder: ${plan.sharkcraftDir}\n`);
@@ -169,16 +175,29 @@ async function applyPresetInit(cwd, mode) {
169
175
  process.stdout.write('\n' + renderGitignorePatch(patch, false));
170
176
  }
171
177
  }
178
+ if (pathsAdvisory.annotated) {
179
+ renderPathsAdvisory(pathsAdvisory);
180
+ }
172
181
  process.stdout.write('\nNext:\n');
173
- for (const cmd of preset.recommendedNextCommands ?? [
174
- 'shrk doctor',
175
- 'shrk context --task "<task>"',
176
- ]) {
182
+ process.stdout.write(bullet('$ shrk doctor — verify the setup (shape-aware verdict)') + '\n');
183
+ process.stdout.write(bullet('$ shrk brief — single-page brief Claude reads first') + '\n');
184
+ process.stdout.write(bullet('$ shrk export claude-skill --write — inline the rules into Claude\'s prompt via .claude/skills/') + '\n');
185
+ for (const cmd of preset.recommendedNextCommands ?? []) {
177
186
  process.stdout.write(bullet(`$ ${cmd}`) + '\n');
178
187
  }
179
188
  process.stdout.write(bullet('Start the MCP server: `shrk mcp serve` (or run it via Claude Code)') + '\n');
180
189
  return 0;
181
190
  }
191
+ function renderPathsAdvisory(advisory) {
192
+ process.stdout.write('\n');
193
+ process.stdout.write(header('Paths advisory'));
194
+ process.stdout.write('These preset-default paths do not exist in this repo:\n');
195
+ for (const p of advisory.missingPaths) {
196
+ process.stdout.write(bullet(p) + '\n');
197
+ }
198
+ process.stdout.write('\nEdit sharkcraft/paths.ts to match your real layout. ' +
199
+ 'Run `shrk onboard --dry-run` to see what the engine infers.\n');
200
+ }
182
201
  function applyLegacyInit(cwd, force) {
183
202
  const { root } = detectProjectRoot(cwd);
184
203
  const sharkcraftDir = nodePath.join(root, 'sharkcraft');
@@ -212,6 +231,10 @@ function applyLegacyInit(cwd, force) {
212
231
  for (const s of skipped)
213
232
  process.stdout.write(bullet(s) + '\n');
214
233
  }
234
+ const legacyAdvisory = annotatePathsAgainstDisk(cwd, sharkcraftDir);
235
+ if (legacyAdvisory.annotated) {
236
+ renderPathsAdvisory(legacyAdvisory);
237
+ }
215
238
  process.stdout.write('\nNext:\n');
216
239
  process.stdout.write(bullet('Run `shrk inspect` to see your project summary.') + '\n');
217
240
  process.stdout.write(bullet('Run `shrk knowledge list` to see what was seeded.') + '\n');
@@ -220,13 +243,23 @@ function applyLegacyInit(cwd, force) {
220
243
  }
221
244
  export const initCommand = {
222
245
  name: 'init',
223
- description: 'Initialize a sharkcraft/ folder in the current repository. Pass --preset <id> to apply a built-in preset (default: generic). Use --zero-config or --preset auto to detect the workspace and pick a preset automatically. Use --legacy for the full pre-preset seed.',
224
- usage: 'shrk init [--preset <id|auto>] [--zero-config] [--dry-run] [--write] [--legacy] [--force] [--merge] [--suggest-only] [--no-gitignore] [--surface-profile <id>]',
246
+ description: 'Initialize a sharkcraft/ folder in the current repository. Pass --preset <id> to apply a built-in preset (default: generic). Use --zero-config or --preset auto to detect the workspace and pick a preset automatically. Use --legacy for the full pre-preset seed. Pass --infer to scan the repo and populate sharkcraft/* with the real signals it finds (paths from disk, rules from tsconfig/package.json, boundaries from layer structure) — combines with --preset to add inferred entries on top of the preset baseline. Pass --with-claude-skill to also generate .claude/skills/<name>/SKILL.md so Claude Code picks up the rules automatically.',
247
+ usage: 'shrk init [--preset <id|auto>] [--zero-config] [--infer] [--dry-run] [--write] [--with-claude-skill] [--legacy] [--force] [--merge] [--suggest-only] [--no-gitignore] [--surface-profile <id>]',
225
248
  async run(args) {
226
249
  const force = flagBool(args, 'force');
227
250
  const merge = flagBool(args, 'merge');
228
251
  const cwd = resolveCwd(args);
252
+ const wantInfer = flagBool(args, 'infer');
229
253
  const skipGitignore = flagBool(args, 'no-gitignore');
254
+ // `--infer` mode short-circuits the preset path entirely. The
255
+ // inferred output IS the populated sharkcraft/*, no preset
256
+ // baseline to merge against. This is the cleaner contract: the
257
+ // user opted into "scan my repo and tell me what's there", and
258
+ // adding a preset's static defaults on top would muddy the
259
+ // confidence reporting in .inferred-report.md.
260
+ if (wantInfer) {
261
+ return runInferInit(cwd, args, force);
262
+ }
230
263
  if (flagBool(args, 'legacy')) {
231
264
  const code = applyLegacyInit(cwd, force);
232
265
  if (code === 0 && !skipGitignore) {
@@ -287,7 +320,7 @@ export const initCommand = {
287
320
  if (dryRun) {
288
321
  process.stdout.write(`Surface profile: ${surfaceDecision.profile} (${surfaceDecision.source}) — ${surfaceDecision.reason}\n`);
289
322
  }
290
- return applyPresetInit(cwd, {
323
+ const presetCode = await applyPresetInit(cwd, {
291
324
  presetId,
292
325
  dryRun,
293
326
  force,
@@ -297,5 +330,139 @@ export const initCommand = {
297
330
  surfaceProfile: surfaceDecision.profile,
298
331
  surfaceProfileReason: surfaceDecision.reason,
299
332
  });
333
+ // `--with-claude-skill` chains the claude-skill export onto the init
334
+ // so a fresh user goes from `npx shrk init --with-claude-skill --write`
335
+ // to a working .claude/skills/<name>/SKILL.md in one step. Skipped in
336
+ // dry-run + when init itself didn't succeed.
337
+ if (presetCode === 0 &&
338
+ !dryRun &&
339
+ (flagBool(args, 'with-claude-skill') || flagBool(args, 'with-skill'))) {
340
+ const skillCode = await runClaudeSkillExportAfterInit(cwd, force);
341
+ // Init success is what we report; skill failure is logged but
342
+ // doesn't fail the init exit code (otherwise users would see a
343
+ // half-applied repo with a non-zero exit and panic).
344
+ if (skillCode !== 0) {
345
+ process.stderr.write('\n(claude-skill export failed — re-run `shrk export claude-skill --write` to retry.)\n');
346
+ }
347
+ }
348
+ return presetCode;
300
349
  },
301
350
  };
351
+ /**
352
+ * Chain the claude-skill export onto a successful init. Loads the
353
+ * exporter lazily (it depends on inspectSharkcraft which has its own
354
+ * caching) and writes the skill file using the same `--force` semantics
355
+ * as init itself.
356
+ */
357
+ /**
358
+ * `shrk init --infer` — scan the repo and populate `sharkcraft/*`
359
+ * with the real signals it finds, instead of writing preset defaults.
360
+ *
361
+ * Pipeline:
362
+ * 1. `inspectSharkcraft({ cwd })` builds the full inspection.
363
+ * 2. `buildOnboardingPlan(inspection)` extracts inferred paths,
364
+ * rules, boundaries, pipelines, verification commands.
365
+ * 3. `synthesizeFromOnboarding(plan)` triages each entry by
366
+ * confidence and emits populated `sharkcraft/*.ts` files plus
367
+ * a companion `.inferred-report.md` + `.inferred-report.json`.
368
+ * 4. Writer respects `--dry-run` / `--write` / `--force` /
369
+ * `--with-claude-skill` semantics consistently with the
370
+ * preset-init path.
371
+ *
372
+ * Honest-by-default: every adopted entry is tagged with its source
373
+ * signal; medium-confidence rows get a `// TODO: review` marker; low-
374
+ * confidence rows are dropped from the populated files and listed in
375
+ * the report so the user knows exactly what was inferred vs needs
376
+ * authoring.
377
+ */
378
+ async function runInferInit(cwd, args, force) {
379
+ const { inspectSharkcraft, buildOnboardingPlan, synthesizeFromOnboarding } = await import('@shrkcrft/inspector');
380
+ const dryRun = !flagBool(args, 'write');
381
+ const sharkcraftDir = nodePath.join(cwd, 'sharkcraft');
382
+ process.stdout.write(header('SharkCraft init — infer'));
383
+ process.stdout.write(`Folder: ${sharkcraftDir}\n`);
384
+ const inspection = await inspectSharkcraft({ cwd });
385
+ const plan = buildOnboardingPlan(inspection);
386
+ const result = synthesizeFromOnboarding(plan);
387
+ // Summary block — print BEFORE writing so the user can ctrl-C if the
388
+ // confidence triage doesn't look right.
389
+ process.stdout.write(`\nDetected profiles: ${plan.projectSummary.profiles.join(', ') || '(none)'}\n`);
390
+ process.stdout.write(`Inference triage: ${result.report.adoptedHigh.length} adopted directly · ` +
391
+ `${result.report.adoptedMedium.length} marked for review · ` +
392
+ `${result.report.dropped.length} dropped (in report).\n\n`);
393
+ const written = [];
394
+ const skipped = [];
395
+ const wouldWrite = [];
396
+ for (const file of result.files) {
397
+ const fullPath = nodePath.join(sharkcraftDir, file.path);
398
+ if (dryRun) {
399
+ wouldWrite.push(file.path);
400
+ continue;
401
+ }
402
+ mkdirSync(nodePath.dirname(fullPath), { recursive: true });
403
+ if (existsSync(fullPath) && !force) {
404
+ skipped.push(file.path);
405
+ continue;
406
+ }
407
+ writeFileSync(fullPath, file.content, 'utf8');
408
+ written.push(file.path);
409
+ }
410
+ if (dryRun) {
411
+ process.stdout.write('Would write:\n');
412
+ for (const p of wouldWrite)
413
+ process.stdout.write(bullet(p) + '\n');
414
+ process.stdout.write('\nRe-run with --write to persist.\n');
415
+ return 0;
416
+ }
417
+ if (written.length) {
418
+ process.stdout.write('Wrote:\n');
419
+ for (const p of written)
420
+ process.stdout.write(bullet(p) + '\n');
421
+ }
422
+ if (skipped.length) {
423
+ process.stdout.write('\nSkipped (already exist; use --force to overwrite):\n');
424
+ for (const p of skipped)
425
+ process.stdout.write(bullet(p) + '\n');
426
+ }
427
+ process.stdout.write(`\nRead the confidence report: \`${nodePath.join('sharkcraft', '.inferred-report.md')}\`\n` +
428
+ `It lists what was adopted high-confidence, what's marked for your review, ` +
429
+ `and what shrk can't infer (project-specific decisions you should author by hand).\n`);
430
+ process.stdout.write('\nNext:\n');
431
+ process.stdout.write(bullet('$ shrk doctor — verify the setup (shape-aware verdict)') + '\n');
432
+ process.stdout.write(bullet('$ shrk brief — single-page brief Claude reads first') + '\n');
433
+ process.stdout.write(bullet('$ shrk export claude-skill --write — inline the rules into Claude\'s prompt') + '\n');
434
+ // Chain claude-skill if requested.
435
+ if (flagBool(args, 'with-claude-skill') || flagBool(args, 'with-skill')) {
436
+ const skillCode = await runClaudeSkillExportAfterInit(cwd, force);
437
+ if (skillCode !== 0) {
438
+ process.stderr.write('\n(claude-skill export failed — re-run `shrk export claude-skill --write` to retry.)\n');
439
+ }
440
+ }
441
+ // Gitignore + paths advisory same as preset path.
442
+ const skipGitignore = flagBool(args, 'no-gitignore');
443
+ if (!skipGitignore) {
444
+ const patch = ensureSharkcraftGitignore({ cwd, dryRun: false });
445
+ if (patch.added.length > 0) {
446
+ process.stdout.write('\n' + renderGitignorePatch(patch, false));
447
+ }
448
+ }
449
+ return 0;
450
+ }
451
+ async function runClaudeSkillExportAfterInit(cwd, force) {
452
+ const { inspectSharkcraft } = await import('@shrkcrft/inspector');
453
+ const { renderExport } = await import("../export/export-formats.js");
454
+ const inspection = await inspectSharkcraft({ cwd });
455
+ const result = renderExport(inspection, { format: 'claude-skill' });
456
+ const outputPath = nodePath.join(cwd, result.suggestedPath);
457
+ mkdirSync(nodePath.dirname(outputPath), { recursive: true });
458
+ if (existsSync(outputPath) && !force) {
459
+ process.stdout.write(`\nSkipped claude-skill export — ${result.suggestedPath} already exists. Pass --force to overwrite, or run \`shrk export claude-skill --write --force\`.\n`);
460
+ return 0;
461
+ }
462
+ writeFileSync(outputPath, result.content, 'utf8');
463
+ process.stdout.write('\n');
464
+ process.stdout.write(header('Claude-skill exported'));
465
+ process.stdout.write(`Wrote ${result.suggestedPath}\n` +
466
+ ` → Claude Code will auto-load this skill in any session opened against this repo.\n`);
467
+ return 0;
468
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-author.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge-author.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAoBH,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAwChC,eAAO,MAAM,mBAAmB,EAAE,eAgEjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eA0GpC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAoEpC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eA2DlC,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,eAmB3C,CAAC"}
1
+ {"version":3,"file":"knowledge-author.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge-author.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAoBH,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAwChC,eAAO,MAAM,mBAAmB,EAAE,eAgEjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eA0GpC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAoEpC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAsElC,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,eAmB3C,CAAC"}
@@ -300,6 +300,15 @@ export const knowledgeLintCommand = {
300
300
  async run(args) {
301
301
  const cwd = resolveCwd(args);
302
302
  const inspection = await inspectSharkcraft({ cwd });
303
+ // Loud guard: a 0-entry scan is NOT a clean pass — it almost always means
304
+ // the loader found nothing (wrong cwd / no `sharkcraft/` folder / no
305
+ // entries), which otherwise reads as "lint passed". Surface it on stderr so
306
+ // it can't be mistaken for success, while keeping stdout/JSON clean.
307
+ if (inspection.knowledgeEntries.length === 0) {
308
+ process.stderr.write('WARN knowledge lint scanned 0 entries — there is nothing to lint (this is NOT a clean pass).\n' +
309
+ ' Likely causes: no `sharkcraft/` folder here, not at the workspace root, or no\n' +
310
+ ' knowledge entries are defined. Run `shrk doctor` to confirm how many entries load.\n');
311
+ }
303
312
  const entryIds = flagList(args, 'id');
304
313
  const includeAdvisory = !flagBool(args, 'no-advisory');
305
314
  const stale = buildKnowledgeStaleReport(inspection);
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-propose.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge-propose.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAkDhC,eAAO,MAAM,uBAAuB,EAAE,eA0ErC,CAAC"}
1
+ {"version":3,"file":"knowledge-propose.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge-propose.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAkDhC,eAAO,MAAM,uBAAuB,EAAE,eA4ErC,CAAC"}
@@ -10,7 +10,7 @@
10
10
  import { mkdirSync, writeFileSync } from 'node:fs';
11
11
  import * as nodePath from 'node:path';
12
12
  import { AssetKind, AssetProvenanceOperation, KNOWLEDGE_PROPOSE_SCHEMA, proposeKnowledge, recordProvenance, renderKnowledgeProposeMarkdown, } from '@shrkcrft/inspector';
13
- import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
13
+ import { flagBool, flagNumber, flagString, resolveCwd, } from "../command-registry.js";
14
14
  import { asJson } from "../output/format-output.js";
15
15
  import { detectAuthoringSource } from "../authoring/authoring-kit.js";
16
16
  function renderProposalAsTs(p) {
@@ -54,13 +54,14 @@ function writeDraftFiles(cwd, report) {
54
54
  export const knowledgeProposeCommand = {
55
55
  name: 'propose',
56
56
  description: 'Propose stub knowledge entries for exported top-level constructs that lack coverage. Preview-first; --write materialises drafts under .sharkcraft/authoring/proposed/.',
57
- usage: 'shrk knowledge propose [--path <file>] [--symbol <name>] [--since <ref>|--all] [--json] [--write]',
57
+ usage: 'shrk knowledge propose [--path <file>] [--symbol <name>] [--since <ref>|--all] [--max <n>] [--json] [--write]',
58
58
  async run(args) {
59
59
  const cwd = resolveCwd(args);
60
60
  const path = flagString(args, 'path');
61
61
  const symbol = flagString(args, 'symbol');
62
62
  const sinceFlag = flagString(args, 'since');
63
63
  const all = flagBool(args, 'all');
64
+ const max = flagNumber(args, 'max');
64
65
  const since = path
65
66
  ? undefined
66
67
  : symbol
@@ -73,6 +74,7 @@ export const knowledgeProposeCommand = {
73
74
  ...(path ? { path } : {}),
74
75
  ...(symbol ? { symbol } : {}),
75
76
  ...(since !== undefined ? { since } : {}),
77
+ ...(max !== undefined && max >= 0 ? { max } : {}),
76
78
  });
77
79
  if (flagBool(args, 'json')) {
78
80
  const payload = flagBool(args, 'write')
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge.command.ts"],"names":[],"mappings":"AAaA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAoFhC,eAAO,MAAM,oBAAoB,EAAE,eAsBlC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAuBjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAqCpC,CAAC;AAoBF,eAAO,MAAM,0BAA0B,EAAE,eAWxC,CAAC;AA8NF,eAAO,MAAM,sBAAsB,EAAE,eAQpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8CxC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAuBrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,eA8B1C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8BxC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,eAkC1C,CAAC"}
1
+ {"version":3,"file":"knowledge.command.d.ts","sourceRoot":"","sources":["../../src/commands/knowledge.command.ts"],"names":[],"mappings":"AAkBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAoFhC,eAAO,MAAM,oBAAoB,EAAE,eA8ClC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAuBjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAqCpC,CAAC;AAoBF,eAAO,MAAM,0BAA0B,EAAE,eAWxC,CAAC;AA8NF,eAAO,MAAM,sBAAsB,EAAE,eAQpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8CxC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,eAuBrC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,EAAE,eA8B1C,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,eA8BxC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,eAkC1C,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { join as nodePathJoin, resolve as nodePathResolve } from 'node:path';
3
3
  import { buildAnchorUpdatePlan, buildKnowledgeStaleReport, buildRenameFilePlan, buildRenameSymbolPlan, inspectSharkcraft, ReferenceCheckOutcome, resolveChangedFiles, } from '@shrkcrft/inspector';
4
- import { formatEntryCompact, formatEntryFull, searchKnowledge } from '@shrkcrft/knowledge';
4
+ import { formatEntryCompact, formatEntryFull, projectKnowledgeEntryForJson, searchKnowledge, } from '@shrkcrft/knowledge';
5
5
  import { flagBool, flagNumber, flagString, flagList, resolveCwd, } from "../command-registry.js";
6
6
  import { asJson, header } from "../output/format-output.js";
7
7
  import { maybeRunInWatchMode } from "../output/watch-loop.js";
@@ -54,7 +54,7 @@ ${p.ci.exitNonZero ? `<p style="color:#a40000;font-weight:bold">FAIL: ${esc(p.ci
54
54
  export const knowledgeListCommand = {
55
55
  name: 'list',
56
56
  description: 'List knowledge entries.',
57
- usage: 'shrk knowledge list [--type rule] [--scope x,y] [--json]',
57
+ usage: 'shrk knowledge list [--type rule] [--scope x,y] [--top N] [--brief] [--json]',
58
58
  async run(args) {
59
59
  const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
60
60
  const types = flagList(args, 'type');
@@ -64,8 +64,31 @@ export const knowledgeListCommand = {
64
64
  entries = entries.filter((e) => types.includes(String(e.type)));
65
65
  if (scope.length)
66
66
  entries = entries.filter((e) => scope.some((s) => e.scope.includes(s)));
67
+ // --top N: a deterministic, token-bounded slice. Sort by id first so the
68
+ // "top N" is stable across machines (entries otherwise load in fs-scan
69
+ // order). Reduce at the source instead of piping through `shrk compress`.
70
+ const top = flagNumber(args, 'top');
71
+ if (top !== undefined && top > 0) {
72
+ entries = [...entries].sort((a, b) => a.id.localeCompare(b.id)).slice(0, top);
73
+ }
67
74
  if (flagBool(args, 'json')) {
68
- process.stdout.write(asJson(entries.map((e) => ({ ...e }))) + '\n');
75
+ // --brief: project to the high-signal fields, dropping content / examples
76
+ // / metadata (the bulk of the payload) so an agent pays far fewer tokens.
77
+ const payload = flagBool(args, 'brief')
78
+ ? entries.map((e) => ({
79
+ id: e.id,
80
+ type: e.type,
81
+ priority: e.priority,
82
+ title: e.title,
83
+ scope: e.scope,
84
+ tags: e.tags,
85
+ appliesWhen: e.appliesWhen,
86
+ }))
87
+ : // Project the declared IKnowledgeEntry fields by direct access rather
88
+ // than spreading (`{ ...e }`), which copies only own-enumerable props
89
+ // and would strip pack entries whose fields are getters/non-enumerable.
90
+ entries.map(projectKnowledgeEntryForJson);
91
+ process.stdout.write(asJson(payload) + '\n');
69
92
  return 0;
70
93
  }
71
94
  process.stdout.write(header(`Knowledge (${entries.length})`));
@@ -0,0 +1,13 @@
1
+ import { type ICommandHandler } from '../command-registry.js';
2
+ /**
3
+ * `shrk migrate` — run a multi-step migration definition.
4
+ *
5
+ * - shrk migrate plan <id> preview what each step would do
6
+ * - shrk migrate apply <id> execute the migration (writes!)
7
+ *
8
+ * Migrations live in `sharkcraft/migrations/<id>.ts` by default; pass
9
+ * `--from <path>` to point at a specific file. Each migration file
10
+ * default-exports an `IMigration` (use `defineMigration({ ... })`).
11
+ */
12
+ export declare const migrateCommand: ICommandHandler;
13
+ //# sourceMappingURL=migrate.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.command.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.command.ts"],"names":[],"mappings":"AAUA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,EAAE,eAsI5B,CAAC"}
@@ -0,0 +1,152 @@
1
+ import { existsSync } from 'node:fs';
2
+ import * as nodePath from 'node:path';
3
+ import { safeImport } from '@shrkcrft/core';
4
+ import { applyMigration, planMigration, pruneMigrations, resumeMigration, } from '@shrkcrft/migrate';
5
+ import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
6
+ import { asJson, header, kv } from "../output/format-output.js";
7
+ /**
8
+ * `shrk migrate` — run a multi-step migration definition.
9
+ *
10
+ * - shrk migrate plan <id> preview what each step would do
11
+ * - shrk migrate apply <id> execute the migration (writes!)
12
+ *
13
+ * Migrations live in `sharkcraft/migrations/<id>.ts` by default; pass
14
+ * `--from <path>` to point at a specific file. Each migration file
15
+ * default-exports an `IMigration` (use `defineMigration({ ... })`).
16
+ */
17
+ export const migrateCommand = {
18
+ name: 'migrate',
19
+ description: 'Orchestrate multi-step refactors: structural rewrites + shell + checks in one named, replayable migration.',
20
+ usage: 'shrk migrate plan <id> [--from <path>] [--json] | shrk migrate apply <id> [--from <path>] [--dry-run] [--no-stop-on-failure] [--json] | shrk migrate resume <id> [--from <path>] [--json] | shrk migrate prune [--older-than <days>] [--include-failed] [--dry-run] [--json]',
21
+ async run(args) {
22
+ const sub = args.positional[0];
23
+ if (sub !== 'plan' && sub !== 'apply' && sub !== 'resume' && sub !== 'prune') {
24
+ process.stderr.write(this.usage + '\n');
25
+ return 2;
26
+ }
27
+ const cwd = resolveCwd(args);
28
+ const wantJson = flagBool(args, 'json');
29
+ if (sub === 'prune') {
30
+ const olderThanRaw = flagString(args, 'older-than');
31
+ const olderThanDays = olderThanRaw !== undefined ? Number(olderThanRaw) : undefined;
32
+ if (olderThanDays !== undefined && (!Number.isFinite(olderThanDays) || olderThanDays < 0)) {
33
+ process.stderr.write(`Invalid --older-than: ${olderThanRaw}\n`);
34
+ return 2;
35
+ }
36
+ const result = pruneMigrations({
37
+ projectRoot: cwd,
38
+ ...(olderThanDays !== undefined ? { olderThanDays } : {}),
39
+ includeFailed: flagBool(args, 'include-failed'),
40
+ dryRun: flagBool(args, 'dry-run'),
41
+ });
42
+ if (wantJson) {
43
+ process.stdout.write(asJson(result) + '\n');
44
+ return 0;
45
+ }
46
+ process.stdout.write(header(`Migrate prune (${result.dryRun ? 'dry-run' : 'applied'})`));
47
+ process.stdout.write(kv('scanned', String(result.scanned)) + '\n');
48
+ process.stdout.write(kv('eligible', String(result.eligible)) + '\n');
49
+ process.stdout.write(kv('removed', String(result.removed)) + '\n');
50
+ for (const e of result.entries.slice(0, 50)) {
51
+ process.stdout.write(` ${e.id} (${e.overall}, ${e.ageDays}d, reason=${e.reason})\n`);
52
+ }
53
+ return 0;
54
+ }
55
+ const id = args.positional[1];
56
+ if (!id) {
57
+ process.stderr.write('Usage: shrk migrate ' + sub + ' <id>\n');
58
+ return 2;
59
+ }
60
+ const fromFlag = flagString(args, 'from');
61
+ const candidate = fromFlag
62
+ ? (nodePath.isAbsolute(fromFlag) ? fromFlag : nodePath.resolve(cwd, fromFlag))
63
+ : nodePath.resolve(cwd, 'sharkcraft', 'migrations', `${id}.ts`);
64
+ if (!existsSync(candidate)) {
65
+ process.stderr.write(`Migration file not found: ${candidate}\n`);
66
+ return 1;
67
+ }
68
+ const result = await safeImport(candidate);
69
+ if (!result.ok) {
70
+ process.stderr.write(`Migration load failed: ${result.error.message}\n`);
71
+ return 1;
72
+ }
73
+ const migration = result.module.default ?? result.module.migration;
74
+ if (!migration) {
75
+ process.stderr.write(`Migration module ${candidate} does not export a default migration.\n`);
76
+ return 1;
77
+ }
78
+ if (migration.id !== id) {
79
+ process.stderr.write(`Migration id mismatch: requested "${id}", file contains "${migration.id}".\n`);
80
+ return 1;
81
+ }
82
+ if (sub === 'plan') {
83
+ const plan = planMigration(migration, cwd);
84
+ if (wantJson) {
85
+ process.stdout.write(asJson(plan) + '\n');
86
+ return 0;
87
+ }
88
+ process.stdout.write(header(`Migration plan: ${plan.migration.title}`));
89
+ process.stdout.write(kv('id', plan.migration.id) + '\n');
90
+ process.stdout.write(kv('total steps', String(plan.plannedSteps.length)) + '\n');
91
+ process.stdout.write(kv('total edits', String(plan.totalEdits)) + '\n');
92
+ process.stdout.write(kv('files affected', String(plan.totalFiles)) + '\n');
93
+ for (const step of plan.plannedSteps) {
94
+ process.stdout.write(`\n [${step.index + 1}/${plan.plannedSteps.length}] ${step.id} (${step.step.kind})\n`);
95
+ if (step.description)
96
+ process.stdout.write(` ${step.description}\n`);
97
+ if (step.rewritePlan) {
98
+ process.stdout.write(` files=${step.rewritePlan.files.length} edits=${step.rewritePlan.totalEdits}\n`);
99
+ }
100
+ else if (step.step.kind === 'shell' || step.step.kind === 'check') {
101
+ process.stdout.write(` $ ${step.step.command}\n`);
102
+ }
103
+ }
104
+ return 0;
105
+ }
106
+ // apply / resume
107
+ const dryRun = flagBool(args, 'dry-run');
108
+ const noStop = flagBool(args, 'no-stop-on-failure');
109
+ let report;
110
+ let resumedFromIndex = 0;
111
+ const resumeDiagnostics = [];
112
+ if (sub === 'resume') {
113
+ const result = resumeMigration(migration, {
114
+ projectRoot: cwd,
115
+ dryRun,
116
+ stopOnFailure: !noStop,
117
+ });
118
+ report = result.report;
119
+ resumedFromIndex = result.resumedFromIndex;
120
+ for (const d of result.diagnostics)
121
+ resumeDiagnostics.push(d);
122
+ }
123
+ else {
124
+ report = applyMigration(migration, {
125
+ projectRoot: cwd,
126
+ dryRun,
127
+ stopOnFailure: !noStop,
128
+ });
129
+ }
130
+ if (wantJson) {
131
+ process.stdout.write(asJson({ ...report, resumedFromIndex, resumeDiagnostics }) + '\n');
132
+ return report.overall === 'fail' ? 1 : 0;
133
+ }
134
+ if (sub === 'resume') {
135
+ for (const d of resumeDiagnostics)
136
+ process.stdout.write(`! ${d}\n`);
137
+ }
138
+ process.stdout.write(header(`Migration ${dryRun ? '(dry-run)' : '(applied)'}: ${report.overall.toUpperCase()}`));
139
+ process.stdout.write(kv('id', report.migration.id) + '\n');
140
+ process.stdout.write(kv('total duration', `${report.totalDurationMs}ms`) + '\n');
141
+ for (const s of report.steps) {
142
+ process.stdout.write(` [${s.status.padEnd(8)}] ${s.id} (${s.kind}) (${s.durationMs}ms)\n`);
143
+ process.stdout.write(` ${s.message}\n`);
144
+ if (s.rewriteStats && s.rewriteStats.conflicts.length > 0) {
145
+ for (const c of s.rewriteStats.conflicts.slice(0, 5)) {
146
+ process.stdout.write(` conflict: ${c}\n`);
147
+ }
148
+ }
149
+ }
150
+ return report.overall === 'fail' ? 1 : 0;
151
+ },
152
+ };
@@ -0,0 +1,23 @@
1
+ import { type ICommandHandler } from '../command-registry.js';
2
+ /**
3
+ * `shrk move-plan <source> <target>` — emit a structured plan for
4
+ * moving a source file to a new location. Read-only: NEVER moves
5
+ * anything itself, never rewrites imports. The agent (or a human)
6
+ * uses the plan to do the actual work.
7
+ *
8
+ * Covers:
9
+ * - graph-traced importer rewrites (relative + package-name imports)
10
+ * - exports to revisit if the source was re-exported from an index
11
+ * - cross-package warnings (layer-order risks)
12
+ * - a rollback plan that's the literal reverse of the move
13
+ * - validation commands to run after applying
14
+ *
15
+ * Limitations:
16
+ * - single-file only. Directory moves can be approximated by
17
+ * listing the directory and running this command per file, or
18
+ * wait for a `--folder` follow-up.
19
+ * - `from '@shrkcrft/pkg/sub'` deep-import rewrites are best-effort;
20
+ * ambiguous cases get reported as `review-manually`.
21
+ */
22
+ export declare const movePlanCommand: ICommandHandler;
23
+ //# sourceMappingURL=move-plan.command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"move-plan.command.d.ts","sourceRoot":"","sources":["../../src/commands/move-plan.command.ts"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,eAAe,EAA+B,MAAM,wBAAwB,CAAC;AAqCrG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,eAAe,EAAE,eA4M7B,CAAC"}