codeprobe 0.1.0

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 (355) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +406 -0
  3. package/dist/cli.d.ts +7 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +104 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/ab.d.ts +7 -0
  8. package/dist/commands/ab.d.ts.map +1 -0
  9. package/dist/commands/ab.js +230 -0
  10. package/dist/commands/ab.js.map +1 -0
  11. package/dist/commands/agents.d.ts +10 -0
  12. package/dist/commands/agents.d.ts.map +1 -0
  13. package/dist/commands/agents.js +326 -0
  14. package/dist/commands/agents.js.map +1 -0
  15. package/dist/commands/autotest.d.ts +10 -0
  16. package/dist/commands/autotest.d.ts.map +1 -0
  17. package/dist/commands/autotest.js +408 -0
  18. package/dist/commands/autotest.js.map +1 -0
  19. package/dist/commands/benchmark.d.ts +6 -0
  20. package/dist/commands/benchmark.d.ts.map +1 -0
  21. package/dist/commands/benchmark.js +215 -0
  22. package/dist/commands/benchmark.js.map +1 -0
  23. package/dist/commands/check.d.ts +10 -0
  24. package/dist/commands/check.d.ts.map +1 -0
  25. package/dist/commands/check.js +333 -0
  26. package/dist/commands/check.js.map +1 -0
  27. package/dist/commands/context.d.ts +16 -0
  28. package/dist/commands/context.d.ts.map +1 -0
  29. package/dist/commands/context.js +219 -0
  30. package/dist/commands/context.js.map +1 -0
  31. package/dist/commands/cost.d.ts +9 -0
  32. package/dist/commands/cost.d.ts.map +1 -0
  33. package/dist/commands/cost.js +142 -0
  34. package/dist/commands/cost.js.map +1 -0
  35. package/dist/commands/dashboard.d.ts +10 -0
  36. package/dist/commands/dashboard.d.ts.map +1 -0
  37. package/dist/commands/dashboard.js +462 -0
  38. package/dist/commands/dashboard.js.map +1 -0
  39. package/dist/commands/diff.d.ts +6 -0
  40. package/dist/commands/diff.d.ts.map +1 -0
  41. package/dist/commands/diff.js +118 -0
  42. package/dist/commands/diff.js.map +1 -0
  43. package/dist/commands/doctor.d.ts +12 -0
  44. package/dist/commands/doctor.d.ts.map +1 -0
  45. package/dist/commands/doctor.js +203 -0
  46. package/dist/commands/doctor.js.map +1 -0
  47. package/dist/commands/explain.d.ts +7 -0
  48. package/dist/commands/explain.d.ts.map +1 -0
  49. package/dist/commands/explain.js +164 -0
  50. package/dist/commands/explain.js.map +1 -0
  51. package/dist/commands/flaky.d.ts +10 -0
  52. package/dist/commands/flaky.d.ts.map +1 -0
  53. package/dist/commands/flaky.js +141 -0
  54. package/dist/commands/flaky.js.map +1 -0
  55. package/dist/commands/generateClaudeMd.d.ts +11 -0
  56. package/dist/commands/generateClaudeMd.d.ts.map +1 -0
  57. package/dist/commands/generateClaudeMd.js +278 -0
  58. package/dist/commands/generateClaudeMd.js.map +1 -0
  59. package/dist/commands/generateRules.d.ts +11 -0
  60. package/dist/commands/generateRules.d.ts.map +1 -0
  61. package/dist/commands/generateRules.js +413 -0
  62. package/dist/commands/generateRules.js.map +1 -0
  63. package/dist/commands/heatmap.d.ts +7 -0
  64. package/dist/commands/heatmap.d.ts.map +1 -0
  65. package/dist/commands/heatmap.js +117 -0
  66. package/dist/commands/heatmap.js.map +1 -0
  67. package/dist/commands/history.d.ts +13 -0
  68. package/dist/commands/history.d.ts.map +1 -0
  69. package/dist/commands/history.js +113 -0
  70. package/dist/commands/history.js.map +1 -0
  71. package/dist/commands/hooks.d.ts +9 -0
  72. package/dist/commands/hooks.d.ts.map +1 -0
  73. package/dist/commands/hooks.js +199 -0
  74. package/dist/commands/hooks.js.map +1 -0
  75. package/dist/commands/improve.d.ts +7 -0
  76. package/dist/commands/improve.d.ts.map +1 -0
  77. package/dist/commands/improve.js +192 -0
  78. package/dist/commands/improve.js.map +1 -0
  79. package/dist/commands/init.d.ts +9 -0
  80. package/dist/commands/init.d.ts.map +1 -0
  81. package/dist/commands/init.js +270 -0
  82. package/dist/commands/init.js.map +1 -0
  83. package/dist/commands/installHook.d.ts +9 -0
  84. package/dist/commands/installHook.d.ts.map +1 -0
  85. package/dist/commands/installHook.js +78 -0
  86. package/dist/commands/installHook.js.map +1 -0
  87. package/dist/commands/lint.d.ts +6 -0
  88. package/dist/commands/lint.d.ts.map +1 -0
  89. package/dist/commands/lint.js +237 -0
  90. package/dist/commands/lint.js.map +1 -0
  91. package/dist/commands/map.d.ts +9 -0
  92. package/dist/commands/map.d.ts.map +1 -0
  93. package/dist/commands/map.js +114 -0
  94. package/dist/commands/map.js.map +1 -0
  95. package/dist/commands/mcp.d.ts +6 -0
  96. package/dist/commands/mcp.d.ts.map +1 -0
  97. package/dist/commands/mcp.js +151 -0
  98. package/dist/commands/mcp.js.map +1 -0
  99. package/dist/commands/models.d.ts +9 -0
  100. package/dist/commands/models.d.ts.map +1 -0
  101. package/dist/commands/models.js +89 -0
  102. package/dist/commands/models.js.map +1 -0
  103. package/dist/commands/pack.d.ts +10 -0
  104. package/dist/commands/pack.d.ts.map +1 -0
  105. package/dist/commands/pack.js +248 -0
  106. package/dist/commands/pack.js.map +1 -0
  107. package/dist/commands/recommend.d.ts +10 -0
  108. package/dist/commands/recommend.d.ts.map +1 -0
  109. package/dist/commands/recommend.js +472 -0
  110. package/dist/commands/recommend.js.map +1 -0
  111. package/dist/commands/regression.d.ts +10 -0
  112. package/dist/commands/regression.d.ts.map +1 -0
  113. package/dist/commands/regression.js +212 -0
  114. package/dist/commands/regression.js.map +1 -0
  115. package/dist/commands/repl.d.ts +9 -0
  116. package/dist/commands/repl.d.ts.map +1 -0
  117. package/dist/commands/repl.js +245 -0
  118. package/dist/commands/repl.js.map +1 -0
  119. package/dist/commands/scan.d.ts +10 -0
  120. package/dist/commands/scan.d.ts.map +1 -0
  121. package/dist/commands/scan.js +352 -0
  122. package/dist/commands/scan.js.map +1 -0
  123. package/dist/commands/score.d.ts +10 -0
  124. package/dist/commands/score.d.ts.map +1 -0
  125. package/dist/commands/score.js +192 -0
  126. package/dist/commands/score.js.map +1 -0
  127. package/dist/commands/security.d.ts +10 -0
  128. package/dist/commands/security.d.ts.map +1 -0
  129. package/dist/commands/security.js +211 -0
  130. package/dist/commands/security.js.map +1 -0
  131. package/dist/commands/simulate.d.ts +7 -0
  132. package/dist/commands/simulate.d.ts.map +1 -0
  133. package/dist/commands/simulate.js +149 -0
  134. package/dist/commands/simulate.js.map +1 -0
  135. package/dist/commands/summary.d.ts +9 -0
  136. package/dist/commands/summary.d.ts.map +1 -0
  137. package/dist/commands/summary.js +271 -0
  138. package/dist/commands/summary.js.map +1 -0
  139. package/dist/commands/test.d.ts +9 -0
  140. package/dist/commands/test.d.ts.map +1 -0
  141. package/dist/commands/test.js +219 -0
  142. package/dist/commands/test.js.map +1 -0
  143. package/dist/commands/ui.d.ts +8 -0
  144. package/dist/commands/ui.d.ts.map +1 -0
  145. package/dist/commands/ui.js +222 -0
  146. package/dist/commands/ui.js.map +1 -0
  147. package/dist/commands/validate.d.ts +7 -0
  148. package/dist/commands/validate.d.ts.map +1 -0
  149. package/dist/commands/validate.js +254 -0
  150. package/dist/commands/validate.js.map +1 -0
  151. package/dist/commands/workflow.d.ts +39 -0
  152. package/dist/commands/workflow.d.ts.map +1 -0
  153. package/dist/commands/workflow.js +309 -0
  154. package/dist/commands/workflow.js.map +1 -0
  155. package/dist/core/__tests__/contextAnalyzer.test.d.ts +2 -0
  156. package/dist/core/__tests__/contextAnalyzer.test.d.ts.map +1 -0
  157. package/dist/core/__tests__/contextAnalyzer.test.js +48 -0
  158. package/dist/core/__tests__/contextAnalyzer.test.js.map +1 -0
  159. package/dist/core/__tests__/promptLinter.test.d.ts +2 -0
  160. package/dist/core/__tests__/promptLinter.test.d.ts.map +1 -0
  161. package/dist/core/__tests__/promptLinter.test.js +74 -0
  162. package/dist/core/__tests__/promptLinter.test.js.map +1 -0
  163. package/dist/core/__tests__/promptRunner.test.d.ts +2 -0
  164. package/dist/core/__tests__/promptRunner.test.d.ts.map +1 -0
  165. package/dist/core/__tests__/promptRunner.test.js +84 -0
  166. package/dist/core/__tests__/promptRunner.test.js.map +1 -0
  167. package/dist/core/__tests__/securityScanner.test.d.ts +2 -0
  168. package/dist/core/__tests__/securityScanner.test.d.ts.map +1 -0
  169. package/dist/core/__tests__/securityScanner.test.js +39 -0
  170. package/dist/core/__tests__/securityScanner.test.js.map +1 -0
  171. package/dist/core/agentTracer.d.ts +21 -0
  172. package/dist/core/agentTracer.d.ts.map +1 -0
  173. package/dist/core/agentTracer.js +355 -0
  174. package/dist/core/agentTracer.js.map +1 -0
  175. package/dist/core/anthropicClient.d.ts +26 -0
  176. package/dist/core/anthropicClient.d.ts.map +1 -0
  177. package/dist/core/anthropicClient.js +62 -0
  178. package/dist/core/anthropicClient.js.map +1 -0
  179. package/dist/core/benchmarkRunner.d.ts +25 -0
  180. package/dist/core/benchmarkRunner.d.ts.map +1 -0
  181. package/dist/core/benchmarkRunner.js +182 -0
  182. package/dist/core/benchmarkRunner.js.map +1 -0
  183. package/dist/core/contextAnalyzer.d.ts +19 -0
  184. package/dist/core/contextAnalyzer.d.ts.map +1 -0
  185. package/dist/core/contextAnalyzer.js +221 -0
  186. package/dist/core/contextAnalyzer.js.map +1 -0
  187. package/dist/core/contextPacker.d.ts +26 -0
  188. package/dist/core/contextPacker.d.ts.map +1 -0
  189. package/dist/core/contextPacker.js +358 -0
  190. package/dist/core/contextPacker.js.map +1 -0
  191. package/dist/core/datasetRunner.d.ts +10 -0
  192. package/dist/core/datasetRunner.d.ts.map +1 -0
  193. package/dist/core/datasetRunner.js +130 -0
  194. package/dist/core/datasetRunner.js.map +1 -0
  195. package/dist/core/doctorRunner.d.ts +24 -0
  196. package/dist/core/doctorRunner.d.ts.map +1 -0
  197. package/dist/core/doctorRunner.js +278 -0
  198. package/dist/core/doctorRunner.js.map +1 -0
  199. package/dist/core/hookScanner.d.ts +24 -0
  200. package/dist/core/hookScanner.d.ts.map +1 -0
  201. package/dist/core/hookScanner.js +226 -0
  202. package/dist/core/hookScanner.js.map +1 -0
  203. package/dist/core/mcpScanner.d.ts +22 -0
  204. package/dist/core/mcpScanner.d.ts.map +1 -0
  205. package/dist/core/mcpScanner.js +290 -0
  206. package/dist/core/mcpScanner.js.map +1 -0
  207. package/dist/core/modelRegistry.d.ts +35 -0
  208. package/dist/core/modelRegistry.d.ts.map +1 -0
  209. package/dist/core/modelRegistry.js +97 -0
  210. package/dist/core/modelRegistry.js.map +1 -0
  211. package/dist/core/promptDiff.d.ts +25 -0
  212. package/dist/core/promptDiff.d.ts.map +1 -0
  213. package/dist/core/promptDiff.js +130 -0
  214. package/dist/core/promptDiff.js.map +1 -0
  215. package/dist/core/promptExplainer.d.ts +17 -0
  216. package/dist/core/promptExplainer.d.ts.map +1 -0
  217. package/dist/core/promptExplainer.js +334 -0
  218. package/dist/core/promptExplainer.js.map +1 -0
  219. package/dist/core/promptImprover.d.ts +19 -0
  220. package/dist/core/promptImprover.d.ts.map +1 -0
  221. package/dist/core/promptImprover.js +260 -0
  222. package/dist/core/promptImprover.js.map +1 -0
  223. package/dist/core/promptLinter.d.ts +24 -0
  224. package/dist/core/promptLinter.d.ts.map +1 -0
  225. package/dist/core/promptLinter.js +319 -0
  226. package/dist/core/promptLinter.js.map +1 -0
  227. package/dist/core/promptRunner.d.ts +31 -0
  228. package/dist/core/promptRunner.d.ts.map +1 -0
  229. package/dist/core/promptRunner.js +427 -0
  230. package/dist/core/promptRunner.js.map +1 -0
  231. package/dist/core/providers/anthropic.d.ts +10 -0
  232. package/dist/core/providers/anthropic.d.ts.map +1 -0
  233. package/dist/core/providers/anthropic.js +26 -0
  234. package/dist/core/providers/anthropic.js.map +1 -0
  235. package/dist/core/providers/base.d.ts +22 -0
  236. package/dist/core/providers/base.d.ts.map +1 -0
  237. package/dist/core/providers/base.js +2 -0
  238. package/dist/core/providers/base.js.map +1 -0
  239. package/dist/core/providers/factory.d.ts +7 -0
  240. package/dist/core/providers/factory.d.ts.map +1 -0
  241. package/dist/core/providers/factory.js +42 -0
  242. package/dist/core/providers/factory.js.map +1 -0
  243. package/dist/core/providers/google.d.ts +10 -0
  244. package/dist/core/providers/google.d.ts.map +1 -0
  245. package/dist/core/providers/google.js +47 -0
  246. package/dist/core/providers/google.js.map +1 -0
  247. package/dist/core/providers/openai.d.ts +19 -0
  248. package/dist/core/providers/openai.d.ts.map +1 -0
  249. package/dist/core/providers/openai.js +54 -0
  250. package/dist/core/providers/openai.js.map +1 -0
  251. package/dist/core/regressionRunner.d.ts +11 -0
  252. package/dist/core/regressionRunner.d.ts.map +1 -0
  253. package/dist/core/regressionRunner.js +116 -0
  254. package/dist/core/regressionRunner.js.map +1 -0
  255. package/dist/core/repositorySimulator.d.ts +17 -0
  256. package/dist/core/repositorySimulator.d.ts.map +1 -0
  257. package/dist/core/repositorySimulator.js +104 -0
  258. package/dist/core/repositorySimulator.js.map +1 -0
  259. package/dist/core/scorer.d.ts +30 -0
  260. package/dist/core/scorer.d.ts.map +1 -0
  261. package/dist/core/scorer.js +317 -0
  262. package/dist/core/scorer.js.map +1 -0
  263. package/dist/core/securityScanner.d.ts +23 -0
  264. package/dist/core/securityScanner.d.ts.map +1 -0
  265. package/dist/core/securityScanner.js +216 -0
  266. package/dist/core/securityScanner.js.map +1 -0
  267. package/dist/core/skillValidator.d.ts +41 -0
  268. package/dist/core/skillValidator.d.ts.map +1 -0
  269. package/dist/core/skillValidator.js +235 -0
  270. package/dist/core/skillValidator.js.map +1 -0
  271. package/dist/core/testHistory.d.ts +44 -0
  272. package/dist/core/testHistory.d.ts.map +1 -0
  273. package/dist/core/testHistory.js +91 -0
  274. package/dist/core/testHistory.js.map +1 -0
  275. package/dist/tokenizers/claudeTokenizer.d.ts +26 -0
  276. package/dist/tokenizers/claudeTokenizer.d.ts.map +1 -0
  277. package/dist/tokenizers/claudeTokenizer.js +83 -0
  278. package/dist/tokenizers/claudeTokenizer.js.map +1 -0
  279. package/dist/types/agent.d.ts +26 -0
  280. package/dist/types/agent.d.ts.map +1 -0
  281. package/dist/types/agent.js +5 -0
  282. package/dist/types/agent.js.map +1 -0
  283. package/dist/types/config.d.ts +30 -0
  284. package/dist/types/config.d.ts.map +1 -0
  285. package/dist/types/config.js +5 -0
  286. package/dist/types/config.js.map +1 -0
  287. package/dist/types/context.d.ts +77 -0
  288. package/dist/types/context.d.ts.map +1 -0
  289. package/dist/types/context.js +5 -0
  290. package/dist/types/context.js.map +1 -0
  291. package/dist/types/dataset.d.ts +26 -0
  292. package/dist/types/dataset.d.ts.map +1 -0
  293. package/dist/types/dataset.js +5 -0
  294. package/dist/types/dataset.js.map +1 -0
  295. package/dist/types/diagnostics.d.ts +31 -0
  296. package/dist/types/diagnostics.d.ts.map +1 -0
  297. package/dist/types/diagnostics.js +5 -0
  298. package/dist/types/diagnostics.js.map +1 -0
  299. package/dist/types/prompt.d.ts +53 -0
  300. package/dist/types/prompt.d.ts.map +1 -0
  301. package/dist/types/prompt.js +5 -0
  302. package/dist/types/prompt.js.map +1 -0
  303. package/dist/types/results.d.ts +42 -0
  304. package/dist/types/results.d.ts.map +1 -0
  305. package/dist/types/results.js +5 -0
  306. package/dist/types/results.js.map +1 -0
  307. package/dist/ui/dashboard.d.ts +57 -0
  308. package/dist/ui/dashboard.d.ts.map +1 -0
  309. package/dist/ui/dashboard.js +644 -0
  310. package/dist/ui/dashboard.js.map +1 -0
  311. package/dist/utils/__tests__/hashing.test.d.ts +2 -0
  312. package/dist/utils/__tests__/hashing.test.d.ts.map +1 -0
  313. package/dist/utils/__tests__/hashing.test.js +28 -0
  314. package/dist/utils/__tests__/hashing.test.js.map +1 -0
  315. package/dist/utils/__tests__/output.test.d.ts +2 -0
  316. package/dist/utils/__tests__/output.test.d.ts.map +1 -0
  317. package/dist/utils/__tests__/output.test.js +62 -0
  318. package/dist/utils/__tests__/output.test.js.map +1 -0
  319. package/dist/utils/cache.d.ts +29 -0
  320. package/dist/utils/cache.d.ts.map +1 -0
  321. package/dist/utils/cache.js +87 -0
  322. package/dist/utils/cache.js.map +1 -0
  323. package/dist/utils/config.d.ts +15 -0
  324. package/dist/utils/config.d.ts.map +1 -0
  325. package/dist/utils/config.js +61 -0
  326. package/dist/utils/config.js.map +1 -0
  327. package/dist/utils/errors.d.ts +43 -0
  328. package/dist/utils/errors.d.ts.map +1 -0
  329. package/dist/utils/errors.js +83 -0
  330. package/dist/utils/errors.js.map +1 -0
  331. package/dist/utils/fs.d.ts +44 -0
  332. package/dist/utils/fs.d.ts.map +1 -0
  333. package/dist/utils/fs.js +119 -0
  334. package/dist/utils/fs.js.map +1 -0
  335. package/dist/utils/hashing.d.ts +13 -0
  336. package/dist/utils/hashing.d.ts.map +1 -0
  337. package/dist/utils/hashing.js +18 -0
  338. package/dist/utils/hashing.js.map +1 -0
  339. package/dist/utils/logger.d.ts +32 -0
  340. package/dist/utils/logger.d.ts.map +1 -0
  341. package/dist/utils/logger.js +76 -0
  342. package/dist/utils/logger.js.map +1 -0
  343. package/dist/utils/output.d.ts +34 -0
  344. package/dist/utils/output.d.ts.map +1 -0
  345. package/dist/utils/output.js +99 -0
  346. package/dist/utils/output.js.map +1 -0
  347. package/dist/utils/paths.d.ts +33 -0
  348. package/dist/utils/paths.d.ts.map +1 -0
  349. package/dist/utils/paths.js +51 -0
  350. package/dist/utils/paths.js.map +1 -0
  351. package/dist/utils/spinner.d.ts +23 -0
  352. package/dist/utils/spinner.d.ts.map +1 -0
  353. package/dist/utils/spinner.js +79 -0
  354. package/dist/utils/spinner.js.map +1 -0
  355. package/package.json +60 -0
