@shrkcrft/cli 0.1.0-alpha.7 → 0.1.0-alpha.9

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 (46) hide show
  1. package/README.md +1 -1
  2. package/dist/commands/boundaries.command.d.ts.map +1 -1
  3. package/dist/commands/boundaries.command.js +12 -0
  4. package/dist/commands/check.command.d.ts.map +1 -1
  5. package/dist/commands/check.command.js +30 -20
  6. package/dist/commands/command-catalog.d.ts.map +1 -1
  7. package/dist/commands/command-catalog.js +14 -1
  8. package/dist/commands/doctor.command.d.ts.map +1 -1
  9. package/dist/commands/doctor.command.js +7 -8
  10. package/dist/commands/help.command.d.ts.map +1 -1
  11. package/dist/commands/help.command.js +8 -6
  12. package/dist/commands/init.command.d.ts.map +1 -1
  13. package/dist/commands/init.command.js +13 -37
  14. package/dist/commands/mcp.command.d.ts.map +1 -1
  15. package/dist/commands/mcp.command.js +131 -2
  16. package/dist/commands/onboard.command.d.ts.map +1 -1
  17. package/dist/commands/onboard.command.js +15 -3
  18. package/dist/commands/packs-new.d.ts.map +1 -1
  19. package/dist/commands/packs-new.js +10 -3
  20. package/dist/commands/packs.command.d.ts.map +1 -1
  21. package/dist/commands/packs.command.js +17 -3
  22. package/dist/commands/review.command.d.ts.map +1 -1
  23. package/dist/commands/review.command.js +28 -2
  24. package/dist/init/init-templates.d.ts.map +1 -1
  25. package/dist/init/init-templates.js +113 -133
  26. package/dist/main.d.ts +1 -1
  27. package/dist/main.d.ts.map +1 -1
  28. package/dist/main.js +35 -13
  29. package/dist/output/failure-hints.d.ts +9 -1
  30. package/dist/output/failure-hints.d.ts.map +1 -1
  31. package/dist/output/failure-hints.js +8 -2
  32. package/dist/output/watch-loop.d.ts +1 -9
  33. package/dist/output/watch-loop.d.ts.map +1 -1
  34. package/dist/output/watch-loop.js +3 -13
  35. package/dist/schemas/json-schemas.d.ts +36 -36
  36. package/dist/schemas/json-schemas.js +36 -36
  37. package/dist/surface/about.d.ts.map +1 -1
  38. package/dist/surface/about.js +15 -37
  39. package/dist/surface/no-args-landing.d.ts.map +1 -1
  40. package/dist/surface/no-args-landing.js +13 -9
  41. package/dist/surface/surface-config-writer.d.ts.map +1 -1
  42. package/dist/surface/surface-config-writer.js +11 -23
  43. package/package.json +25 -26
  44. package/dist/init/paths-advisory.d.ts +0 -20
  45. package/dist/init/paths-advisory.d.ts.map +0 -1
  46. package/dist/init/paths-advisory.js +0 -88
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  SharkCraft CLI (`shrk`): structured project intelligence for AI coding agents.
4
4
 
