@shrkcrft/cli 0.1.0-alpha.8 → 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 (74) 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 +3 -7
  7. package/dist/commands/command-catalog.d.ts.map +1 -1
  8. package/dist/commands/command-catalog.js +47 -113
  9. package/dist/commands/commands.command.d.ts.map +1 -1
  10. package/dist/commands/commands.command.js +4 -4
  11. package/dist/commands/constructs.command.d.ts.map +1 -1
  12. package/dist/commands/constructs.command.js +22 -5
  13. package/dist/commands/doctor.command.d.ts.map +1 -1
  14. package/dist/commands/doctor.command.js +9 -42
  15. package/dist/commands/export.command.d.ts.map +1 -1
  16. package/dist/commands/export.command.js +3 -76
  17. package/dist/commands/help.command.d.ts +3 -4
  18. package/dist/commands/help.command.d.ts.map +1 -1
  19. package/dist/commands/help.command.js +21 -77
  20. package/dist/commands/helper.command.js +1 -1
  21. package/dist/commands/import.command.d.ts.map +1 -1
  22. package/dist/commands/import.command.js +5 -121
  23. package/dist/commands/init.command.d.ts.map +1 -1
  24. package/dist/commands/init.command.js +16 -184
  25. package/dist/commands/mcp.command.d.ts.map +1 -1
  26. package/dist/commands/mcp.command.js +131 -2
  27. package/dist/commands/onboard.command.d.ts.map +1 -1
  28. package/dist/commands/onboard.command.js +15 -3
  29. package/dist/commands/packs-new.d.ts +1 -1
  30. package/dist/commands/packs-new.d.ts.map +1 -1
  31. package/dist/commands/packs-new.js +36 -5
  32. package/dist/commands/packs.command.d.ts.map +1 -1
  33. package/dist/commands/packs.command.js +17 -3
  34. package/dist/commands/plugin.command.d.ts +11 -0
  35. package/dist/commands/plugin.command.d.ts.map +1 -0
  36. package/dist/commands/plugin.command.js +394 -0
  37. package/dist/commands/profiles.command.js +4 -4
  38. package/dist/commands/release.command.js +13 -13
  39. package/dist/commands/review.command.d.ts.map +1 -1
  40. package/dist/commands/review.command.js +28 -2
  41. package/dist/commands/search.command.js +1 -1
  42. package/dist/commands/task-context.command.js +16 -0
  43. package/dist/export/export-formats.d.ts +1 -1
  44. package/dist/export/export-formats.d.ts.map +1 -1
  45. package/dist/export/export-formats.js +12 -139
  46. package/dist/init/init-templates.d.ts.map +1 -1
  47. package/dist/init/init-templates.js +113 -133
  48. package/dist/main.d.ts +1 -1
  49. package/dist/main.d.ts.map +1 -1
  50. package/dist/main.js +46 -117
  51. package/dist/output/failure-hints.d.ts +9 -1
  52. package/dist/output/failure-hints.d.ts.map +1 -1
  53. package/dist/output/failure-hints.js +8 -2
  54. package/dist/output/watch-loop.d.ts +1 -9
  55. package/dist/output/watch-loop.d.ts.map +1 -1
  56. package/dist/output/watch-loop.js +3 -13
  57. package/dist/schemas/json-schemas.d.ts +36 -36
  58. package/dist/schemas/json-schemas.js +36 -36
  59. package/dist/surface/about.d.ts.map +1 -1
  60. package/dist/surface/about.js +15 -37
  61. package/dist/surface/no-args-landing.d.ts.map +1 -1
  62. package/dist/surface/no-args-landing.js +13 -9
  63. package/dist/surface/surface-config-writer.d.ts.map +1 -1
  64. package/dist/surface/surface-config-writer.js +11 -23
  65. package/package.json +25 -26
  66. package/dist/commands/diff-check.command.d.ts +0 -30
  67. package/dist/commands/diff-check.command.d.ts.map +0 -1
  68. package/dist/commands/diff-check.command.js +0 -210
  69. package/dist/export/claude-commands-export.d.ts +0 -60
  70. package/dist/export/claude-commands-export.d.ts.map +0 -1
  71. package/dist/export/claude-commands-export.js +0 -276
  72. package/dist/init/paths-advisory.d.ts +0 -20
  73. package/dist/init/paths-advisory.d.ts.map +0 -1
  74. package/dist/init/paths-advisory.js +0 -88
