@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
@@ -0,0 +1,125 @@
1
+ const SOURCE_HINT = 'Edit knowledge entries via the files registered in `sharkcraft/sharkcraft.config.ts` (knowledgeFiles / ruleFiles / pathFiles). Locate the entry literal by its `id`.';
2
+ export function buildKnowledgeFixPlan(report) {
3
+ const fixes = [];
4
+ const skipped = [];
5
+ for (const entry of report.entries) {
6
+ for (const f of entry.deterministicFindings) {
7
+ const out = dispatchDeterministic(entry, f);
8
+ if (out.kind === 'fix')
9
+ fixes.push(out.fix);
10
+ else
11
+ skipped.push(out.skip);
12
+ }
13
+ for (const f of entry.llmFindings) {
14
+ fixes.push(makeLlmFix(entry, f));
15
+ }
16
+ }
17
+ const summary = {
18
+ fixCount: fixes.length,
19
+ highConfidence: fixes.filter((f) => f.confidence === 'high').length,
20
+ mediumConfidence: fixes.filter((f) => f.confidence === 'medium').length,
21
+ lowConfidence: fixes.filter((f) => f.confidence === 'low').length,
22
+ skipped: skipped.length,
23
+ };
24
+ const generatedAt = new Date().toISOString();
25
+ return {
26
+ fixPlanId: `fix-${generatedAt.replace(/[:.]/g, '-')}`,
27
+ generatedAt,
28
+ auditId: report.auditId,
29
+ sourceHint: SOURCE_HINT,
30
+ fixes,
31
+ skipped,
32
+ summary,
33
+ };
34
+ }
35
+ function dispatchDeterministic(entry, f) {
36
+ // Stale-reference family: high-confidence fixes — the deterministic engine
37
+ // already names the bad reference and (often) a replacement candidate.
38
+ if (f.category.startsWith('knowledge-stale.')) {
39
+ return makeFix(entry, f, f.severity === 'error' ? 'high' : 'medium', 'Repair a stale or missing reference in this entry.', [
40
+ `Locate knowledge entry "${entry.entryId}" (${SOURCE_HINT}).`,
41
+ `Deterministic finding: ${f.message}`,
42
+ f.fixSuggestion ? `Inspector-suggested fix: ${f.fixSuggestion}` : 'No automated fix candidate — verify the new symbol/file path manually.',
43
+ `If a replacement exists, update the reference in place. Otherwise remove the stale reference. Verify the entry still parses.`,
44
+ ].join('\n'));
45
+ }
46
+ switch (f.category) {
47
+ case 'knowledge.summary-missing':
48
+ return makeFix(entry, f, 'high', 'Add a one-sentence summary.', [
49
+ `Locate knowledge entry "${entry.entryId}" (${SOURCE_HINT}).`,
50
+ f.stubSuggestion
51
+ ? `Inspector-suggested stub: ${f.stubSuggestion}`
52
+ : `Add a \`summary\` field — one sentence that lets a reader grok the entry without opening it.`,
53
+ 'Verify the entry still parses.',
54
+ ].join('\n'));
55
+ case 'knowledge.tags-missing':
56
+ return makeFix(entry, f, 'high', 'Add tags so the entry surfaces in tag-based searches.', [
57
+ `Locate knowledge entry "${entry.entryId}" (${SOURCE_HINT}).`,
58
+ 'Add a `tags` array with 1–3 short kebab-case tags reflecting topic + scope.',
59
+ 'Verify the entry still parses.',
60
+ ].join('\n'));
61
+ case 'knowledge.title-missing':
62
+ return makeFix(entry, f, 'high', 'Add a `title` field.', [
63
+ `Locate knowledge entry "${entry.entryId}" (${SOURCE_HINT}).`,
64
+ 'Add a `title: "<short human-readable name>"` field — used in lists and reports.',
65
+ 'Verify the entry still parses.',
66
+ ].join('\n'));
67
+ case 'knowledge.summary-too-long':
68
+ return makeFix(entry, f, 'medium', 'Tighten the summary.', [
69
+ `Locate knowledge entry "${entry.entryId}" (${SOURCE_HINT}).`,
70
+ `Trim the \`summary\` to ≤ 320 chars. If you can't, move detail into \`body\` instead.`,
71
+ ].join('\n'));
72
+ default:
73
+ if (f.category.includes('obsolete-entry')) {
74
+ return {
75
+ kind: 'skip',
76
+ skip: {
77
+ entryId: entry.entryId,
78
+ findingCategory: f.category,
79
+ finding: f.message,
80
+ reason: 'obsolete-entry — human/agent must decide to retire or refresh; do not auto-remove.',
81
+ },
82
+ };
83
+ }
84
+ return makeFix(entry, f, 'low', `Address finding "${f.category}".`, [
85
+ `Locate knowledge entry "${entry.entryId}" (${SOURCE_HINT}).`,
86
+ `The audit reported: ${f.message}`,
87
+ f.fixSuggestion ?? f.stubSuggestion
88
+ ? `Inspector-suggested fix: ${f.fixSuggestion ?? f.stubSuggestion}`
89
+ : 'No specific suggestion was supplied — use judgment.',
90
+ `Apply a minimal change that resolves the finding without touching unrelated fields. Verify the entry still parses.`,
91
+ ].filter(Boolean).join('\n'));
92
+ }
93
+ }
94
+ function makeFix(entry, f, confidence, intent, agentPrompt) {
95
+ return {
96
+ kind: 'fix',
97
+ fix: {
98
+ entryId: entry.entryId,
99
+ findingCategory: f.category,
100
+ finding: f.message,
101
+ severity: f.severity,
102
+ intent,
103
+ agentPrompt,
104
+ confidence,
105
+ source: 'deterministic',
106
+ },
107
+ };
108
+ }
109
+ function makeLlmFix(entry, f) {
110
+ return {
111
+ entryId: entry.entryId,
112
+ findingCategory: f.category,
113
+ finding: f.message,
114
+ severity: f.severity,
115
+ intent: `Review the LLM-flagged "${f.category}" finding and decide whether to act.`,
116
+ agentPrompt: [
117
+ `Locate knowledge entry "${entry.entryId}" (${SOURCE_HINT}).`,
118
+ `An LLM critique flagged (confidence ${f.confidence.toFixed(2)}): ${f.message}`,
119
+ `LLM findings are advisory — verify against the entry body and sibling entries before acting.`,
120
+ `If you choose to act, keep the change minimal. If you don't, record the decision in your response.`,
121
+ ].join('\n'),
122
+ confidence: 'low',
123
+ source: 'llm',
124
+ };
125
+ }
@@ -0,0 +1,11 @@
1
+ import { type IAiProvider } from '@shrkcrft/ai';
2
+ import type { ISharkcraftInspection } from '@shrkcrft/inspector';
3
+ import type { IPipelineAuditReport } from './pipeline-audit.js';
4
+ export interface IEnrichPipelineAuditOptions {
5
+ provider: IAiProvider;
6
+ inspection: ISharkcraftInspection;
7
+ maxTokensPerPipeline?: number;
8
+ onPerPipelineError?: (pipelineId: string, error: Error) => void;
9
+ }
10
+ export declare function enrichPipelineAuditWithLlm(report: IPipelineAuditReport, options: IEnrichPipelineAuditOptions): Promise<IPipelineAuditReport>;
11
+ //# sourceMappingURL=pipeline-audit-llm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-audit-llm.d.ts","sourceRoot":"","sources":["../../src/audit/pipeline-audit-llm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAGV,oBAAoB,EAErB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,qBAAqB,CAAC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACjE;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,oBAAoB,CAAC,CAiC/B"}
@@ -0,0 +1,134 @@
1
+ import { AiMessageRole } from '@shrkcrft/ai';
2
+ export async function enrichPipelineAuditWithLlm(report, options) {
3
+ const enriched = [];
4
+ for (const entry of report.pipelines) {
5
+ const pipeline = options.inspection.pipelineRegistry.get(entry.pipelineId);
6
+ if (!pipeline) {
7
+ enriched.push(entry);
8
+ continue;
9
+ }
10
+ try {
11
+ const messages = buildEnrichmentMessages(pipeline, entry);
12
+ const res = await options.provider.send({
13
+ messages,
14
+ maxTokens: options.maxTokensPerPipeline ?? 1024,
15
+ });
16
+ if (!res.ok) {
17
+ options.onPerPipelineError?.(entry.pipelineId, res.error);
18
+ enriched.push(entry);
19
+ continue;
20
+ }
21
+ const parsed = parseLlmFindings(res.value.content);
22
+ enriched.push({ ...entry, llmFindings: parsed });
23
+ }
24
+ catch (e) {
25
+ options.onPerPipelineError?.(entry.pipelineId, e);
26
+ enriched.push(entry);
27
+ }
28
+ }
29
+ return {
30
+ ...report,
31
+ llmEnriched: true,
32
+ llmProviderId: options.provider.id,
33
+ pipelines: enriched,
34
+ };
35
+ }
36
+ function buildEnrichmentMessages(pipeline, entry) {
37
+ const system = {
38
+ role: AiMessageRole.System,
39
+ content: [
40
+ 'You are a critic auditing a SharkCraft pipeline definition for staleness, content quality, and step-ordering issues.',
41
+ '',
42
+ 'CRITICAL DISTINCTION:',
43
+ '- You are auditing the PIPELINE itself, not its target domain. A pipeline that orchestrates a release is fine even if the release process changes; only flag it if the pipeline now executes the wrong steps.',
44
+ '- A step referencing a tool you do not recognise is NOT necessarily wrong — flag it only if the deterministic layer has already marked the reference as unresolved or if the name is clearly a typo of a real tool.',
45
+ '',
46
+ 'STRICT silence bias: emit a finding only if a senior maintainer would change something on the strength of it. Better silence than ceremony.',
47
+ '',
48
+ 'Look for issues the deterministic layer (pipelines lint) CANNOT see:',
49
+ ' 1. **step-order-bug** — steps that depend on each other are in the wrong order.',
50
+ ' 2. **review-gap** — a writing step lacks proper review/handoff context.',
51
+ ' 3. **missing-precondition** — a step that assumes state a prior step does not establish.',
52
+ ' 4. **stale-step** — a step references a workflow or tool that has changed.',
53
+ ' 5. **dead-step** — a step that no longer does anything useful.',
54
+ ' 6. **other** — only if none of the above fit.',
55
+ '',
56
+ 'Return ONLY a JSON object, no preface, no fences:',
57
+ '{',
58
+ ' "findings": [',
59
+ ' { "severity": "info"|"warn"|"error", "category": "<one of the above>", "message": "<one sentence>", "confidence": 0.0 }',
60
+ ' ]',
61
+ '}',
62
+ 'If nothing new is worth flagging, return {"findings": []}.',
63
+ ].join('\n'),
64
+ };
65
+ const user = {
66
+ role: AiMessageRole.User,
67
+ content: [
68
+ `# Pipeline under audit`,
69
+ `id: ${pipeline.id}`,
70
+ ``,
71
+ `## Steps`,
72
+ JSON.stringify(pipeline.steps, null, 2).slice(0, 4096),
73
+ ``,
74
+ `## Deterministic findings already produced`,
75
+ entry.deterministicFindings.length === 0
76
+ ? '(none)'
77
+ : entry.deterministicFindings
78
+ .map((f) => `- [${f.severity}] ${f.category}${f.stepId ? ` (${f.stepId})` : ''}: ${f.message}`)
79
+ .join('\n'),
80
+ ].join('\n'),
81
+ };
82
+ return [system, user];
83
+ }
84
+ function parseLlmFindings(raw) {
85
+ const trimmed = raw.trim();
86
+ let jsonText = trimmed;
87
+ const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/);
88
+ if (fenced)
89
+ jsonText = fenced[1].trim();
90
+ let parsed;
91
+ try {
92
+ parsed = JSON.parse(jsonText);
93
+ }
94
+ catch {
95
+ const first = jsonText.indexOf('{');
96
+ const last = jsonText.lastIndexOf('}');
97
+ if (first < 0 || last <= first)
98
+ return [];
99
+ try {
100
+ parsed = JSON.parse(jsonText.slice(first, last + 1));
101
+ }
102
+ catch {
103
+ return [];
104
+ }
105
+ }
106
+ if (!parsed || typeof parsed !== 'object')
107
+ return [];
108
+ const list = parsed.findings;
109
+ if (!Array.isArray(list))
110
+ return [];
111
+ const out = [];
112
+ for (const item of list) {
113
+ if (!item || typeof item !== 'object')
114
+ continue;
115
+ const obj = item;
116
+ const severity = coerceSeverity(obj.severity);
117
+ const category = typeof obj.category === 'string' && obj.category.trim() ? obj.category.trim() : 'other';
118
+ const message = typeof obj.message === 'string' ? obj.message.trim() : '';
119
+ const confidence = typeof obj.confidence === 'number' && obj.confidence >= 0 && obj.confidence <= 1
120
+ ? obj.confidence
121
+ : 0.5;
122
+ if (!message)
123
+ continue;
124
+ out.push({ severity, category, message, confidence });
125
+ }
126
+ return out;
127
+ }
128
+ function coerceSeverity(value) {
129
+ if (value === 'error' || value === 'warn' || value === 'info')
130
+ return value;
131
+ if (value === 'warning')
132
+ return 'warn';
133
+ return 'info';
134
+ }
@@ -0,0 +1,69 @@
1
+ import { type ISharkcraftInspection } from '@shrkcrft/inspector';
2
+ import type { IAiBlock } from '@shrkcrft/ai';
3
+ export type PipelineAuditFindingSeverity = 'info' | 'warn' | 'error';
4
+ export interface IPipelineAuditFinding {
5
+ severity: PipelineAuditFindingSeverity;
6
+ category: string;
7
+ stepId?: string;
8
+ message: string;
9
+ sources: readonly string[];
10
+ }
11
+ export interface ILlmPipelineAuditFinding {
12
+ severity: PipelineAuditFindingSeverity;
13
+ category: string;
14
+ message: string;
15
+ confidence: number;
16
+ }
17
+ export type PipelineAuditVerdict = 'ok' | 'minor' | 'stale' | 'broken';
18
+ export interface IPipelineAuditEntry {
19
+ pipelineId: string;
20
+ verdict: PipelineAuditVerdict;
21
+ deterministicFindings: readonly IPipelineAuditFinding[];
22
+ llmFindings: readonly ILlmPipelineAuditFinding[];
23
+ }
24
+ export interface IPipelineAuditReport {
25
+ auditId: string;
26
+ generatedAt: string;
27
+ llmEnriched: boolean;
28
+ llmProviderId: string | null;
29
+ pipelines: readonly IPipelineAuditEntry[];
30
+ summary: {
31
+ ok: number;
32
+ minor: number;
33
+ stale: number;
34
+ broken: number;
35
+ total: number;
36
+ };
37
+ ai?: IAiBlock;
38
+ }
39
+ export interface IBuildPipelineAuditOptions {
40
+ pipelineId?: string;
41
+ }
42
+ export declare function buildPipelineAudit(inspection: ISharkcraftInspection, options?: IBuildPipelineAuditOptions): IPipelineAuditReport;
43
+ export interface IPipelineFixInstruction {
44
+ pipelineId: string;
45
+ stepId?: string;
46
+ findingCategory: string;
47
+ finding: string;
48
+ severity: PipelineAuditFindingSeverity;
49
+ intent: string;
50
+ agentPrompt: string;
51
+ confidence: 'high' | 'medium' | 'low';
52
+ source: 'deterministic' | 'llm';
53
+ llmSuggestion?: string;
54
+ }
55
+ export interface IPipelineFixPlan {
56
+ fixPlanId: string;
57
+ generatedAt: string;
58
+ auditId: string;
59
+ sourceHint: string;
60
+ fixes: readonly IPipelineFixInstruction[];
61
+ summary: {
62
+ fixCount: number;
63
+ highConfidence: number;
64
+ mediumConfidence: number;
65
+ lowConfidence: number;
66
+ };
67
+ }
68
+ export declare function buildPipelineFixPlan(report: IPipelineAuditReport): IPipelineFixPlan;
69
+ //# sourceMappingURL=pipeline-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-audit.d.ts","sourceRoot":"","sources":["../../src/audit/pipeline-audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,MAAM,4BAA4B,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAErE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvE,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,oBAAoB,CAAC;IAC9B,qBAAqB,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACxD,WAAW,EAAE,SAAS,wBAAwB,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC1C,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACrF,EAAE,CAAC,EAAE,QAAQ,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,qBAAqB,EACjC,OAAO,GAAE,0BAA+B,GACvC,oBAAoB,CA0CtB;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,4BAA4B,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,MAAM,EAAE,eAAe,GAAG,KAAK,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,uBAAuB,EAAE,CAAC;IAC1C,OAAO,EAAE;QACP,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAKD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,gBAAgB,CAyBnF"}
@@ -0,0 +1,166 @@
1
+ import { lintPipelines, } from '@shrkcrft/inspector';
2
+ export function buildPipelineAudit(inspection, options = {}) {
3
+ const targetIds = options.pipelineId ? [options.pipelineId] : undefined;
4
+ const lint = lintPipelines(inspection, targetIds);
5
+ const byPipeline = new Map();
6
+ for (const r of lint.results)
7
+ byPipeline.set(r.pipelineId, [...r.issues]);
8
+ const pipelines = [];
9
+ for (const [pipelineId, issues] of byPipeline.entries()) {
10
+ const det = issues.map((i) => ({
11
+ severity: normaliseSeverity(i.severity),
12
+ category: i.code,
13
+ ...(i.stepId ? { stepId: i.stepId } : {}),
14
+ message: i.message,
15
+ sources: ['pipelines lint'],
16
+ }));
17
+ pipelines.push({
18
+ pipelineId,
19
+ verdict: deriveVerdict(det),
20
+ deterministicFindings: det,
21
+ llmFindings: [],
22
+ });
23
+ }
24
+ const summary = pipelines.reduce((acc, p) => {
25
+ acc[p.verdict] += 1;
26
+ acc.total += 1;
27
+ return acc;
28
+ }, { ok: 0, minor: 0, stale: 0, broken: 0, total: 0 });
29
+ const generatedAt = new Date().toISOString();
30
+ return {
31
+ auditId: `audit-${generatedAt.replace(/[:.]/g, '-')}`,
32
+ generatedAt,
33
+ llmEnriched: false,
34
+ llmProviderId: null,
35
+ pipelines,
36
+ summary,
37
+ };
38
+ }
39
+ const SOURCE_HINT = 'Edit pipelines via the files registered in `sharkcraft/sharkcraft.config.ts` (pipelineFiles). Locate the pipeline literal by its `id`.';
40
+ export function buildPipelineFixPlan(report) {
41
+ const fixes = [];
42
+ for (const p of report.pipelines) {
43
+ for (const f of p.deterministicFindings) {
44
+ fixes.push(dispatchDeterministic(p.pipelineId, f));
45
+ }
46
+ for (const f of p.llmFindings) {
47
+ fixes.push(makeLlmFix(p.pipelineId, f));
48
+ }
49
+ }
50
+ const summary = {
51
+ fixCount: fixes.length,
52
+ highConfidence: fixes.filter((f) => f.confidence === 'high').length,
53
+ mediumConfidence: fixes.filter((f) => f.confidence === 'medium').length,
54
+ lowConfidence: fixes.filter((f) => f.confidence === 'low').length,
55
+ };
56
+ const generatedAt = new Date().toISOString();
57
+ return {
58
+ fixPlanId: `fix-${generatedAt.replace(/[:.]/g, '-')}`,
59
+ generatedAt,
60
+ auditId: report.auditId,
61
+ sourceHint: SOURCE_HINT,
62
+ fixes,
63
+ summary,
64
+ };
65
+ }
66
+ function normaliseSeverity(s) {
67
+ if (s === 'error')
68
+ return 'error';
69
+ if (s === 'warning')
70
+ return 'warn';
71
+ return 'info';
72
+ }
73
+ function deriveVerdict(findings) {
74
+ if (findings.some((f) => f.severity === 'error'))
75
+ return 'broken';
76
+ if (findings.some((f) => f.severity === 'warn'))
77
+ return 'stale';
78
+ if (findings.some((f) => f.severity === 'info'))
79
+ return 'minor';
80
+ return 'ok';
81
+ }
82
+ function dispatchDeterministic(pipelineId, f) {
83
+ const confidenceMap = {
84
+ 'missing-title': 'high',
85
+ 'missing-step-id': 'high',
86
+ 'missing-step-type': 'high',
87
+ 'write-without-review': 'medium',
88
+ 'review-points-missing': 'medium',
89
+ 'unresolved-reference': 'medium',
90
+ 'uncataloged-command': 'low',
91
+ };
92
+ const confidence = confidenceMap[f.category] ?? 'low';
93
+ const stepClause = f.stepId ? ` (step "${f.stepId}")` : '';
94
+ return {
95
+ pipelineId,
96
+ ...(f.stepId ? { stepId: f.stepId } : {}),
97
+ findingCategory: f.category,
98
+ finding: f.message,
99
+ severity: f.severity,
100
+ intent: intentFor(f.category, stepClause),
101
+ agentPrompt: [
102
+ `Locate pipeline "${pipelineId}" (${SOURCE_HINT}).`,
103
+ `Finding: ${f.message}`,
104
+ promptFor(f.category, stepClause, pipelineId),
105
+ 'Verify the file still parses.',
106
+ ].join('\n'),
107
+ confidence,
108
+ source: 'deterministic',
109
+ };
110
+ }
111
+ function intentFor(category, stepClause) {
112
+ switch (category) {
113
+ case 'missing-title':
114
+ return 'Add a title (and/or description) to the pipeline.';
115
+ case 'missing-step-id':
116
+ return `Add an \`id\` to the unnamed step${stepClause}.`;
117
+ case 'missing-step-type':
118
+ return `Add a \`type\` to the step${stepClause}.`;
119
+ case 'write-without-review':
120
+ return `Mark the writing step${stepClause} with \`humanReview: true\`.`;
121
+ case 'review-points-missing':
122
+ return 'Add at least one explicit `humanReview` checkpoint to this pipeline.';
123
+ case 'unresolved-reference':
124
+ return `Repair an unresolved \`references[]\` id${stepClause}.`;
125
+ case 'uncataloged-command':
126
+ return `Either align the cliCommand to a cataloged \`shrk\` verb${stepClause} or document the new command.`;
127
+ default:
128
+ return `Address finding "${category}"${stepClause}.`;
129
+ }
130
+ }
131
+ function promptFor(category, stepClause, pipelineId) {
132
+ switch (category) {
133
+ case 'missing-title':
134
+ return 'Add a `title: "<short name>"` field at the pipeline level. Optional `description` for one-paragraph context.';
135
+ case 'missing-step-id':
136
+ return `Each step must have a unique kebab-case \`id\` within pipeline "${pipelineId}". Pick a name that summarises the step's intent.`;
137
+ case 'missing-step-type':
138
+ return `The step${stepClause} must have a \`type\` (e.g. shell-command, generation-plan, apply-plan).`;
139
+ case 'write-without-review':
140
+ return `Writing steps must declare \`humanReview: true\` so the agent pauses for confirmation.`;
141
+ case 'review-points-missing':
142
+ return 'A pipeline that mutates files must include at least one human-review checkpoint.';
143
+ case 'unresolved-reference':
144
+ return 'The id in `references[]` does not match any template or rule. Either remove it or correct the spelling.';
145
+ case 'uncataloged-command':
146
+ return 'Either replace the command with a known `shrk` verb or extend the catalog if this is a legitimate new command.';
147
+ default:
148
+ return 'Apply a minimal change that resolves the finding without touching unrelated fields.';
149
+ }
150
+ }
151
+ function makeLlmFix(pipelineId, f) {
152
+ return {
153
+ pipelineId,
154
+ findingCategory: f.category,
155
+ finding: f.message,
156
+ severity: f.severity,
157
+ intent: `Review the LLM-flagged "${f.category}" finding and decide whether to act.`,
158
+ agentPrompt: [
159
+ `Locate pipeline "${pipelineId}" (${SOURCE_HINT}).`,
160
+ `An LLM critique flagged (confidence ${f.confidence.toFixed(2)}): ${f.message}`,
161
+ 'LLM findings are advisory — verify against the pipeline body and peers before acting.',
162
+ ].join('\n'),
163
+ confidence: 'low',
164
+ source: 'llm',
165
+ };
166
+ }
@@ -0,0 +1,19 @@
1
+ import { type IAiMessage, type IAiProvider } from '@shrkcrft/ai';
2
+ import type { ITemplateDefinition } from '@shrkcrft/templates';
3
+ import type { ISharkcraftInspection } from '@shrkcrft/inspector';
4
+ import type { ILlmAuditFinding, ITemplateAuditEntry, ITemplateAuditReport } from './templates-audit.js';
5
+ export interface IEnrichOptions {
6
+ provider: IAiProvider;
7
+ inspection: ISharkcraftInspection;
8
+ maxTokensPerTemplate?: number;
9
+ onPerTemplateError?: (templateId: string, error: Error) => void;
10
+ }
11
+ export declare function enrichAuditWithLlm(report: ITemplateAuditReport, options: IEnrichOptions): Promise<ITemplateAuditReport>;
12
+ declare function buildEnrichmentMessages(template: ITemplateDefinition, peers: readonly ITemplateDefinition[], entry: ITemplateAuditEntry): IAiMessage[];
13
+ declare function parseLlmFindings(raw: string): readonly ILlmAuditFinding[];
14
+ export declare const __internals: {
15
+ parseLlmFindings: typeof parseLlmFindings;
16
+ buildEnrichmentMessages: typeof buildEnrichmentMessages;
17
+ };
18
+ export {};
19
+ //# sourceMappingURL=templates-audit-llm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates-audit-llm.d.ts","sourceRoot":"","sources":["../../src/audit/templates-audit-llm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAEV,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,qBAAqB,CAAC;IAClC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACjE;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,oBAAoB,CAAC,CAwC/B;AAED,iBAAS,uBAAuB,CAC9B,QAAQ,EAAE,mBAAmB,EAC7B,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,KAAK,EAAE,mBAAmB,GACzB,UAAU,EAAE,CAsGd;AAuBD,iBAAS,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,gBAAgB,EAAE,CAoClE;AAQD,eAAO,MAAM,WAAW;;;CAAgD,CAAC"}