5
- Part of [SharkCraft](https://github.com/shrkcrft/sharkcraft) — a deterministic, local-first toolkit that gives AI coding agents durable project context. See the main repo for documentation, examples, and the `shrk` CLI.
5
+ Part of [SharkCraft](https://github.com/sharkcraft/sharkcraft) — a deterministic, local-first toolkit that gives AI coding agents durable project context. See the main repo for documentation, examples, and the `shrk` CLI.
6
6
 
7
7
  ## Install
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"boundaries.command.d.ts","sourceRoot":"","sources":["../../src/commands/boundaries.command.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAwB,KAAK,eAAe,EAA+B,MAAM,wBAAwB,CAAC;AAGjH,eAAO,MAAM,qBAAqB,EAAE,eAuBnC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAqClC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eAmDtC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAyEpC,CAAC;AAsCF,uCAAuC;AACvC,eAAO,MAAM,wBAAwB,EAAE,eAqEtC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eA0CtC,CAAC"}
1
+ {"version":3,"file":"boundaries.command.d.ts","sourceRoot":"","sources":["../../src/commands/boundaries.command.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAwB,KAAK,eAAe,EAA+B,MAAM,wBAAwB,CAAC;AAGjH,eAAO,MAAM,qBAAqB,EAAE,eAuBnC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,eAqClC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eAmDtC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,eAyEpC,CAAC;AAsCF,uCAAuC;AACvC,eAAO,MAAM,wBAAwB,EAAE,eAmFtC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eA0CtC,CAAC"}
@@ -218,6 +218,18 @@ export const boundariesEnforceCommand = {
218
218
  const fileList = filesRaw
219
219
  ? filesRaw.split(',').map((s) => s.trim()).filter(Boolean)
220
220
  : [];
221
+ if (since) {
222
+ const { verifyGitRef } = await import('@shrkcrft/inspector');
223
+ const verify = verifyGitRef(cwd, since);
224
+ if (!verify.valid) {
225
+ process.stderr.write(`error: --since ref "${since}" does not resolve to a commit in this repository.\n` +
226
+ (verify.suggestions && verify.suggestions.length > 0
227
+ ? `\nDid you mean:\n${verify.suggestions.map((s) => ` --since ${s}`).join('\n')}\n`
228
+ : '') +
229
+ '\nUse `git branch -a` to list available refs.\n');
230
+ return 2;
231
+ }
232
+ }
221
233
  const wantChangedScope = changedOnly || staged || Boolean(since) || fileList.length > 0;
222
234
  const { filterViolationsToChangedScope } = await import('@shrkcrft/inspector');
223
235
  const filtered = wantChangedScope
@@ -1 +1 @@
1
- {"version":3,"file":"check.command.d.ts","sourceRoot":"","sources":["../../src/commands/check.command.ts"],"names":[],"mappings":"AAmBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAikBhC,eAAO,MAAM,YAAY,EAAE,eAmD1B,CAAC"}
1
+ {"version":3,"file":"check.command.d.ts","sourceRoot":"","sources":["../../src/commands/check.command.ts"],"names":[],"mappings":"AAoBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA0kBhC,eAAO,MAAM,YAAY,EAAE,eAmD1B,CAAC"}
@@ -1,9 +1,8 @@
1
- import { buildAiReadinessReport, buildImportHygieneReport, buildPackDoctorReport, ChangedScopeMode, diagnoseActionHints, emitImportHygieneAllowlistDraft, filterViolationsToChangedScope, ImportHygieneFindingKind, inspectSharkcraft, isTodoReason, renderImportHygieneText, resolveChangedFiles, runDoctor, suggestBoundaryFixes, } from '@shrkcrft/inspector';
1
+ import { buildAiReadinessReport, buildImportHygieneReport, buildPackDoctorReport, ChangedScopeMode, diagnoseActionHints, emitImportHygieneAllowlistDraft, filterViolationsToChangedScope, ImportHygieneFindingKind, inspectSharkcraft, isTodoReason, renderImportHygieneText, resolveChangedFiles, runDoctor, suggestBoundaryFixes, verifyGitRef, } from '@shrkcrft/inspector';
2
2
  import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'node:fs';
3
3
  import * as nodePath from 'node:path';
4
4
  import { flagBool, flagNumber, flagString, flagVars, resolveCwd, } from "../command-registry.js";
5
5
  import { asJson, header, kv } from "../output/format-output.js";
6
- import { maybeRunInWatchMode } from "../output/watch-loop.js";
7
6
  import { validateTemplateVariables } from '@shrkcrft/templates';
8
7
  import { FileChangeType, planGeneration } from '@shrkcrft/generator';
9
8
  import { evaluateBoundaries, loadTsconfigPaths, scanImports, summarizeImports, } from '@shrkcrft/boundaries';
@@ -153,6 +152,13 @@ async function checkImports(args) {
153
152
  const cwd = resolveCwd(args);
154
153
  const changedOnly = flagBool(args, 'changed-only');
155
154
  const since = flagString(args, 'since');
155
+ if (since) {
156
+ const verify = verifyGitRef(cwd, since);
157
+ if (!verify.valid) {
158
+ process.stderr.write(renderSinceRefError(since, verify.suggestions ?? []));
159
+ return 2;
160
+ }
161
+ }
156
162
  let files;
157
163
  if (changedOnly || since) {
158
164
  const changed = resolveChangedFiles({
@@ -294,6 +300,13 @@ function readChangedScopeOptions(args, cwd) {
294
300
  : [];
295
301
  if (!changedOnly && !staged && !since && files.length === 0)
296
302
  return null;
303
+ if (since) {
304
+ const verify = verifyGitRef(cwd, since);
305
+ if (!verify.valid) {
306
+ process.stderr.write(renderSinceRefError(since, verify.suggestions ?? []));
307
+ process.exit(2);
308
+ }
309
+ }
297
310
  const out = { projectRoot: cwd };
298
311
  if (files.length > 0)
299
312
  out.files = files;
@@ -305,23 +318,20 @@ function readChangedScopeOptions(args, cwd) {
305
318
  out.includeWorktree = true;
306
319
  return out;
307
320
  }
308
- async function checkBoundaries(args) {
309
- const watchExit = await maybeRunInWatchMode(args, checkBoundariesOnce, {
310
- defaultPaths: BOUNDARIES_DEFAULT_WATCH_PATHS,
311
- });
312
- if (watchExit !== null)
313
- return watchExit;
314
- return checkBoundariesOnce(args);
321
+ function renderSinceRefError(ref, suggestions) {
322
+ const lines = [];
323
+ lines.push(`error: --since ref "${ref}" does not resolve to a commit in this repository.`);
324
+ if (suggestions.length > 0) {
325
+ lines.push('');
326
+ lines.push('Did you mean:');
327
+ for (const s of suggestions)
328
+ lines.push(` --since ${s}`);
329
+ }
330
+ lines.push('');
331
+ lines.push('Use `git branch -a` to list available refs, or skip --since to use the working tree.');
332
+ return lines.join('\n') + '\n';
315
333
  }
316
- const BOUNDARIES_DEFAULT_WATCH_PATHS = [
317
- 'sharkcraft',
318
- 'packages',
319
- 'apps',
320
- 'libs',
321
- 'src',
322
- 'tools',
323
- ];
324
- async function checkBoundariesOnce(args) {
334
+ async function checkBoundaries(args) {
325
335
  const cwd = resolveCwd(args);
326
336
  const inspection = await inspectSharkcraft({ cwd });
327
337
  const rules = inspection.boundaryRegistry.list();
@@ -521,8 +531,8 @@ async function checkBoundariesOnce(args) {
521
531
  // ────────────────────────────────────────────────────────────────────────
522
532
  export const checkCommand = {
523
533
  name: 'check',
524
- description: 'Run SharkCraft-level validation across knowledge / rules / templates / pipelines / packs / action hints / doctor. `check boundaries [--watch [--paths a,b] [--debounce N] [--once]]` re-runs the boundary scan on file changes.',
525
- usage: 'shrk [--cwd <dir>] check [packs|pipelines|knowledge|generation|boundaries|imports] [--strict] [--min-score <0-100>] [--json] [--watch [--paths <list>] [--debounce N] [--once]]',
534
+ description: 'Run SharkCraft-level validation across knowledge / rules / templates / pipelines / packs / action hints / doctor.',
535
+ usage: 'shrk [--cwd <dir>] check [packs|pipelines|knowledge|generation] [--strict] [--min-score <0-100>] [--json]',
526
536
  async run(args) {
527
537
  const sub = args.positional[0];
528
538
  if (sub === 'generation')
@@ -1 +1 @@
1
- {"version":3,"file":"command-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/command-catalog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command-catalog.d.ts","sourceRoot":"","sources":["../../src/commands/command-catalog.ts"],"names":[],"mappings":"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"}
@@ -1108,7 +1108,13 @@ export const COMMAND_CATALOG = Object.freeze([
1108
1108
  }),
1109
1109
  entry({
1110
1110
  command: 'mcp serve',
1111
- description: 'Start the read-only MCP server (stdio).',
1111
+ description: 'Start the read-only MCP server (stdio or --http).',
1112
+ category: 'meta',
1113
+ safetyLevel: SafetyLevel.ReadOnly,
1114
+ }),
1115
+ entry({
1116
+ command: 'mcp install',
1117
+ description: 'Print the MCP config snippet + path for Claude Code / Claude Desktop / Cursor / Cline (copy-paste, no file writes).',
1112
1118
  category: 'meta',
1113
1119
  safetyLevel: SafetyLevel.ReadOnly,
1114
1120
  }),
@@ -2260,6 +2266,13 @@ export const COMMAND_CATALOG = Object.freeze([
2260
2266
  safetyLevel: SafetyLevel.ReadOnly,
2261
2267
  mcpAvailable: true,
2262
2268
  }),
2269
+ entry({
2270
+ command: 'packs compat --fast',
2271
+ description: 'Pack compat scan with regex-only export walker (legacy). Default is TS-AST based.',
2272
+ category: 'packs',
2273
+ safetyLevel: SafetyLevel.ReadOnly,
2274
+ mcpAvailable: false,
2275
+ }),
2263
2276
  entry({
2264
2277
  command: 'onboard adopt status --max-age-days',
2265
2278
  description: 'Adoption checkpoint status with custom max-age (default 30 days).',
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA0JhC,eAAO,MAAM,aAAa,EAAE,eAW3B,CAAC;AA0ZF,eAAO,MAAM,qBAAqB,EAAE,eAmCnC,CAAC;AAuDF,eAAO,MAAM,yBAAyB,EAAE,eAavC,CAAC;AAIF,eAAO,MAAM,wBAAwB,EAAE,eA2CtC,CAAC;AAgCF,eAAO,MAAM,6BAA6B,EAAE,eAa3C,CAAC"}
1
+ {"version":3,"file":"doctor.command.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAwJhC,eAAO,MAAM,aAAa,EAAE,eAW3B,CAAC;AA+ZF,eAAO,MAAM,qBAAqB,EAAE,eAmCnC,CAAC;AAuDF,eAAO,MAAM,yBAAyB,EAAE,eAavC,CAAC;AAIF,eAAO,MAAM,wBAAwB,EAAE,eA2CtC,CAAC;AAgCF,eAAO,MAAM,6BAA6B,EAAE,eAa3C,CAAC"}
@@ -38,7 +38,7 @@ function describeStrictMode(mode) {
38
38
  case 'all':
39
39
  return 'strict=all (every warning fails)';
40
40
  case 'warnings':
41
- return 'strict=warnings (structural warnings fail, advisory excluded)';
41
+ return 'strict=warnings (structural warnings fail, hint-quality excluded)';
42
42
  case 'errors':
43
43
  return 'strict=errors (only errors fail)';
44
44
  case 'off':
@@ -59,10 +59,8 @@ function evaluateStrict(mode, checks, errorCount) {
59
59
  for (const c of checks) {
60
60
  if (c.severity !== DoctorSeverity.Warning)
61
61
  continue;
62
- // `--strict=warnings` excludes anything the inspector flagged as
63
- // advisory (action-hint quality today, any future advisory category
64
- // tomorrow). `--strict=all` counts every warning, advisory or not.
65
- if (mode === 'warnings' && c.advisory === true) {
62
+ const isHintQuality = c.id.startsWith('actionhints-');
63
+ if (mode === 'warnings' && isHintQuality) {
66
64
  excludedWarnings += 1;
67
65
  }
68
66
  else {
@@ -76,7 +74,7 @@ function evaluateStrict(mode, checks, errorCount) {
76
74
  excludedWarnings,
77
75
  reason: mode === 'all'
78
76
  ? 'any warning'
79
- : 'structural warnings only (advisory excluded)',
77
+ : 'structural warnings only (hint-quality excluded)',
80
78
  };
81
79
  }
82
80
  function buildFilterOptions(args, suppressions) {
@@ -422,7 +420,7 @@ async function doctorCommandImpl(args) {
422
420
  void saveDoctorSuppressions;
423
421
  void existsSync;
424
422
  if (strictMode === 'warnings' && strictEval.excludedWarnings > 0) {
425
- process.stdout.write(` (strict=warnings excluded ${strictEval.excludedWarnings} advisory warning(s); use --strict=all to include)\n`);
423
+ process.stdout.write(` (strict=warnings excluded ${strictEval.excludedWarnings} hint-quality warning(s); use --strict=all to include)\n`);
426
424
  }
427
425
  // Surface acknowledgement state. Bare suppressions don't qualify as
428
426
  // acknowledgements; expiring/expired ones get a callout so authors don't
@@ -481,7 +479,8 @@ async function doctorCommandImpl(args) {
481
479
  }
482
480
  // Failure-to-success hints surface only when something is wrong.
483
481
  if (overallExitCode !== 0 || result.summary.warnings > 0) {
484
- process.stdout.write(renderFailureHints(doctorHints()));
482
+ const folderMissing = result.checks.some((c) => c.id === 'sharkcraft-folder' && (c.severity === 'error' || c.severity === 'warning'));
483
+ process.stdout.write(renderFailureHints(doctorHints({ sharkcraftFolderMissing: folderMissing })));
485
484
  }
486
485
  // When there are preview-eligible findings (action-hints,
487
486
  // knowledge-stale, template-drift, self-config, pack-conflict,
@@ -1 +1 @@
1
- {"version":3,"file":"help.command.d.ts","sourceRoot":"","sources":["../../src/commands/help.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAuB1C;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe;;;;cAK3C;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAA;KAAE,GAAG,MAAM;EA2FpF"}
1
+ {"version":3,"file":"help.command.d.ts","sourceRoot":"","sources":["../../src/commands/help.command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAyB1C;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe;;;;cAK3C;QAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAA;KAAE,GAAG,MAAM;EA2FpF"}
@@ -9,20 +9,22 @@ import { header } from "../output/format-output.js";
9
9
  */
10
10
  export function renderStartScreen() {
11
11
  const lines = [];
12
- lines.push('SharkCraft CLI — deterministic, local-first project intelligence for AI coding agents.');
12
+ lines.push('SharkCraft CLI — the safety layer beneath your AI coding agent.');
13
13
  lines.push('Usage: shrk [--cwd <dir>] <command> [...args]');
14
14
  lines.push('');
15
+ lines.push('Prove it in 60 seconds:');
16
+ lines.push(' $ shrk check boundaries --changed-only --since main');
17
+ lines.push(' $ shrk review packet --v3 --since main');
18
+ lines.push(' $ shrk mcp install claude-code — copy-paste the MCP entry');
19
+ lines.push('');
15
20
  lines.push('Core (always on):');
16
- lines.push(' $ shrk recommend "<task>" — what should I do?');
17
21
  lines.push(' $ shrk doctor — is the workspace healthy?');
18
- lines.push(' $ shrk context --task "<task>" focused context for a task');
22
+ lines.push(' $ shrk recommend "<task>" what command should I reach for?');
19
23
  lines.push(' $ shrk init — create sharkcraft/ + config skeleton');
20
- lines.push(' $ shrk check boundaries — boundary enforcement');
21
24
  lines.push(' $ shrk surface list — every command grouped by tier');
22
25
  lines.push('');
23
26
  lines.push('Discover the rest (extended tier — always callable):');
24
27
  lines.push(' $ shrk surface list — full surface, grouped by tier and profile');
25
- lines.push(' $ shrk surface profiles — named profiles (small-app / monorepo / ci / agent / pack-author)');
26
28
  lines.push(' $ shrk surface explain <cmd> — why a command has its current tier');
27
29
  lines.push(' $ shrk help <command> — usage for a specific command');
28
30
  lines.push(' $ shrk --full-help — the long, exhaustive help');
@@ -89,7 +91,7 @@ export function makeHelpCommand(registry) {
89
91
  process.stdout.write(renderStartScreen());
90
92
  return 0;
91
93
  }
92
- process.stdout.write(`SharkCraft CLI — structured project intelligence for AI coding agents\n`);
94
+ process.stdout.write(`SharkCraft CLI — the safety layer beneath your AI coding agent.\n`);
93
95
  process.stdout.write(`Usage: shrk [--cwd <dir>] <command> [...args]\n`);
94
96
  process.stdout.write(header('Top-level commands'));
95
97
  for (const c of registry.list()) {
@@ -1 +1 @@
1
- {"version":3,"file":"init.command.d.ts","sourceRoot":"","sources":["../../src/commands/init.command.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAwB,KAAK,eAAe,EAA+B,MAAM,wBAAwB,CAAC;AAmSjH,eAAO,MAAM,WAAW,EAAE,eA2FzB,CAAC"}
1
+ {"version":3,"file":"init.command.d.ts","sourceRoot":"","sources":["../../src/commands/init.command.ts"],"names":[],"mappings":"AAeA,OAAO,EAAwB,KAAK,eAAe,EAA+B,MAAM,wBAAwB,CAAC;AA4QjH,eAAO,MAAM,WAAW,EAAE,eA2FzB,CAAC"}
@@ -6,7 +6,6 @@ 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";
10
9
  import { applySurfaceTextEdit } from "../surface/surface-config-writer.js";
11
10
  import { flagBool, flagString, resolveCwd } from "../command-registry.js";
12
11
  import { bullet, header } from "../output/format-output.js";
@@ -109,13 +108,8 @@ async function applyPresetInit(cwd, mode) {
109
108
  process.stdout.write(bullet(`(warning) ${warn}`) + '\n');
110
109
  }
111
110
  process.stdout.write('\nNext:\n');
112
- for (const cmd of preset.recommendedNextCommands ?? [
113
- 'shrk init --zero-config --write',
114
- 'shrk doctor',
115
- 'shrk context --task "<task>"',
116
- ]) {
117
- process.stdout.write(bullet(`$ ${cmd}`) + '\n');
118
- }
111
+ process.stdout.write(bullet('$ shrk init --zero-config --write') + '\n');
112
+ process.stdout.write(bullet('Then prove it: $ shrk check boundaries --changed-only --since main') + '\n');
119
113
  if (!mode.skipGitignore) {
120
114
  const patch = ensureSharkcraftGitignore({ cwd, dryRun: true });
121
115
  process.stdout.write('\n' + renderGitignorePatch(patch, true));
@@ -134,11 +128,6 @@ async function applyPresetInit(cwd, mode) {
134
128
  source: 'override',
135
129
  });
136
130
  }
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);
142
131
  process.stdout.write(header('SharkCraft initialized'));
143
132
  process.stdout.write(`Preset: ${preset.id} — ${preset.title}\n`);
144
133
  process.stdout.write(`Folder: ${plan.sharkcraftDir}\n`);
@@ -175,29 +164,20 @@ async function applyPresetInit(cwd, mode) {
175
164
  process.stdout.write('\n' + renderGitignorePatch(patch, false));
176
165
  }
177
166
  }
178
- if (pathsAdvisory.annotated) {
179
- renderPathsAdvisory(pathsAdvisory);
180
- }
181
- process.stdout.write('\nNext:\n');
182
- for (const cmd of preset.recommendedNextCommands ?? [
183
- 'shrk doctor',
184
- 'shrk context --task "<task>"',
185
- ]) {
186
- process.stdout.write(bullet(`$ ${cmd}`) + '\n');
167
+ process.stdout.write('\nProve it works (60 seconds):\n');
168
+ process.stdout.write(bullet('$ shrk check boundaries --changed-only --since main') + '\n');
169
+ process.stdout.write(bullet('$ shrk review packet --v3 --since main') + '\n');
170
+ process.stdout.write('\nOptional:\n');
171
+ process.stdout.write(bullet('$ shrk doctor') + '\n');
172
+ process.stdout.write(bullet('$ shrk mcp serve # plug into Claude Code / Cursor / Cline') + '\n');
173
+ if (preset.recommendedNextCommands && preset.recommendedNextCommands.length > 0) {
174
+ process.stdout.write('\nPreset-specific next steps:\n');
175
+ for (const cmd of preset.recommendedNextCommands) {
176
+ process.stdout.write(bullet(`$ ${cmd}`) + '\n');
177
+ }
187
178
  }
188
- process.stdout.write(bullet('Start the MCP server: `shrk mcp serve` (or run it via Claude Code)') + '\n');
189
179
  return 0;
190
180
  }
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
- }
201
181
  function applyLegacyInit(cwd, force) {
202
182
  const { root } = detectProjectRoot(cwd);
203
183
  const sharkcraftDir = nodePath.join(root, 'sharkcraft');
@@ -231,10 +211,6 @@ function applyLegacyInit(cwd, force) {
231
211
  for (const s of skipped)
232
212
  process.stdout.write(bullet(s) + '\n');
233
213
  }
234
- const legacyAdvisory = annotatePathsAgainstDisk(cwd, sharkcraftDir);
235
- if (legacyAdvisory.annotated) {
236
- renderPathsAdvisory(legacyAdvisory);
237
- }
238
214
  process.stdout.write('\nNext:\n');
239
215
  process.stdout.write(bullet('Run `shrk inspect` to see your project summary.') + '\n');
240
216
  process.stdout.write(bullet('Run `shrk knowledge list` to see what was seeded.') + '\n');
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.command.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.command.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAKhC,eAAO,MAAM,UAAU,EAAE,eAiCxB,CAAC"}
1
+ {"version":3,"file":"mcp.command.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.command.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAKhC,eAAO,MAAM,UAAU,EAAE,eAiDxB,CAAC"}
@@ -6,7 +6,7 @@ import { buildSurfaceSummary, findCommandInSummary } from "../surface/surface-su
6
6
  export const mcpCommand = {
7
7
  name: 'mcp',
8
8
  description: 'MCP server operations (subcommand required).',
9
- usage: 'shrk [--cwd <dir>] mcp serve [--verbose] [--watch] [--http] [--port <n>] [--host <h>]',
9
+ usage: 'shrk [--cwd <dir>] mcp serve [--verbose] [--watch] [--http] [--port <n>] [--host <h>] | shrk mcp install [<harness>]',
10
10
  async run(args) {
11
11
  const sub = args.positional[0];
12
12
  if (sub === 'serve') {
@@ -35,10 +35,139 @@ export const mcpCommand = {
35
35
  return 1;
36
36
  }
37
37
  }
38
- process.stderr.write('Usage: shrk mcp serve [--http] [--port N] [--watch]\n');
38
+ if (sub === 'install') {
39
+ const harness = args.positional[1];
40
+ const showAll = flagBool(args, 'all-paths');
41
+ if (harness !== undefined && !HARNESSES.some((h) => h.id === harness)) {
42
+ process.stderr.write(`Unknown harness: ${harness}\nKnown: ${HARNESSES.map((h) => h.id).join(', ')}\n`);
43
+ return 2;
44
+ }
45
+ process.stdout.write(renderMcpInstallInstructions(harness, showAll));
46
+ return 0;
47
+ }
48
+ process.stderr.write('Usage:\n' +
49
+ ' shrk mcp serve [--http] [--port N] [--watch]\n' +
50
+ ' shrk mcp install [claude-code|claude-desktop|cursor|cline]\n');
39
51
  return 2;
40
52
  },
41
53
  };
54
+ const HARNESSES = [
55
+ {
56
+ id: 'claude-code',
57
+ label: 'Claude Code (Anthropic CLI)',
58
+ configPaths: [
59
+ { os: '*', path: '<repo>/.mcp.json # project-scoped (preferred)' },
60
+ { os: '*', path: '~/.claude.json # user-scoped (fallback)' },
61
+ ],
62
+ note: 'Claude Code reads both; project-scoped wins when present.',
63
+ },
64
+ {
65
+ id: 'claude-desktop',
66
+ label: 'Claude Desktop',
67
+ configPaths: [
68
+ { os: 'darwin', path: '~/Library/Application Support/Claude/claude_desktop_config.json' },
69
+ { os: 'win32', path: '%APPDATA%\\Claude\\claude_desktop_config.json' },
70
+ { os: 'linux', path: '~/.config/Claude/claude_desktop_config.json' },
71
+ ],
72
+ note: 'Restart Claude Desktop after editing.',
73
+ },
74
+ {
75
+ id: 'cursor',
76
+ label: 'Cursor IDE',
77
+ configPaths: [
78
+ { os: '*', path: '~/.cursor/mcp.json # user-scoped' },
79
+ { os: '*', path: '<repo>/.cursor/mcp.json # project-scoped' },
80
+ ],
81
+ note: 'Cursor merges both. Reload the IDE after editing.',
82
+ },
83
+ {
84
+ id: 'cline',
85
+ label: 'Cline (VS Code extension)',
86
+ configPaths: [
87
+ {
88
+ os: 'darwin',
89
+ path: '~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json',
90
+ },
91
+ {
92
+ os: 'win32',
93
+ path: '%APPDATA%\\Code\\User\\globalStorage\\saoudrizwan.claude-dev\\settings\\cline_mcp_settings.json',
94
+ },
95
+ {
96
+ os: 'linux',
97
+ path: '~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json',
98
+ },
99
+ ],
100
+ note: 'Reload the Cline panel after editing.',
101
+ },
102
+ ];
103
+ function currentOs() {
104
+ const p = process.platform;
105
+ if (p === 'darwin' || p === 'win32' || p === 'linux')
106
+ return p;
107
+ return 'other';
108
+ }
109
+ function pathsForPlatform(target, showAll) {
110
+ if (showAll)
111
+ return target.configPaths.map((p) => p.path);
112
+ const os = currentOs();
113
+ const matched = target.configPaths.filter((p) => p.os === '*' || p.os === os);
114
+ // If the current OS has no specific entry, fall back to all to avoid an
115
+ // empty list. (`other` platforms like FreeBSD land here.)
116
+ if (matched.length === 0)
117
+ return target.configPaths.map((p) => p.path);
118
+ return matched.map((p) => p.path);
119
+ }
120
+ const SHARKCRAFT_MCP_SNIPPET = `{
121
+ "mcpServers": {
122
+ "sharkcraft": {
123
+ "command": "shrk",
124
+ "args": ["mcp", "serve"]
125
+ }
126
+ }
127
+ }`;
128
+ function renderMcpInstallInstructions(harness, showAll) {
129
+ const lines = [];
130
+ if (!harness) {
131
+ lines.push('SharkCraft MCP server entry (universal, stdio transport):');
132
+ lines.push('');
133
+ lines.push(SHARKCRAFT_MCP_SNIPPET);
134
+ lines.push('');
135
+ lines.push('Paste it into one of these harnesses (`shrk mcp install <id>` for exact paths):');
136
+ lines.push('');
137
+ for (const h of HARNESSES) {
138
+ lines.push(` ${h.id.padEnd(16)} ${h.label}`);
139
+ }
140
+ lines.push('');
141
+ lines.push('After pasting, restart/reload the harness. The server is read-only — agents cannot write.');
142
+ return lines.join('\n') + '\n';
143
+ }
144
+ const target = HARNESSES.find((h) => h.id === harness);
145
+ if (!target) {
146
+ return (`Unknown harness: ${harness}\n` +
147
+ `Known: ${HARNESSES.map((h) => h.id).join(', ')}\n`);
148
+ }
149
+ const paths = pathsForPlatform(target, showAll);
150
+ const os = currentOs();
151
+ lines.push(`${target.label}`);
152
+ lines.push('');
153
+ lines.push(showAll || os === 'other'
154
+ ? 'Config file (all platforms):'
155
+ : `Config file (${os}; pass --all-paths to see every platform):`);
156
+ for (const p of paths)
157
+ lines.push(` ${p}`);
158
+ lines.push('');
159
+ lines.push('Add this entry (merge with any existing `mcpServers` block):');
160
+ lines.push('');
161
+ lines.push(SHARKCRAFT_MCP_SNIPPET);
162
+ if (target.note) {
163
+ lines.push('');
164
+ lines.push(target.note);
165
+ }
166
+ lines.push('');
167
+ lines.push('Verify by asking the agent: "List MCP tools available." You should see ~250 sharkcraft tools.');
168
+ lines.push('The server is read-only — agents cannot write. Use `shrk apply --verify-signature` for writes.');
169
+ return lines.join('\n') + '\n';
170
+ }
42
171
  /**
43
172
  * Build the MCP tier-gate resolver from the surface summary.
44
173
  * Returns a function that, given a tool, decides whether to refuse the
@@ -1 +1 @@
1
- {"version":3,"file":"onboard.command.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.command.ts"],"names":[],"mappings":"AA6CA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,cAAc,EAAE,eA4N5B,CAAC"}
1
+ {"version":3,"file":"onboard.command.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.command.ts"],"names":[],"mappings":"AA6CA,OAAO,EAML,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,eAAO,MAAM,cAAc,EAAE,eA2O5B,CAAC"}
@@ -5,8 +5,8 @@ import { flagBool, flagNumber, flagString, flagList, resolveCwd, } from "../comm
5
5
  import { asJson, header, kv } from "../output/format-output.js";
6
6
  export const onboardCommand = {
7
7
  name: 'onboard',
8
- description: 'Analyze an existing repository and produce a SharkCraft onboarding plan (rules / paths / templates / boundaries / pipelines + readiness estimate). Default is dry-run; `--write-drafts` writes advisory drafts under sharkcraft/onboarding/ (never overwrites rules.ts / paths.ts / templates.ts). `--scaffold-templates` drafts runnable template bodies. `--import-agents` parses AGENTS.md / CLAUDE.md / .cursor/rules into a draft. `--diff` compares the plan against the live config.',
9
- usage: 'shrk [--cwd <dir>] onboard [--dry-run] [--write-drafts] [--scaffold-templates] [--import-agents] [--diff] [--preset <id>] [--json]',
8
+ description: 'Analyze an existing repository and produce a SharkCraft onboarding plan (rules / paths / templates / boundaries / pipelines + readiness estimate). Default is dry-run; `--write-drafts` writes advisory drafts under sharkcraft/onboarding/ (never overwrites rules.ts / paths.ts / templates.ts). Re-running `--write-drafts` against hand-edited drafts performs a three-way merge against the previous snapshot; conflicts emit conflict markers inside the draft (use `--abort-on-conflict` for CI to leave the file untouched and exit non-zero). `--scaffold-templates` drafts runnable template bodies. `--import-agents` parses AGENTS.md / CLAUDE.md / .cursor/rules into a draft. `--diff` compares the plan against the live config.',
9
+ usage: 'shrk [--cwd <dir>] onboard [--dry-run] [--write-drafts] [--abort-on-conflict] [--scaffold-templates] [--import-agents] [--diff] [--preset <id>] [--json]',
10
10
  async run(args) {
11
11
  // Dispatch sub-verb: `shrk onboard adopt [...]`.
12
12
  if (args.positional[0] === 'adopt') {
@@ -15,6 +15,7 @@ export const onboardCommand = {
15
15
  }
16
16
  const cwd = resolveCwd(args);
17
17
  const writeDrafts = flagBool(args, 'write-drafts');
18
+ const abortOnConflict = flagBool(args, 'abort-on-conflict');
18
19
  const scaffoldTemplates = flagBool(args, 'scaffold-templates');
19
20
  const importAgents = flagBool(args, 'import-agents');
20
21
  const diffMode = flagBool(args, 'diff');
@@ -35,6 +36,7 @@ export const onboardCommand = {
35
36
  written = writeOnboardingDrafts(plan, {
36
37
  projectRoot: cwd,
37
38
  ...(importedAgentRules ? { importedAgentRules } : {}),
39
+ abortOnConflict,
38
40
  });
39
41
  }
40
42
  const diff = diffMode ? buildOnboardingDiff(inspection, plan) : undefined;
@@ -166,8 +168,18 @@ export const onboardCommand = {
166
168
  if (writeDrafts && written) {
167
169
  process.stdout.write(`Wrote ${written.files.length} draft file(s) to:\n ${written.outDir}\n`);
168
170
  for (const f of written.files) {
169
- process.stdout.write(` + ${f.path} (${f.bytes} bytes)\n`);
171
+ process.stdout.write(` + ${f.path} (${f.bytes} bytes) [${f.mergeStatus}]\n`);
170
172
  }
173
+ if (written.conflicts > 0) {
174
+ process.stderr.write(`\nConflict regions emitted in ${written.conflicts} draft file(s). ` +
175
+ 'Resolve <<<<<<< / ======= / >>>>>>> markers before adopting.\n');
176
+ }
177
+ if (written.aborted > 0) {
178
+ process.stderr.write(`\n--abort-on-conflict: ${written.aborted} draft file(s) left unchanged due to conflicts.\n`);
179
+ return 1;
180
+ }
181
+ if (written.conflicts > 0)
182
+ return 2;
171
183
  }
172
184
  else if (dryRun) {
173
185
  process.stdout.write('Dry-run only. Re-run with `--write-drafts` to write advisory drafts.\n');
@@ -1 +1 @@
1
- {"version":3,"file":"packs-new.d.ts","sourceRoot":"","sources":["../../src/commands/packs-new.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAIhC,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,YAAY,GAAG,kBAAkB,CAAC;AAUpG,UAAU,aAAa;IACrB,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CA+G/E;AA4TD,eAAO,MAAM,eAAe,EAAE,eAoG7B,CAAC;AAUF,eAAO,MAAM,gBAAgB,EAAE,eAqI9B,CAAC"}
1
+ {"version":3,"file":"packs-new.d.ts","sourceRoot":"","sources":["../../src/commands/packs-new.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAGhC,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,YAAY,GAAG,kBAAkB,CAAC;AAUpG,UAAU,aAAa;IACrB,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CA+G/E;AA4TD,eAAO,MAAM,eAAe,EAAE,eAoG7B,CAAC;AAUF,eAAO,MAAM,gBAAgB,EAAE,eAqI9B,CAAC"}
@@ -1,8 +1,15 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
1
9
  import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
2
10
  import * as nodePath from 'node:path';
3
11
  import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
4
12
  import { asJson, header, kv } from "../output/format-output.js";
5
- import { importModuleViaLoader } from '@shrkcrft/core';
6
13
  const VALID_KINDS = new Set([
7
14
  'generic',
8
15
  'framework',
@@ -638,7 +645,7 @@ async function runRuntimePackTest(input) {
638
645
  if (existsSync(entry)) {
639
646
  try {
640
647
  const { pathToFileURL } = await import('node:url');
641
- const mod = (await importModuleViaLoader(entry));
648
+ const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(entry).href + `?bust=${Date.now()}`)));
642
649
  const value = mod.default ?? mod;
643
650
  const shape = describeShape(value);
644
651
  modules.push({
@@ -685,7 +692,7 @@ async function runRuntimePackTest(input) {
685
692
  continue;
686
693
  try {
687
694
  const { pathToFileURL } = await import('node:url');
688
- const mod = (await importModuleViaLoader(full));
695
+ const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(full).href + `?bust=${Date.now()}`)));
689
696
  const value = mod.default;
690
697
  const arr = Array.isArray(value) ? value : null;
691
698
  modules.push({
@@ -1 +1 @@
1
- {"version":3,"file":"packs.command.d.ts","sourceRoot":"","sources":["../../src/commands/packs.command.ts"],"names":[],"mappings":"AAoBA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAQhC,eAAO,MAAM,yBAAyB,EAAE,eAoCvC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,eAsGzC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,eA+CnC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAuD9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAsE7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAqDjC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAyFhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAqEhC,CAAC;AA4DF,eAAO,MAAM,gBAAgB,EAAE,eA+K9B,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eAmCtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAmFhC,CAAC;AAMF,eAAO,MAAM,qBAAqB,EAAE,eA4BnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,eA+E/B,CAAC"}
1
+ {"version":3,"file":"packs.command.d.ts","sourceRoot":"","sources":["../../src/commands/packs.command.ts"],"names":[],"mappings":"AAqBA,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAOhC,eAAO,MAAM,yBAAyB,EAAE,eAoCvC,CAAC;AAEF,eAAO,MAAM,2BAA2B,EAAE,eAsGzC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,eA+CnC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,eAuD9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,eAsE7B,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,eAqDjC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAyFhC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAqEhC,CAAC;AA4DF,eAAO,MAAM,gBAAgB,EAAE,eA+K9B,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,eAmCtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,eAyFhC,CAAC;AAMF,eAAO,MAAM,qBAAqB,EAAE,eA4BnC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,eA+E/B,CAAC"}