@@ -0,0 +1,472 @@
1
+ /**
2
+ * `codeprobe recommend [path]` — Analyze an entire project and give
3
+ * actionable recommendations for improving prompt engineering practices.
4
+ *
5
+ * Checks for missing specs, untested prompts, missing configs, context
6
+ * window overflows, security issues, and more.
7
+ */
8
+ import { resolve, join } from 'node:path';
9
+ import { access } from 'node:fs/promises';
10
+ import { resolvePath } from '../utils/paths.js';
11
+ import { fileExists, isDirectory, walkDirectory, readTextFile } from '../utils/fs.js';
12
+ import { estimateTokens } from '../tokenizers/claudeTokenizer.js';
13
+ import { setLogLevel } from '../utils/logger.js';
14
+ // ---------------------------------------------------------------------------
15
+ // Context window sizes for known models
16
+ // ---------------------------------------------------------------------------
17
+ const MODEL_CONTEXT_WINDOWS = {
18
+ 'gpt-4o': 128_000,
19
+ 'gpt-4-turbo': 128_000,
20
+ 'gpt-4': 8_192,
21
+ 'gpt-3.5-turbo': 16_385,
22
+ 'claude-sonnet-4-6': 200_000,
23
+ 'claude-opus-4-6': 200_000,
24
+ 'claude-3-5-sonnet': 200_000,
25
+ 'claude-3-opus': 200_000,
26
+ 'claude-3-haiku': 200_000,
27
+ };
28
+ const DEFAULT_IGNORE_DIRS = new Set([
29
+ 'node_modules', '.git', 'dist', 'build', 'coverage',
30
+ '.next', '.nuxt', '__pycache__', '.venv', 'vendor',
31
+ '.cache', '.turbo',
32
+ ]);
33
+ // ---------------------------------------------------------------------------
34
+ // Individual checks
35
+ // ---------------------------------------------------------------------------
36
+ async function findPromptSpecs(rootPath) {
37
+ const { glob } = await import('glob');
38
+ return glob(resolve(rootPath, '**/*.prompt.{yaml,yml}'), {
39
+ absolute: true,
40
+ ignore: ['**/node_modules/**', '**/.git/**', '**/dist/**'],
41
+ });
42
+ }
43
+ /**
44
+ * Check 1: No prompt specs found.
45
+ */
46
+ async function checkNoSpecs(rootPath) {
47
+ const specs = await findPromptSpecs(rootPath);
48
+ if (specs.length === 0) {
49
+ return {
50
+ priority: 'critical',
51
+ category: 'Setup',
52
+ title: 'No prompt specs found',
53
+ description: 'Create prompt specs to test your AI prompts',
54
+ command: 'codeprobe init',
55
+ };
56
+ }
57
+ return null;
58
+ }
59
+ /**
60
+ * Check 2: Prompt specs with no tests.
61
+ */
62
+ async function checkSpecsWithoutTests(rootPath) {
63
+ const yaml = (await import('js-yaml')).default;
64
+ const specs = await findPromptSpecs(rootPath);
65
+ const untested = [];
66
+ for (const specFile of specs) {
67
+ const content = await readTextFile(specFile);
68
+ if (!content)
69
+ continue;
70
+ try {
71
+ const parsed = yaml.load(content);
72
+ if (!parsed['tests'] || !Array.isArray(parsed['tests']) || parsed['tests'].length === 0) {
73
+ const fileName = specFile.split('/').pop() ?? specFile;
74
+ untested.push(fileName);
75
+ }
76
+ }
77
+ catch {
78
+ // Skip unparseable files
79
+ }
80
+ }
81
+ if (untested.length > 0) {
82
+ const first = untested[0];
83
+ return {
84
+ priority: 'high',
85
+ category: 'Testing',
86
+ title: `${untested.length} prompt spec${untested.length > 1 ? 's have' : ' has'} no tests`,
87
+ description: 'Untested prompts may have regressions',
88
+ command: `codeprobe autotest prompts/${first}`,
89
+ };
90
+ }
91
+ return null;
92
+ }
93
+ /**
94
+ * Check 3: No CLAUDE.md or .cursorrules.
95
+ */
96
+ async function checkAiConfig(rootPath) {
97
+ const claudeMdPath = join(rootPath, 'CLAUDE.md');
98
+ const cursorRulesPath = join(rootPath, '.cursorrules');
99
+ const windsurfPath = join(rootPath, '.windsurfrules');
100
+ const copilotPath = join(rootPath, '.github', 'copilot-instructions.md');
101
+ const hasClaudeMd = await fileExists(claudeMdPath);
102
+ const hasCursorRules = await fileExists(cursorRulesPath);
103
+ const hasWindsurf = await fileExists(windsurfPath);
104
+ const hasCopilot = await fileExists(copilotPath);
105
+ if (!hasClaudeMd && !hasCursorRules && !hasWindsurf && !hasCopilot) {
106
+ return {
107
+ priority: 'high',
108
+ category: 'Configuration',
109
+ title: 'No AI tool configuration found',
110
+ description: 'No CLAUDE.md, .cursorrules, .windsurfrules, or copilot-instructions.md found',
111
+ command: 'codeprobe generate-claudemd',
112
+ };
113
+ }
114
+ if (!hasClaudeMd) {
115
+ return {
116
+ priority: 'medium',
117
+ category: 'Configuration',
118
+ title: 'No CLAUDE.md found',
119
+ description: 'Add a CLAUDE.md for better Claude Code context',
120
+ command: 'codeprobe generate-claudemd',
121
+ };
122
+ }
123
+ return null;
124
+ }
125
+ /**
126
+ * Check 4: Repo exceeds common context windows.
127
+ */
128
+ async function checkContextWindow(rootPath) {
129
+ const entries = await walkDirectory(rootPath, { ignoreDirs: DEFAULT_IGNORE_DIRS });
130
+ const files = entries.filter((e) => e.isFile && e.size < 1_000_000);
131
+ let totalTokens = 0;
132
+ // Sample up to 200 files to avoid excessive I/O
133
+ const sample = files.slice(0, 200);
134
+ for (const file of sample) {
135
+ const content = await readTextFile(file.path);
136
+ if (!content)
137
+ continue;
138
+ totalTokens += estimateTokens(content);
139
+ }
140
+ // Extrapolate if we sampled
141
+ if (files.length > sample.length) {
142
+ totalTokens = Math.round(totalTokens * (files.length / sample.length));
143
+ }
144
+ // Check against GPT-4o (most common limit to exceed)
145
+ const gpt4oLimit = MODEL_CONTEXT_WINDOWS['gpt-4o'];
146
+ if (totalTokens > gpt4oLimit) {
147
+ const tokenStr = totalTokens > 1_000_000
148
+ ? `${(totalTokens / 1_000_000).toFixed(1)}M`
149
+ : `${Math.round(totalTokens / 1000)}k`;
150
+ return {
151
+ priority: 'high',
152
+ category: 'Context',
153
+ title: 'Repository exceeds GPT-4o context window',
154
+ description: `~${tokenStr} tokens estimated, exceeds 128k window`,
155
+ command: 'codeprobe pack . --model gpt-4o',
156
+ };
157
+ }
158
+ return null;
159
+ }
160
+ /**
161
+ * Check 5: Large files dominating tokens.
162
+ */
163
+ async function checkLargeFiles(rootPath) {
164
+ const entries = await walkDirectory(rootPath, { ignoreDirs: DEFAULT_IGNORE_DIRS });
165
+ const files = entries.filter((e) => e.isFile && e.size > 50_000 && e.size < 1_000_000);
166
+ if (files.length >= 3) {
167
+ return {
168
+ priority: 'medium',
169
+ category: 'Context',
170
+ title: `${files.length} large files may dominate token budget`,
171
+ description: 'Review the top files by token count to optimize context',
172
+ command: 'codeprobe heatmap --top 5',
173
+ };
174
+ }
175
+ return null;
176
+ }
177
+ /**
178
+ * Check 6: No .gitignore.
179
+ */
180
+ async function checkGitignore(rootPath) {
181
+ const gitignorePath = join(rootPath, '.gitignore');
182
+ if (!(await fileExists(gitignorePath))) {
183
+ return {
184
+ priority: 'medium',
185
+ category: 'Configuration',
186
+ title: 'No .gitignore found',
187
+ description: 'Add a .gitignore to exclude irrelevant files from context',
188
+ command: 'echo "node_modules/\\ndist/\\ncoverage/" > .gitignore',
189
+ };
190
+ }
191
+ return null;
192
+ }
193
+ /**
194
+ * Check 7: Lock files present (informational).
195
+ */
196
+ async function checkLockFiles(rootPath) {
197
+ const lockFiles = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lockb'];
198
+ const found = [];
199
+ for (const lock of lockFiles) {
200
+ if (await fileExists(join(rootPath, lock))) {
201
+ found.push(lock);
202
+ }
203
+ }
204
+ if (found.length > 0) {
205
+ return {
206
+ priority: 'low',
207
+ category: 'Context',
208
+ title: 'Lock files present in repository',
209
+ description: 'Lock files are excluded from pack by default, but verify they are not polluting context',
210
+ command: 'codeprobe context .',
211
+ };
212
+ }
213
+ return null;
214
+ }
215
+ /**
216
+ * Check 8: No test history.
217
+ */
218
+ async function checkTestHistory(rootPath) {
219
+ const historyPath = join(rootPath, '.codeprobe', 'history');
220
+ let hasHistory = false;
221
+ try {
222
+ await access(historyPath);
223
+ hasHistory = true;
224
+ }
225
+ catch {
226
+ // No history directory
227
+ }
228
+ if (!hasHistory) {
229
+ return {
230
+ priority: 'low',
231
+ category: 'Testing',
232
+ title: 'No test history',
233
+ description: 'Start tracking test results over time',
234
+ command: 'codeprobe test',
235
+ };
236
+ }
237
+ return null;
238
+ }
239
+ /**
240
+ * Check 9: Security issues in prompt specs.
241
+ */
242
+ async function checkSecurityIssues(rootPath) {
243
+ const specs = await findPromptSpecs(rootPath);
244
+ if (specs.length === 0)
245
+ return null;
246
+ const injectionPattern = /ignore\s+(previous|above|all)\s+(instructions?|prompts?|rules?)/i;
247
+ const secretPattern = /(?:api[_-]?key|apikey|secret|password|token)\s*[:=]\s*['"][^'"]{8,}/i;
248
+ let issueCount = 0;
249
+ for (const specFile of specs) {
250
+ const content = await readTextFile(specFile);
251
+ if (!content)
252
+ continue;
253
+ if (injectionPattern.test(content) || secretPattern.test(content)) {
254
+ issueCount++;
255
+ }
256
+ }
257
+ if (issueCount > 0) {
258
+ return {
259
+ priority: 'critical',
260
+ category: 'Security',
261
+ title: `Security issues found in ${issueCount} spec${issueCount > 1 ? 's' : ''}`,
262
+ description: 'Potential injection patterns or leaked secrets detected',
263
+ command: 'codeprobe security',
264
+ };
265
+ }
266
+ return null;
267
+ }
268
+ /**
269
+ * Check 10: Lint warnings in prompt specs.
270
+ */
271
+ async function checkLintWarnings(rootPath) {
272
+ const yaml = (await import('js-yaml')).default;
273
+ const specs = await findPromptSpecs(rootPath);
274
+ let warnings = 0;
275
+ for (const specFile of specs) {
276
+ const content = await readTextFile(specFile);
277
+ if (!content)
278
+ continue;
279
+ try {
280
+ const parsed = yaml.load(content);
281
+ if (!parsed['name'])
282
+ warnings++;
283
+ if (!parsed['prompt'])
284
+ warnings++;
285
+ if (!parsed['description'])
286
+ warnings++;
287
+ }
288
+ catch {
289
+ warnings++;
290
+ }
291
+ }
292
+ if (warnings > 0) {
293
+ return {
294
+ priority: 'medium',
295
+ category: 'Quality',
296
+ title: `${warnings} lint warning${warnings > 1 ? 's' : ''} in prompt specs`,
297
+ description: 'Fix lint issues to improve spec quality',
298
+ command: 'codeprobe lint',
299
+ };
300
+ }
301
+ return null;
302
+ }
303
+ /**
304
+ * Check 11: No CI configured.
305
+ */
306
+ async function checkCi(rootPath) {
307
+ const ciPaths = [
308
+ join(rootPath, '.github', 'workflows'),
309
+ join(rootPath, '.gitlab-ci.yml'),
310
+ join(rootPath, '.circleci'),
311
+ join(rootPath, 'Jenkinsfile'),
312
+ ];
313
+ for (const ciPath of ciPaths) {
314
+ try {
315
+ await access(ciPath);
316
+ return null; // CI found
317
+ }
318
+ catch {
319
+ // Continue checking
320
+ }
321
+ }
322
+ return {
323
+ priority: 'medium',
324
+ category: 'CI/CD',
325
+ title: 'No CI configured',
326
+ description: 'Add a CI workflow to run prompt tests automatically',
327
+ command: 'codeprobe doctor',
328
+ };
329
+ }
330
+ /**
331
+ * Check 12: Multiple AI tool configs without coordination.
332
+ */
333
+ async function checkMultipleAiConfigs(rootPath) {
334
+ const configs = [];
335
+ const paths = [
336
+ [join(rootPath, 'CLAUDE.md'), 'CLAUDE.md'],
337
+ [join(rootPath, '.cursorrules'), '.cursorrules'],
338
+ [join(rootPath, '.windsurfrules'), '.windsurfrules'],
339
+ [join(rootPath, '.github', 'copilot-instructions.md'), 'copilot-instructions.md'],
340
+ ];
341
+ for (const [path, name] of paths) {
342
+ if (await fileExists(path)) {
343
+ configs.push(name);
344
+ }
345
+ }
346
+ if (configs.length >= 2) {
347
+ return {
348
+ priority: 'low',
349
+ category: 'Configuration',
350
+ title: 'Multiple AI tool configs detected',
351
+ description: `Found: ${configs.join(', ')}. Consider keeping them in sync`,
352
+ command: 'codeprobe generate-rules',
353
+ };
354
+ }
355
+ return null;
356
+ }
357
+ // ---------------------------------------------------------------------------
358
+ // Score calculation
359
+ // ---------------------------------------------------------------------------
360
+ function calculateScore(recommendations) {
361
+ let score = 10;
362
+ for (const rec of recommendations) {
363
+ switch (rec.priority) {
364
+ case 'critical':
365
+ score -= 3;
366
+ break;
367
+ case 'high':
368
+ score -= 2;
369
+ break;
370
+ case 'medium':
371
+ score -= 1;
372
+ break;
373
+ case 'low':
374
+ score -= 0.5;
375
+ break;
376
+ }
377
+ }
378
+ return Math.max(0, Math.min(10, Math.round(score)));
379
+ }
380
+ function getScoreMessage(score) {
381
+ if (score >= 9)
382
+ return 'Excellent setup';
383
+ if (score >= 7)
384
+ return 'Good, minor improvements possible';
385
+ if (score >= 5)
386
+ return 'Room for improvement';
387
+ if (score >= 3)
388
+ return 'Needs attention';
389
+ return 'Significant issues to address';
390
+ }
391
+ // ---------------------------------------------------------------------------
392
+ // Main runner
393
+ // ---------------------------------------------------------------------------
394
+ async function runRecommendations(rootPath) {
395
+ const checks = [
396
+ checkNoSpecs,
397
+ checkSpecsWithoutTests,
398
+ checkAiConfig,
399
+ checkContextWindow,
400
+ checkLargeFiles,
401
+ checkGitignore,
402
+ checkLockFiles,
403
+ checkTestHistory,
404
+ checkSecurityIssues,
405
+ checkLintWarnings,
406
+ checkCi,
407
+ checkMultipleAiConfigs,
408
+ ];
409
+ const results = await Promise.all(checks.map((check) => check(rootPath)));
410
+ const recommendations = results.filter((r) => r !== null);
411
+ // Sort by priority
412
+ const priorityOrder = {
413
+ critical: 0,
414
+ high: 1,
415
+ medium: 2,
416
+ low: 3,
417
+ };
418
+ recommendations.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);
419
+ return recommendations;
420
+ }
421
+ // ---------------------------------------------------------------------------
422
+ // Command
423
+ // ---------------------------------------------------------------------------
424
+ export function registerRecommendCommand(program) {
425
+ program
426
+ .command('recommend [path]')
427
+ .description('Analyze project and give actionable recommendations for prompt engineering')
428
+ .option('--json', 'Output recommendations as JSON')
429
+ .action(async (pathArg, options) => {
430
+ if (options.json) {
431
+ setLogLevel('silent');
432
+ }
433
+ const chalk = (await import('chalk')).default;
434
+ const targetPath = resolvePath(pathArg ?? '.');
435
+ if (!(await isDirectory(targetPath))) {
436
+ console.error(chalk.red(`Error: path is not a directory: ${targetPath}`));
437
+ process.exitCode = 1;
438
+ return;
439
+ }
440
+ const recommendations = await runRecommendations(targetPath);
441
+ const score = calculateScore(recommendations);
442
+ if (options.json) {
443
+ console.log(JSON.stringify({ recommendations, score }, null, 2));
444
+ return;
445
+ }
446
+ console.log(chalk.bold('\nSmart Recommendations'));
447
+ console.log('');
448
+ if (recommendations.length === 0) {
449
+ console.log(chalk.green(' No issues found — your project looks great!'));
450
+ console.log('');
451
+ console.log(chalk.bold(` Score: ${score}/10 — ${getScoreMessage(score)}`));
452
+ console.log('');
453
+ return;
454
+ }
455
+ const priorityColor = {
456
+ critical: chalk.bgRed.white,
457
+ high: chalk.red,
458
+ medium: chalk.yellow,
459
+ low: chalk.blue,
460
+ };
461
+ for (const rec of recommendations) {
462
+ const label = priorityColor[rec.priority](` ${rec.priority.toUpperCase()} `);
463
+ console.log(` ${label} ${chalk.bold(rec.title)}`);
464
+ console.log(` ${rec.description}`);
465
+ console.log(` ${chalk.dim('\u2192 Run:')} ${chalk.cyan(rec.command)}`);
466
+ console.log('');
467
+ }
468
+ console.log(chalk.bold(` Score: ${score}/10 — ${getScoreMessage(score)}`));
469
+ console.log('');
470
+ });
471
+ }
472
+ //# sourceMappingURL=recommend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommend.js","sourceRoot":"","sources":["../../src/commands/recommend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `codeprobe regression [path]` — Run tests and compare against a saved baseline.
3
+ *
4
+ * First run with `--save` to establish a baseline of passing tests.
5
+ * Subsequent runs compare current results against that baseline and
6
+ * report any regressions (tests that previously passed but now fail).
7
+ */
8
+ import { Command } from 'commander';
9
+ export declare function registerRegressionCommand(program: Command): void;
10
+ //# sourceMappingURL=regression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regression.d.ts","sourceRoot":"","sources":["../../src/commands/regression.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8DpC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2MhE"}