@@ -8,46 +8,24 @@ import { SHARKCRAFT_VERSION } from '@shrkcrft/shared';
8
8
  * `docs/`; this is the in-binary summary.
9
9
  */
10
10
  export function renderAbout() {
11
- return `SharkCraft v${SHARKCRAFT_VERSION}
11
+ return `SharkCraft v${SHARKCRAFT_VERSION} — the safety layer beneath your AI coding agent.
12
12
 
13
- What it is
14
- A deterministic, local-first toolkit that gives AI coding agents
15
- durable project context. Ships as a CLI (\`shrk\`) the only write
16
- path plus a read-only MCP server, plus a library of structured
17
- assets (knowledge, rules, paths, templates, pipelines, presets,
18
- boundaries).
13
+ Three structural guarantees (not prompts):
14
+ - MCP is read-only. Agents cannot write through it.
15
+ - Writes flow through signed plans. \`shrk apply --verify-signature\`
16
+ refuses on divergence.
17
+ - Boundaries are mechanical. \`shrk check boundaries --changed-only\`
18
+ fails only on violations the current diff introduced.
19
19
 
20
- What it is NOT
21
- There is no AI inside the engine. Every output is a pure function
22
- of the workspace + the asset registries. The agent uses the engine;
23
- the engine never calls a model.
20
+ On top of that: typed rules, paths, templates, pipelines, presets — so
21
+ the agent hallucinates less inside the bounds the safety surface enforces.
22
+ No AI inside the engine; every output is a pure function of the workspace.
24
23
 
25
- The safety contract
26
- - All write paths are preview-first. \`--apply\` is opt-in, scoped,
27
- and idempotent.
28
- - MCP is read-only. Every MCP tool returns data + a next-command
29
- hint; the human runs the CLI for any write.
30
- - Apply requires \`--verify-signature\` for signed plans, refuses
31
- on divergence unless \`--allow-divergent\`.
24
+ Try:
25
+ shrk check boundaries --changed-only --since main
26
+ shrk review packet --v3 --since main
27
+ shrk mcp install claude-code
32
28
 
33
- Calibration to project size
34
- Surface tiers (\`shrk surface list\`):
35
- - core always on
36
- - extended visible in --help, callable
37
- - experimental hidden until enabled (\`shrk surface enable\`)
38
- Project shape (\`shrk doctor\`) drives the default surface for a
39
- fresh repo.
40
-
41
- Where to read more
42
- docs/overview.md what SharkCraft is and isn't
43
- docs/philosophy.md the non-negotiable design rules
44
- docs/surface-tiers.md the tier model
45
- docs/safety-model.md plan / review / apply contract
46
-
47
- Quick start
48
- shrk doctor health check
49
- shrk task "<what>" full task packet (rules + templates + commands)
50
- shrk recommend "<what>" what command should I reach for?
51
- shrk surface list what is available in this repo
29
+ Docs: overview.md · safety-model.md · INDEX.md · demo.md
52
30
  `;
53
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"no-args-landing.d.ts","sourceRoot":"","sources":["../../src/surface/no-args-landing.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BtE"}
1
+ {"version":3,"file":"no-args-landing.d.ts","sourceRoot":"","sources":["../../src/surface/no-args-landing.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAiCtE"}
@@ -8,7 +8,7 @@ import { buildSurfaceSummary } from "./surface-summary.js";
8
8
  */
9
9
  export async function renderNoArgsLanding(cwd) {
10
10
  const lines = [];
11
- lines.push(`shrk v${SHARKCRAFT_VERSION} — deterministic context for AI coding agents.`);
11
+ lines.push(`shrk v${SHARKCRAFT_VERSION} — the safety layer beneath your AI coding agent.`);
12
12
  lines.push('');
13
13
  let totals = '';
14
14
  try {
@@ -21,16 +21,20 @@ export async function renderNoArgsLanding(cwd) {
21
21
  }
22
22
  lines.push(totals);
23
23
  lines.push('');
24
- lines.push('Most useful next:');
25
- lines.push(' shrk doctor health check');
26
- lines.push(' shrk task "<what>" full packet for a task');
27
- lines.push(' shrk recommend "<what>" what should I do?');
28
- lines.push(' shrk surface list what is available in this repo');
24
+ lines.push('Prove it in 60 seconds:');
25
+ lines.push(' shrk check boundaries --changed-only --since main');
26
+ lines.push(' fail only on violations the diff introduced');
27
+ lines.push(' shrk review packet --v3 --since main');
28
+ lines.push(' structured packet for an AI PR reviewer');
29
+ lines.push(' shrk apply --verify-signature <plan.json>');
30
+ lines.push(' signed-plan write — refuses on divergence');
29
31
  lines.push('');
30
- lines.push('See:');
32
+ lines.push('Orient:');
33
+ lines.push(' shrk doctor health check + AI-readiness score');
34
+ lines.push(' shrk recommend "<task>" what command should I reach for?');
35
+ lines.push(' shrk surface list what is available in this repo');
36
+ lines.push(' shrk --about the safety contract in one screen');
31
37
  lines.push(' shrk --help every visible command');
32
- lines.push(' shrk surface explain <cmd> why a command is/is not visible');
33
- lines.push(' shrk --about what shrk is and is not');
34
38
  lines.push('');
35
39
  return lines.join('\n');
36
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"surface-config-writer.d.ts","sourceRoot":"","sources":["../../src/surface/surface-config-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,oBAAoB;IACpB,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,SAAS,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACrC,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACrC,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,KAAK,EAAE,SAAS,kBAAkB,EAAE,GACnC,kBAAkB,CA0BpB;AAOD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,kBAAkB,GACvB,yBAAyB,CAe3B;AAoBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAO,GAAG,MAAM,CAsBjF;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CA6BtF;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE/D"}
1
+ {"version":3,"file":"surface-config-writer.d.ts","sourceRoot":"","sources":["../../src/surface/surface-config-writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,oBAAoB;IACpB,KAAK,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,SAAS,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACrC,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACrC,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,KAAK,EAAE,SAAS,kBAAkB,EAAE,GACnC,kBAAkB,CA0BpB;AAOD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,kBAAkB,GACvB,yBAAyB,CAe3B;AAmBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAO,GAAG,MAAM,CAsBjF;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAgBtF;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE/D"}
@@ -72,11 +72,10 @@ function fileExists(p) {
72
72
  return false;
73
73
  }
74
74
  }
75
- // Plain default export no @shrkcrft/* import required. The config
76
- // loader (packages/config/src/config-loader.ts) validates by shape, so a
77
- // literal object works the same as a `defineSharkCraftConfig()` call.
78
- const DEFAULT_CONFIG_BODY = `export default {
79
- };
75
+ const DEFAULT_CONFIG_BODY = `import { defineSharkCraftConfig } from '@shrkcrft/config';
76
+
77
+ export default defineSharkCraftConfig({
78
+ });
80
79
  `;
81
80
  const SURFACE_BLOCK_REGEX = /(^\s*surface\s*:\s*\{[\s\S]*?\}\s*,?\s*\n)/m;
82
81
  /**
@@ -121,25 +120,14 @@ export function applySurfaceTextEdit(original, surface) {
121
120
  if (SURFACE_BLOCK_REGEX.test(original)) {
122
121
  return original.replace(SURFACE_BLOCK_REGEX, block);
123
122
  }
124
- // (A) `defineSharkCraftConfig({ ... })` style insert before the `})`.
125
- const closeFn = /(\n)(\}\)\s*;?\s*)$/m;
126
- if (closeFn.test(original)) {
127
- return original.replace(closeFn, `\n${block}$2`);
123
+ // Insert before the closing `})` / `});` of the config object.
124
+ // Prefer the last `})` so nested objects don't trip us up.
125
+ const closeRegex = /(\n)(\}\)\s*;?\s*)$/m;
126
+ if (closeRegex.test(original)) {
127
+ return original.replace(closeRegex, `\n${block}$2`);
128
128
  }
129
- // (B) `const config = { ... };\nexport default config;` plain style —
130
- // insert before the `};` that closes the literal.
131
- const closePlain = /(\n)(\};?\s*\nexport\s+default\s+\w+\s*;?\s*\n*)$/m;
132
- if (closePlain.test(original)) {
133
- return original.replace(closePlain, `\n${block}$2`);
134
- }
135
- // (C) `export default { ... };` direct style — insert before the `};`.
136
- const closeDirect = /(\n)(\};?\s*\n*)$/m;
137
- if (closeDirect.test(original)) {
138
- return original.replace(closeDirect, `\n${block}$2`);
139
- }
140
- // Fallback: append at end with a plain default-exported config (no
141
- // `@shrkcrft/*` import required).
142
- return `${original}\n${DEFAULT_CONFIG_BODY.replace('};', `${block}};`)}`;
129
+ // Fallback: append at end with a defineSharkCraftConfig wrapper.
130
+ return `${original}\n${DEFAULT_CONFIG_BODY.replace('})', `${block}})`)}`;
143
131
  }
144
132
  /** Default config file path for a project. */
145
133
  export function defaultConfigFile(sharkcraftDir) {
package/package.json CHANGED
@@ -1,16 +1,15 @@
1
1
  {
2
2
  "name": "@shrkcrft/cli",
3
- "version": "0.1.0-alpha.8",
4
- "description": "SharkCraft CLI (`shrk`): structured project intelligence for AI coding agents.",
3
+ "version": "0.1.0-alpha.9",
4
+ "description": "SharkCraft CLI (`shrk`): the safety layer beneath your AI coding agent.",
5
5
  "license": "MIT",
6
6
  "author": "SharkCraft contributors",
7
7
  "type": "module",
8
8
  "main": "./dist/index.js",
9
- "types": "./dist/index.d.d.ts",
9
+ "types": "./dist/index.d.ts",
10
10
  "exports": {
11
11
  ".": {
12
12
  "types": "./dist/index.d.ts",
13
- "bun": "./src/index.ts",
14
13
  "import": "./dist/index.js",
15
14
  "default": "./dist/index.js"
16
15
  }
@@ -25,12 +24,12 @@
25
24
  ],
26
25
  "repository": {
27
26
  "type": "git",
28
- "url": "git+https://github.com/shrkcrft/sharkcraft.git",
27
+ "url": "git+https://github.com/sharkcraft/sharkcraft.git",
29
28
  "directory": "packages/cli"
30
29
  },
31
- "homepage": "https://github.com/shrkcrft/sharkcraft",
30
+ "homepage": "https://github.com/sharkcraft/sharkcraft",
32
31
  "bugs": {
33
- "url": "https://github.com/shrkcrft/sharkcraft/issues"
32
+ "url": "https://github.com/sharkcraft/sharkcraft/issues"
34
33
  },
35
34
  "keywords": [
36
35
  "sharkcraft",
@@ -47,25 +46,25 @@
47
46
  "typecheck": "tsc --noEmit -p tsconfig.json"
48
47
  },
49
48
  "dependencies": {
50
- "@shrkcrft/core": "^0.1.0-alpha.8",
51
- "@shrkcrft/config": "^0.1.0-alpha.8",
52
- "@shrkcrft/workspace": "^0.1.0-alpha.8",
53
- "@shrkcrft/knowledge": "^0.1.0-alpha.8",
54
- "@shrkcrft/context": "^0.1.0-alpha.8",
55
- "@shrkcrft/rules": "^0.1.0-alpha.8",
56
- "@shrkcrft/paths": "^0.1.0-alpha.8",
57
- "@shrkcrft/templates": "^0.1.0-alpha.8",
58
- "@shrkcrft/plugin-api": "^0.1.0-alpha.8",
59
- "@shrkcrft/dashboard-api": "^0.1.0-alpha.8",
60
- "@shrkcrft/pipelines": "^0.1.0-alpha.8",
61
- "@shrkcrft/presets": "^0.1.0-alpha.8",
62
- "@shrkcrft/boundaries": "^0.1.0-alpha.8",
63
- "@shrkcrft/generator": "^0.1.0-alpha.8",
64
- "@shrkcrft/importer": "^0.1.0-alpha.8",
65
- "@shrkcrft/inspector": "^0.1.0-alpha.8",
66
- "@shrkcrft/ai": "^0.1.0-alpha.8",
67
- "@shrkcrft/shared": "^0.1.0-alpha.8",
68
- "@shrkcrft/mcp-server": "^0.1.0-alpha.8"
49
+ "@shrkcrft/core": "^0.1.0-alpha.9",
50
+ "@shrkcrft/config": "^0.1.0-alpha.9",
51
+ "@shrkcrft/workspace": "^0.1.0-alpha.9",
52
+ "@shrkcrft/knowledge": "^0.1.0-alpha.9",
53
+ "@shrkcrft/context": "^0.1.0-alpha.9",
54
+ "@shrkcrft/rules": "^0.1.0-alpha.9",
55
+ "@shrkcrft/paths": "^0.1.0-alpha.9",
56
+ "@shrkcrft/templates": "^0.1.0-alpha.9",
57
+ "@shrkcrft/plugin-api": "^0.1.0-alpha.9",
58
+ "@shrkcrft/dashboard-api": "^0.1.0-alpha.9",
59
+ "@shrkcrft/pipelines": "^0.1.0-alpha.9",
60
+ "@shrkcrft/presets": "^0.1.0-alpha.9",
61
+ "@shrkcrft/boundaries": "^0.1.0-alpha.9",
62
+ "@shrkcrft/generator": "^0.1.0-alpha.9",
63
+ "@shrkcrft/importer": "^0.1.0-alpha.9",
64
+ "@shrkcrft/inspector": "^0.1.0-alpha.9",
65
+ "@shrkcrft/ai": "^0.1.0-alpha.9",
66
+ "@shrkcrft/shared": "^0.1.0-alpha.9",
67
+ "@shrkcrft/mcp-server": "^0.1.0-alpha.9"
69
68
  },
70
69
  "publishConfig": {
71
70
  "access": "public"
@@ -1,30 +0,0 @@
1
- /**
2
- * `shrk diff-check` — agent self-validation after edits.
3
- *
4
- * The story this command tells:
5
- * 1. An AI agent (Claude Code, Cursor, etc.) makes some file changes.
6
- * 2. Before declaring "done", the agent runs `shrk diff-check`.
7
- * 3. The command scopes both the boundary check and the
8
- * import-hygiene check to only the files the agent touched in the
9
- * current git diff.
10
- * 4. The output is a single agent-friendly JSON envelope with a
11
- * verdict (ok / warnings / errors) and a one-line next action.
12
- *
13
- * Why a new command instead of "just run `shrk check boundaries
14
- * --changed-only` and `shrk check imports --changed-only`":
15
- *
16
- * - One command instead of two — agents reliably run the *one* tool
17
- * they're told to run; chained-command workflows get skipped.
18
- * - One verdict — no need to OR two separate JSON outputs.
19
- * - Stable, narrow schema — designed for agent consumption, not
20
- * human terminals. Won't grow flags over time.
21
- * - Concrete `nextAction` line — the agent knows exactly what to do
22
- * next (declare done, fix N things, or re-run after a manual fix).
23
- *
24
- * This is a pure composer — all real logic stays in
25
- * `@shrkcrft/inspector` and `@shrkcrft/boundaries`. We just stitch
26
- * their outputs together with consistent scoping.
27
- */
28
- import { type ICommandHandler } from '../command-registry.js';
29
- export declare const diffCheckCommand: ICommandHandler;
30
- //# sourceMappingURL=diff-check.command.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"diff-check.command.d.ts","sourceRoot":"","sources":["../../src/commands/diff-check.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAcH,OAAO,EAIL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AA0GhC,eAAO,MAAM,gBAAgB,EAAE,eAiI9B,CAAC"}
@@ -1,210 +0,0 @@
1
- /**
2
- * `shrk diff-check` — agent self-validation after edits.
3
- *
4
- * The story this command tells:
5
- * 1. An AI agent (Claude Code, Cursor, etc.) makes some file changes.
6
- * 2. Before declaring "done", the agent runs `shrk diff-check`.
7
- * 3. The command scopes both the boundary check and the
8
- * import-hygiene check to only the files the agent touched in the
9
- * current git diff.
10
- * 4. The output is a single agent-friendly JSON envelope with a
11
- * verdict (ok / warnings / errors) and a one-line next action.
12
- *
13
- * Why a new command instead of "just run `shrk check boundaries
14
- * --changed-only` and `shrk check imports --changed-only`":
15
- *
16
- * - One command instead of two — agents reliably run the *one* tool
17
- * they're told to run; chained-command workflows get skipped.
18
- * - One verdict — no need to OR two separate JSON outputs.
19
- * - Stable, narrow schema — designed for agent consumption, not
20
- * human terminals. Won't grow flags over time.
21
- * - Concrete `nextAction` line — the agent knows exactly what to do
22
- * next (declare done, fix N things, or re-run after a manual fix).
23
- *
24
- * This is a pure composer — all real logic stays in
25
- * `@shrkcrft/inspector` and `@shrkcrft/boundaries`. We just stitch
26
- * their outputs together with consistent scoping.
27
- */
28
- import { buildImportHygieneReport, filterViolationsToChangedScope, inspectSharkcraft, resolveChangedFiles, } from '@shrkcrft/inspector';
29
- import { evaluateBoundaries, loadTsconfigPaths, scanImports, } from '@shrkcrft/boundaries';
30
- import { flagBool, flagString, resolveCwd, } from "../command-registry.js";
31
- import { asJson, bullet, header, kv } from "../output/format-output.js";
32
- const SCHEMA = 'sharkcraft.diff-check/v1';
33
- function resolveScope(args, cwd) {
34
- const staged = flagBool(args, 'staged');
35
- const since = flagString(args, 'since');
36
- const filesRaw = flagString(args, 'files');
37
- const files = filesRaw
38
- ? filesRaw.split(',').map((s) => s.trim()).filter((s) => s.length > 0)
39
- : [];
40
- if (files.length > 0) {
41
- return { mode: 'files', options: { projectRoot: cwd, files } };
42
- }
43
- if (staged) {
44
- return { mode: 'staged', options: { projectRoot: cwd, staged: true } };
45
- }
46
- if (since) {
47
- return { mode: 'since', options: { projectRoot: cwd, since } };
48
- }
49
- // Default: worktree (== `--changed-only` from `shrk check boundaries`).
50
- return {
51
- mode: 'worktree',
52
- options: { projectRoot: cwd, includeWorktree: true },
53
- };
54
- }
55
- function deriveVerdict(env) {
56
- const bErr = env.boundaries.counts.error;
57
- const bWarn = env.boundaries.counts.warning;
58
- const iErr = env.imports.verdict === 'errors' ? (env.imports.counts.error ?? env.imports.findings.length) : 0;
59
- const iWarn = env.imports.verdict === 'warnings' ? (env.imports.counts.warning ?? env.imports.findings.length) : 0;
60
- if (env.scope.fileCount === 0) {
61
- return {
62
- verdict: 'ok',
63
- summary: 'No files changed in the current diff scope.',
64
- nextAction: 'Nothing to check. If you expected changes, verify your `--staged` / `--since <ref>` flag or save your edits first.',
65
- };
66
- }
67
- if (bErr > 0 || iErr > 0) {
68
- const parts = [];
69
- if (bErr > 0)
70
- parts.push(`${bErr} boundary violation${bErr === 1 ? '' : 's'}`);
71
- if (iErr > 0)
72
- parts.push(`${iErr} import-hygiene error${iErr === 1 ? '' : 's'}`);
73
- return {
74
- verdict: 'errors',
75
- summary: `Diff fails the gate: ${parts.join(', ')}.`,
76
- nextAction: 'Fix every error in `boundaries.violations` and `imports.findings` (look at each entry\'s `suggestedFix` line), then re-run `shrk diff-check`.',
77
- };
78
- }
79
- if (bWarn > 0 || iWarn > 0) {
80
- const parts = [];
81
- if (bWarn > 0)
82
- parts.push(`${bWarn} boundary warning${bWarn === 1 ? '' : 's'}`);
83
- if (iWarn > 0)
84
- parts.push(`${iWarn} import-hygiene warning${iWarn === 1 ? '' : 's'}`);
85
- return {
86
- verdict: 'warnings',
87
- summary: `Diff passes the gate with ${parts.join(', ')}.`,
88
- nextAction: 'Safe to declare done. Review warnings if the diff touches a sensitive area; otherwise these are non-blocking.',
89
- };
90
- }
91
- return {
92
- verdict: 'ok',
93
- summary: `Diff passes the gate (${env.scope.fileCount} file${env.scope.fileCount === 1 ? '' : 's'}, 0 violations).`,
94
- nextAction: 'Safe to declare done.',
95
- };
96
- }
97
- export const diffCheckCommand = {
98
- name: 'diff-check',
99
- description: 'Self-check the current git diff against this project\'s boundary + import-hygiene rules. Single-call composite of `shrk check boundaries --changed-only` + `shrk check imports --changed-only`, with one verdict and one nextAction line. Designed for AI agents to run after editing — pass --json for the structured envelope.',
100
- usage: 'shrk [--cwd <dir>] diff-check [--staged | --since <ref> | --files a.ts,b.ts] [--json]',
101
- async run(args) {
102
- const cwd = resolveCwd(args);
103
- const wantJson = flagBool(args, 'json');
104
- const { mode, options: scopeOptions } = resolveScope(args, cwd);
105
- // 1. Resolve the changed file set once. Both engines re-use it.
106
- const changed = resolveChangedFiles(scopeOptions);
107
- const changedFiles = changed.files;
108
- // 2. Boundary engine — only if rules exist.
109
- const inspection = await inspectSharkcraft({ cwd });
110
- const rules = inspection.boundaryRegistry.list();
111
- let boundaryBlock = {
112
- ran: false,
113
- rulesEvaluated: 0,
114
- counts: { error: 0, warning: 0, info: 0 },
115
- violations: [],
116
- };
117
- if (rules.length > 0 && changedFiles.length > 0) {
118
- const scan = scanImports({ projectRoot: cwd });
119
- const tsconfigPaths = loadTsconfigPaths(cwd);
120
- const evalResult = evaluateBoundaries(scan, rules, {
121
- ...(tsconfigPaths.aliases.size > 0 ? { tsconfigPaths } : {}),
122
- });
123
- const filtered = filterViolationsToChangedScope(evalResult.violations, scopeOptions);
124
- boundaryBlock = {
125
- ran: true,
126
- rulesEvaluated: evalResult.rulesEvaluated,
127
- counts: {
128
- error: filtered.includedViolations.filter((v) => v.severity === 'error').length,
129
- warning: filtered.includedViolations.filter((v) => v.severity === 'warning').length,
130
- info: filtered.includedViolations.filter((v) => v.severity === 'info').length,
131
- },
132
- violations: filtered.includedViolations,
133
- };
134
- }
135
- else if (rules.length > 0 && changedFiles.length === 0) {
136
- boundaryBlock = { ...boundaryBlock, ran: true, rulesEvaluated: rules.length };
137
- }
138
- // 3. Import-hygiene engine — always runs, but scoped to changed files.
139
- let importsBlock = {
140
- ran: false,
141
- verdict: 'skipped',
142
- counts: {},
143
- findings: [],
144
- };
145
- if (changedFiles.length > 0) {
146
- const report = buildImportHygieneReport(cwd, { files: changedFiles });
147
- importsBlock = {
148
- ran: true,
149
- verdict: report.verdict,
150
- counts: report.counts ?? {},
151
- findings: report.findings,
152
- };
153
- }
154
- // 4. Build envelope + derive verdict.
155
- const partial = {
156
- schema: SCHEMA,
157
- generatedAt: new Date().toISOString(),
158
- scope: {
159
- mode,
160
- files: changedFiles,
161
- fileCount: changedFiles.length,
162
- },
163
- boundaries: boundaryBlock,
164
- imports: importsBlock,
165
- };
166
- const { verdict, summary, nextAction } = deriveVerdict(partial);
167
- const envelope = { ...partial, verdict, summary, nextAction };
168
- // 5. Render.
169
- if (wantJson) {
170
- process.stdout.write(asJson(envelope) + '\n');
171
- return verdict === 'errors' ? 1 : 0;
172
- }
173
- process.stdout.write(header('Diff check'));
174
- process.stdout.write(kv('scope', `${envelope.scope.mode} (${envelope.scope.fileCount} file${envelope.scope.fileCount === 1 ? '' : 's'})`) + '\n');
175
- process.stdout.write(kv('boundaries', envelope.boundaries.ran
176
- ? `${envelope.boundaries.counts.error} errors, ${envelope.boundaries.counts.warning} warnings`
177
- : '(no rules configured or no scoped files)') + '\n');
178
- process.stdout.write(kv('imports', envelope.imports.ran
179
- ? `verdict=${envelope.imports.verdict} (${envelope.imports.findings.length} finding${envelope.imports.findings.length === 1 ? '' : 's'})`
180
- : '(no scoped files)') + '\n');
181
- process.stdout.write(kv('verdict', envelope.verdict) + '\n');
182
- process.stdout.write('\n');
183
- process.stdout.write(envelope.summary + '\n');
184
- if (envelope.boundaries.violations.length > 0) {
185
- process.stdout.write('\nBoundary violations:\n');
186
- for (const v of envelope.boundaries.violations.slice(0, 10)) {
187
- const file = String(v.file ?? '');
188
- const rule = String(v.ruleId ?? '');
189
- const fix = v.suggestedFix ? ` — ${String(v.suggestedFix)}` : '';
190
- process.stdout.write(bullet(`${rule} in ${file}${fix}`) + '\n');
191
- }
192
- if (envelope.boundaries.violations.length > 10) {
193
- process.stdout.write(` … and ${envelope.boundaries.violations.length - 10} more (pass --json for full list).\n`);
194
- }
195
- }
196
- if (envelope.imports.findings.length > 0) {
197
- process.stdout.write('\nImport findings:\n');
198
- for (const f of envelope.imports.findings.slice(0, 10)) {
199
- const file = String(f.path ?? f.file ?? '');
200
- const kind = String(f.kind ?? '');
201
- process.stdout.write(bullet(`${kind} in ${file}`) + '\n');
202
- }
203
- if (envelope.imports.findings.length > 10) {
204
- process.stdout.write(` … and ${envelope.imports.findings.length - 10} more (pass --json for full list).\n`);
205
- }
206
- }
207
- process.stdout.write(`\nNext: ${envelope.nextAction}\n`);
208
- return verdict === 'errors' ? 1 : 0;
209
- },
210
- };
@@ -1,60 +0,0 @@
1
- /**
2
- * `.claude/commands/` generator — emits per-project slash commands
3
- * for Claude Code. Companion to `claude-skill` export, but with a
4
- * different inversion semantics:
5
- *
6
- * - **claude-skill** loads rules into Claude's prompt automatically
7
- * based on description match. Passive — Claude reads the rules.
8
- * - **claude-commands** registers slash commands the USER invokes
9
- * (`/new-service`, `/check-changes`). Active — the command IS the
10
- * recipe; Claude follows it step-by-step.
11
- *
12
- * Generated commands fall into two buckets:
13
- *
14
- * **Static commands** (always present, project-agnostic recipes):
15
- * - `/follow-shrk` — short reminder of the apply-gate flow.
16
- * - `/check-changes` — runs `shrk check boundaries --changed-only`
17
- * scoped to the current diff and reports back.
18
- * - `/shrk-brief` — runs `shrk brief` and uses the output for the
19
- * current task.
20
- * - `/explain-file <path>` — per-file rules / paths / boundary
21
- * lookup (pairs with `shrk advise <path>` from Phase 3).
22
- *
23
- * **Per-template commands** (one per id in `sharkcraft/templates.ts`):
24
- * - `/new-<template-id>` — Claude runs `shrk gen <template-id>
25
- * <name> --dry-run --save-plan ...`, reviews the plan, and
26
- * applies via `shrk apply ... --verify-signature --validate`.
27
- *
28
- * Generated files are self-contained markdown — no `@shrkcrft/*`
29
- * imports, no shell expansions. Each one is a complete "recipe in a
30
- * file" that Claude Code reads when the user types the slash command.
31
- */
32
- import type { ISharkcraftInspection } from '@shrkcrft/inspector';
33
- export interface IClaudeCommandFile {
34
- /** Path relative to project root (e.g. `.claude/commands/new-service.md`). */
35
- path: string;
36
- /** Full markdown body, including YAML frontmatter. */
37
- content: string;
38
- /** The slash name users type (e.g. `new-service` → `/new-service`). */
39
- slash: string;
40
- /** Why this command was generated — surfaces in the dry-run summary. */
41
- source: 'static' | 'template';
42
- }
43
- export interface IClaudeCommandsResult {
44
- files: readonly IClaudeCommandFile[];
45
- }
46
- export interface IClaudeCommandsOptions {
47
- /**
48
- * Cap on the number of per-template commands to emit. Default 20.
49
- * Templates are sorted by id; the first N are kept.
50
- */
51
- maxTemplateCommands?: number;
52
- }
53
- /**
54
- * Build the full set of `.claude/commands/*.md` files for a project.
55
- *
56
- * Pure — caller writes the bytes. Same shape as the `synthesize-*`
57
- * functions in this codebase: input inspection → output file list.
58
- */
59
- export declare function buildClaudeCommands(inspection: ISharkcraftInspection, options?: IClaudeCommandsOptions): IClaudeCommandsResult;
60
- //# sourceMappingURL=claude-commands-export.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"claude-commands-export.d.ts","sourceRoot":"","sources":["../../src/export/claude-commands-export.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACtC;AA0MD,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,qBAAqB,EACjC,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAsDvB"}