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,141 @@
1
+ /**
2
+ * `codeprobe flaky [path]` — Detect flaky tests by running each test N times.
3
+ *
4
+ * Runs each test multiple times and reports consistency. In mock mode,
5
+ * tests are deterministic and should always be STABLE. In live mode,
6
+ * flakiness reflects real model non-determinism.
7
+ */
8
+ import { resolve } from 'node:path';
9
+ import { resolvePath } from '../utils/paths.js';
10
+ import { fileExists, isDirectory } from '../utils/fs.js';
11
+ import { formatTable } from '../utils/output.js';
12
+ import { parsePromptSpec, runSingleTest, } from '../core/promptRunner.js';
13
+ import { setLogLevel } from '../utils/logger.js';
14
+ // ---------------------------------------------------------------------------
15
+ // Command registration
16
+ // ---------------------------------------------------------------------------
17
+ export function registerFlakyCommand(program) {
18
+ program
19
+ .command('flaky [path]')
20
+ .description('Detect flaky tests by running each test multiple times')
21
+ .option('--runs <n>', 'Number of runs per test', '5')
22
+ .option('--json', 'Output results as JSON')
23
+ .option('--mode <mode>', 'Execution mode: mock or live', 'mock')
24
+ .option('--model <model>', 'Override the model in the prompt spec (live mode)')
25
+ .action(async (pathArg, options) => {
26
+ if (options.json) {
27
+ setLogLevel('silent');
28
+ }
29
+ const chalk = (await import('chalk')).default;
30
+ const targetPath = resolvePath(pathArg ?? 'prompts');
31
+ const numRuns = Math.max(1, parseInt(options.runs ?? '5', 10));
32
+ const mode = options.mode === 'live' ? 'live' : 'mock';
33
+ const runOpts = {
34
+ mode,
35
+ verbose: false,
36
+ cache: false, // Never cache for flakiness detection
37
+ modelOverride: options.model,
38
+ };
39
+ // Collect prompt spec files
40
+ let specFiles;
41
+ if (await fileExists(targetPath)) {
42
+ specFiles = [targetPath];
43
+ }
44
+ else if (await isDirectory(targetPath)) {
45
+ const { glob } = await import('glob');
46
+ specFiles = await glob(resolve(targetPath, '**/*.prompt.{yaml,yml}'), { absolute: true });
47
+ if (specFiles.length === 0) {
48
+ specFiles = await glob(resolve(targetPath, '**/*.{yaml,yml}'), { absolute: true });
49
+ }
50
+ specFiles.sort();
51
+ }
52
+ else {
53
+ console.error(chalk.red(`Error: path not found: ${targetPath}`));
54
+ process.exitCode = 1;
55
+ return;
56
+ }
57
+ if (specFiles.length === 0) {
58
+ if (options.json) {
59
+ console.log(JSON.stringify({ tests: [], stableCount: 0, flakyCount: 0, totalCount: 0 }, null, 2));
60
+ }
61
+ else {
62
+ console.log(chalk.yellow('\nNo prompt spec files found.'));
63
+ }
64
+ return;
65
+ }
66
+ // Run each test N times
67
+ const allResults = [];
68
+ for (const specFile of specFiles) {
69
+ const spec = await parsePromptSpec(specFile);
70
+ const tests = spec.tests ?? [];
71
+ for (const test of tests) {
72
+ let passCount = 0;
73
+ let failCount = 0;
74
+ for (let i = 0; i < numRuns; i++) {
75
+ const result = await runSingleTest(spec, test, runOpts);
76
+ if (result.passed) {
77
+ passCount++;
78
+ }
79
+ else {
80
+ failCount++;
81
+ }
82
+ }
83
+ const passRate = Math.round((passCount / numRuns) * 100);
84
+ const isStable = passRate === 100 || passRate === 0;
85
+ allResults.push({
86
+ testName: test.name,
87
+ promptName: spec.name,
88
+ runs: numRuns,
89
+ passed: passCount,
90
+ failed: failCount,
91
+ passRate,
92
+ status: isStable ? 'STABLE' : 'FLAKY',
93
+ });
94
+ }
95
+ }
96
+ const stableCount = allResults.filter((r) => r.status === 'STABLE').length;
97
+ const flakyCount = allResults.filter((r) => r.status === 'FLAKY').length;
98
+ const report = {
99
+ tests: allResults,
100
+ stableCount,
101
+ flakyCount,
102
+ totalCount: allResults.length,
103
+ };
104
+ // JSON output
105
+ if (options.json) {
106
+ console.log(JSON.stringify(report, null, 2));
107
+ return;
108
+ }
109
+ // Table output
110
+ console.log('');
111
+ console.log(chalk.bold('Flakiness Report'));
112
+ console.log('');
113
+ const headers = ['Test', 'Runs', 'Pass', 'Fail', 'Rate', 'Status'];
114
+ const rows = [];
115
+ for (const r of allResults) {
116
+ const statusStr = r.status === 'STABLE'
117
+ ? chalk.green('STABLE')
118
+ : chalk.yellow('FLAKY');
119
+ rows.push([
120
+ `${r.promptName}/${r.testName}`,
121
+ String(r.runs),
122
+ String(r.passed),
123
+ String(r.failed),
124
+ `${r.passRate}%`,
125
+ statusStr,
126
+ ]);
127
+ }
128
+ const table = formatTable(headers, rows);
129
+ for (const line of table.split('\n')) {
130
+ console.log(` ${line}`);
131
+ }
132
+ console.log('');
133
+ console.log(` Overall: ${chalk.green(`${stableCount}/${allResults.length} stable`)}, ` +
134
+ `${flakyCount > 0 ? chalk.yellow(`${flakyCount}/${allResults.length} flaky`) : `${flakyCount}/${allResults.length} flaky`}`);
135
+ console.log('');
136
+ if (flakyCount > 0) {
137
+ process.exitCode = 1;
138
+ }
139
+ });
140
+ }
141
+ //# sourceMappingURL=flaky.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flaky.js","sourceRoot":"","sources":["../../src/commands/flaky.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `codeprobe generate-claudemd [path]` — Auto-generate a CLAUDE.md file
3
+ * based on repository analysis.
4
+ *
5
+ * Scans the directory for tech stack indicators, context budget, Claude
6
+ * assets, and key files, then produces a CLAUDE.md that helps Claude Code
7
+ * understand the project.
8
+ */
9
+ import { Command } from 'commander';
10
+ export declare function registerGenerateClaudeMdCommand(program: Command): void;
11
+ //# sourceMappingURL=generateClaudeMd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateClaudeMd.d.ts","sourceRoot":"","sources":["../../src/commands/generateClaudeMd.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiTpC,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsDtE"}
@@ -0,0 +1,278 @@
1
+ /**
2
+ * `codeprobe generate-claudemd [path]` — Auto-generate a CLAUDE.md file
3
+ * based on repository analysis.
4
+ *
5
+ * Scans the directory for tech stack indicators, context budget, Claude
6
+ * assets, and key files, then produces a CLAUDE.md that helps Claude Code
7
+ * understand the project.
8
+ */
9
+ import { stat, writeFile } from 'node:fs/promises';
10
+ import { resolve, basename } from 'node:path';
11
+ import { analyzeContext } from '../core/contextAnalyzer.js';
12
+ import { scanForClaudeAssets } from '../core/agentTracer.js';
13
+ import { readTextFile, fileExists } from '../utils/fs.js';
14
+ import { resolvePath } from '../utils/paths.js';
15
+ import { formatTokens } from '../utils/output.js';
16
+ const TECH_INDICATORS = [
17
+ { file: 'package.json', tech: 'Node.js / TypeScript / JavaScript' },
18
+ { file: 'go.mod', tech: 'Go' },
19
+ { file: 'requirements.txt', tech: 'Python' },
20
+ { file: 'pyproject.toml', tech: 'Python' },
21
+ { file: 'Cargo.toml', tech: 'Rust' },
22
+ { file: 'pom.xml', tech: 'Java' },
23
+ { file: 'build.gradle', tech: 'Java' },
24
+ { file: 'Gemfile', tech: 'Ruby' },
25
+ { file: 'mix.exs', tech: 'Elixir' },
26
+ ];
27
+ // -----------------------------------------------------------------------
28
+ // Helpers
29
+ // -----------------------------------------------------------------------
30
+ /**
31
+ * Detect technologies present in the target directory by checking for
32
+ * well-known build/config files.
33
+ */
34
+ async function detectTechStack(targetPath) {
35
+ const detected = [];
36
+ const seen = new Set();
37
+ for (const indicator of TECH_INDICATORS) {
38
+ const indicatorPath = resolve(targetPath, indicator.file);
39
+ if (await fileExists(indicatorPath)) {
40
+ if (!seen.has(indicator.tech)) {
41
+ seen.add(indicator.tech);
42
+ detected.push(indicator.tech);
43
+ }
44
+ }
45
+ }
46
+ // Check for .csproj files (glob-style — just look for any in root)
47
+ const { walkDirectory } = await import('../utils/fs.js');
48
+ const entries = await walkDirectory(targetPath, {
49
+ ignoreDirs: new Set([
50
+ 'node_modules', '.git', 'dist', 'build', 'coverage',
51
+ '__pycache__', '.next', '.nuxt', 'vendor', '.venv',
52
+ ]),
53
+ });
54
+ const hasCsproj = entries.some((e) => e.isFile && e.extension === '.csproj');
55
+ if (hasCsproj && !seen.has('.NET / C#')) {
56
+ detected.push('.NET / C#');
57
+ }
58
+ return detected;
59
+ }
60
+ /**
61
+ * Read project name and description from package.json if it exists.
62
+ */
63
+ async function readPackageJson(targetPath) {
64
+ const pkgPath = resolve(targetPath, 'package.json');
65
+ const content = await readTextFile(pkgPath);
66
+ if (content === null)
67
+ return null;
68
+ try {
69
+ const parsed = JSON.parse(content);
70
+ if (typeof parsed === 'object' && parsed !== null) {
71
+ const pkg = parsed;
72
+ return {
73
+ name: typeof pkg['name'] === 'string' ? pkg['name'] : '',
74
+ description: typeof pkg['description'] === 'string' ? pkg['description'] : '',
75
+ };
76
+ }
77
+ }
78
+ catch {
79
+ // Invalid JSON — ignore
80
+ }
81
+ return null;
82
+ }
83
+ /**
84
+ * Build the directory structure section by summarizing top-level dirs
85
+ * with file counts.
86
+ */
87
+ function buildDirectorySection(entries) {
88
+ const dirCounts = new Map();
89
+ for (const entry of entries) {
90
+ if (!entry.isFile)
91
+ continue;
92
+ const parts = entry.relativePath.split(/[/\\]/);
93
+ const topDir = parts.length > 1 ? parts[0] : '(root)';
94
+ dirCounts.set(topDir, (dirCounts.get(topDir) ?? 0) + 1);
95
+ }
96
+ // Sort by file count descending
97
+ const sorted = Array.from(dirCounts.entries()).sort((a, b) => b[1] - a[1]);
98
+ if (sorted.length === 0)
99
+ return '_No files found._';
100
+ const lines = [];
101
+ for (const [dir, count] of sorted.slice(0, 15)) {
102
+ lines.push(`- \`${dir}/\` — ${count} file${count === 1 ? '' : 's'}`);
103
+ }
104
+ if (sorted.length > 15) {
105
+ lines.push(`- _...and ${sorted.length - 15} more directories_`);
106
+ }
107
+ return lines.join('\n');
108
+ }
109
+ /**
110
+ * Generate the full CLAUDE.md content string.
111
+ */
112
+ async function generateClaudeMdContent(targetPath) {
113
+ const absolutePath = resolve(targetPath);
114
+ const dirName = basename(absolutePath);
115
+ // Run analysis in parallel
116
+ const [analysis, assets, techStack, pkgInfo] = await Promise.all([
117
+ analyzeContext(absolutePath),
118
+ scanForClaudeAssets(absolutePath),
119
+ detectTechStack(absolutePath),
120
+ readPackageJson(absolutePath),
121
+ ]);
122
+ // Project title
123
+ const projectName = pkgInfo?.name || dirName;
124
+ const description = pkgInfo?.description || `Project at \`${dirName}\``;
125
+ // Directory structure from walk entries (re-use analysis data for file entries)
126
+ // We need to walk again to get directory entries for the structure section.
127
+ const { walkDirectory } = await import('../utils/fs.js');
128
+ const allEntries = await walkDirectory(absolutePath, {
129
+ ignoreDirs: new Set([
130
+ 'node_modules', '.git', 'dist', 'build', 'coverage',
131
+ '__pycache__', '.next', '.nuxt', 'vendor', '.venv',
132
+ ]),
133
+ });
134
+ const directorySection = buildDirectorySection(allEntries);
135
+ // Tech stack section
136
+ const techStackSection = techStack.length > 0
137
+ ? techStack.map((t) => `- ${t}`).join('\n')
138
+ : '- _No recognized tech stack detected_';
139
+ // Context budget section
140
+ const fit200k = analysis.fitEstimates.find((f) => f.windowLabel === '200k');
141
+ const fit1M = analysis.fitEstimates.find((f) => f.windowLabel === '1M');
142
+ const fitsLabel = (fits, utilization) => {
143
+ const pct = (utilization * 100).toFixed(1);
144
+ return fits ? `fits (${pct}% utilization)` : `doesn't fit (${pct}% utilization)`;
145
+ };
146
+ const contextBudgetLines = [
147
+ `- Total files: ${analysis.totalFiles}`,
148
+ `- Estimated tokens: ${formatTokens(analysis.estimatedTokens)}`,
149
+ ];
150
+ if (fit200k) {
151
+ contextBudgetLines.push(`- 200k window: ${fitsLabel(fit200k.fits, fit200k.utilization)}`);
152
+ }
153
+ if (fit1M) {
154
+ contextBudgetLines.push(`- 1M window: ${fitsLabel(fit1M.fits, fit1M.utilization)}`);
155
+ }
156
+ // Build & Run section
157
+ let buildRunSection;
158
+ if (pkgInfo) {
159
+ buildRunSection = [
160
+ '```bash',
161
+ 'npm install',
162
+ 'npm run build',
163
+ 'npm test',
164
+ 'npm start',
165
+ '```',
166
+ ].join('\n');
167
+ }
168
+ else {
169
+ buildRunSection = '_Add build and run instructions here._';
170
+ }
171
+ // Claude Assets Found section
172
+ let claudeAssetsSection;
173
+ if (assets.length > 0) {
174
+ claudeAssetsSection = assets
175
+ .map((a) => `- \`${a.path.replace(absolutePath + '/', '')}\` — ${a.type} (${a.confidence} confidence)`)
176
+ .join('\n');
177
+ }
178
+ else {
179
+ claudeAssetsSection = '_No Claude Code assets found (no CLAUDE.md, .claude/, skills, hooks, or MCP configs)._';
180
+ }
181
+ // Key Files section (top 10 by token count)
182
+ const topFiles = analysis.largestFiles.slice(0, 10);
183
+ let keyFilesSection;
184
+ if (topFiles.length > 0) {
185
+ keyFilesSection = topFiles
186
+ .map((f) => `- \`${f.path}\` — ${formatTokens(f.estimatedTokens)} tokens`)
187
+ .join('\n');
188
+ }
189
+ else {
190
+ keyFilesSection = '_No text files found._';
191
+ }
192
+ // Context Strategy section
193
+ let strategySection;
194
+ if (fit200k?.fits) {
195
+ strategySection =
196
+ 'Repository fits comfortably in the 200k context window. Full codebase can be included.';
197
+ }
198
+ else if (fit1M?.fits) {
199
+ strategySection =
200
+ 'Repository fits in the 1M window but exceeds 200k. Use `codeprobe pack --target 200k` to identify priority files.';
201
+ }
202
+ else {
203
+ strategySection =
204
+ 'Repository exceeds context windows. Focus on specific modules. Use `codeprobe pack` to build a targeted context plan.';
205
+ }
206
+ // Assemble the final document
207
+ const sections = [
208
+ `# ${projectName}`,
209
+ '',
210
+ '## Overview',
211
+ description,
212
+ '',
213
+ '## Tech Stack',
214
+ techStackSection,
215
+ '',
216
+ '## Project Structure',
217
+ directorySection,
218
+ '',
219
+ '## Context Budget',
220
+ contextBudgetLines.join('\n'),
221
+ '',
222
+ '## Build & Run',
223
+ buildRunSection,
224
+ '',
225
+ '## Claude Assets Found',
226
+ claudeAssetsSection,
227
+ '',
228
+ '## Key Files',
229
+ keyFilesSection,
230
+ '',
231
+ '## Context Strategy',
232
+ strategySection,
233
+ '',
234
+ ];
235
+ return sections.join('\n');
236
+ }
237
+ // -----------------------------------------------------------------------
238
+ // Command registration
239
+ // -----------------------------------------------------------------------
240
+ export function registerGenerateClaudeMdCommand(program) {
241
+ program
242
+ .command('generate-claudemd [path]')
243
+ .description('Auto-generate a CLAUDE.md file based on repository analysis')
244
+ .option('--dry-run', 'Print to stdout instead of writing a file')
245
+ .option('--output <file>', 'Custom output path (default: CLAUDE.md)')
246
+ .action(async (pathArg, options) => {
247
+ const targetPath = resolvePath(pathArg ?? '.');
248
+ // Validate the target path exists and is a directory
249
+ try {
250
+ const s = await stat(targetPath);
251
+ if (!s.isDirectory()) {
252
+ console.error(`Error: not a directory: ${targetPath}`);
253
+ process.exitCode = 1;
254
+ return;
255
+ }
256
+ }
257
+ catch {
258
+ console.error(`Error: path not found: ${targetPath}`);
259
+ process.exitCode = 1;
260
+ return;
261
+ }
262
+ const chalk = (await import('chalk')).default;
263
+ if (!options.dryRun) {
264
+ console.log(chalk.dim('Analyzing repository...'));
265
+ }
266
+ const content = await generateClaudeMdContent(targetPath);
267
+ if (options.dryRun) {
268
+ console.log(content);
269
+ return;
270
+ }
271
+ const outputPath = options.output
272
+ ? resolvePath(options.output)
273
+ : resolve(targetPath, 'CLAUDE.md');
274
+ await writeFile(outputPath, content, 'utf-8');
275
+ console.log(chalk.green(`CLAUDE.md written to ${outputPath}`));
276
+ });
277
+ }
278
+ //# sourceMappingURL=generateClaudeMd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateClaudeMd.js","sourceRoot":"","sources":["../../src/commands/generateClaudeMd.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAWlD,MAAM,eAAe,GAAiC;IACpD,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,mCAAmC,EAAE;IACnE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE;IAC9B,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC5C,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC1C,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;IACpC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;IACjC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE;IACtC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;IACjC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE;CACpC,CAAC;AAEF,0EAA0E;AAC1E,UAAU;AACV,0EAA0E;AAE1E;;;GAGG;AACH,KAAK,UAAU,eAAe,CAAC,UAAkB;IAC/C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,SAAS,IAAI,eAAe,EAAE,CAAC;QACxC,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,MAAM,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACzB,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE;QAC9C,UAAU,EAAE,IAAI,GAAG,CAAC;YAClB,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;YACnD,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO;SACnD,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAC5B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,CAC7C,CAAC;IACF,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAOD;;GAEG;AACH,KAAK,UAAU,eAAe,CAC5B,UAAkB;IAElB,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,MAAM,GAAG,GAAG,MAAiC,CAAC;YAC9C,OAAO;gBACL,IAAI,EAAE,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;gBACxD,WAAW,EACT,OAAO,GAAG,CAAC,aAAa,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE;aACnE,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAC5B,OAIE;IAEF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE5C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,SAAS;QAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QACvD,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,gCAAgC;IAChC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CACjD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CACtB,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,mBAAmB,CAAC;IAEpD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAC/C,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,SAAS,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,aAAa,MAAM,CAAC,MAAM,GAAG,EAAE,oBAAoB,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,uBAAuB,CACpC,UAAkB;IAElB,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEvC,2BAA2B;IAC3B,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC/D,cAAc,CAAC,YAAY,CAAC;QAC5B,mBAAmB,CAAC,YAAY,CAAC;QACjC,eAAe,CAAC,YAAY,CAAC;QAC7B,eAAe,CAAC,YAAY,CAAC;KAC9B,CAAC,CAAC;IAEH,gBAAgB;IAChB,MAAM,WAAW,GAAG,OAAO,EAAE,IAAI,IAAI,OAAO,CAAC;IAC7C,MAAM,WAAW,GACf,OAAO,EAAE,WAAW,IAAI,gBAAgB,OAAO,IAAI,CAAC;IAEtD,gFAAgF;IAChF,4EAA4E;IAC5E,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,YAAY,EAAE;QACnD,UAAU,EAAE,IAAI,GAAG,CAAC;YAClB,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;YACnD,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO;SACnD,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAE3D,qBAAqB;IACrB,MAAM,gBAAgB,GACpB,SAAS,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC3C,CAAC,CAAC,uCAAuC,CAAC;IAE9C,yBAAyB;IACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,MAAM,CAChC,CAAC;IACF,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAC9B,CAAC;IAEF,MAAM,SAAS,GAAG,CAChB,IAAa,EACb,WAAmB,EACX,EAAE;QACV,MAAM,GAAG,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC,CAAC,CAAC,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IACnF,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAG;QACzB,kBAAkB,QAAQ,CAAC,UAAU,EAAE;QACvC,uBAAuB,YAAY,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;KAChE,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,kBAAkB,CAAC,IAAI,CACrB,kBAAkB,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CACjE,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,kBAAkB,CAAC,IAAI,CACrB,gBAAgB,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,EAAE,CAC3D,CAAC;IACJ,CAAC;IAED,sBAAsB;IACtB,IAAI,eAAuB,CAAC;IAC5B,IAAI,OAAO,EAAE,CAAC;QACZ,eAAe,GAAG;YAChB,SAAS;YACT,aAAa;YACb,eAAe;YACf,UAAU;YACV,WAAW;YACX,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;SAAM,CAAC;QACN,eAAe,GAAG,wCAAwC,CAAC;IAC7D,CAAC;IAED,8BAA8B;IAC9B,IAAI,mBAA2B,CAAC;IAChC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,mBAAmB,GAAG,MAAM;aACzB,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,GAAG,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,UAAU,cAAc,CAC7F;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;SAAM,CAAC;QACN,mBAAmB,GAAG,wFAAwF,CAAC;IACjH,CAAC;IAED,4CAA4C;IAC5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpD,IAAI,eAAuB,CAAC;IAC5B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,eAAe,GAAG,QAAQ;aACvB,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,OAAO,CAAC,CAAC,IAAI,QAAQ,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC,SAAS,CAChE;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;SAAM,CAAC;QACN,eAAe,GAAG,wBAAwB,CAAC;IAC7C,CAAC;IAED,2BAA2B;IAC3B,IAAI,eAAuB,CAAC;IAC5B,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;QAClB,eAAe;YACb,wFAAwF,CAAC;IAC7F,CAAC;SAAM,IAAI,KAAK,EAAE,IAAI,EAAE,CAAC;QACvB,eAAe;YACb,mHAAmH,CAAC;IACxH,CAAC;SAAM,CAAC;QACN,eAAe;YACb,uHAAuH,CAAC;IAC5H,CAAC;IAED,8BAA8B;IAC9B,MAAM,QAAQ,GAAG;QACf,KAAK,WAAW,EAAE;QAClB,EAAE;QACF,aAAa;QACb,WAAW;QACX,EAAE;QACF,eAAe;QACf,gBAAgB;QAChB,EAAE;QACF,sBAAsB;QACtB,gBAAgB;QAChB,EAAE;QACF,mBAAmB;QACnB,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,EAAE;QACF,gBAAgB;QAChB,eAAe;QACf,EAAE;QACF,wBAAwB;QACxB,mBAAmB;QACnB,EAAE;QACF,cAAc;QACd,eAAe;QACf,EAAE;QACF,qBAAqB;QACrB,eAAe;QACf,EAAE;KACH,CAAC;IAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,0EAA0E;AAC1E,uBAAuB;AACvB,0EAA0E;AAE1E,MAAM,UAAU,+BAA+B,CAAC,OAAgB;IAC9D,OAAO;SACJ,OAAO,CAAC,0BAA0B,CAAC;SACnC,WAAW,CACV,6DAA6D,CAC9D;SACA,MAAM,CAAC,WAAW,EAAE,2CAA2C,CAAC;SAChE,MAAM,CAAC,iBAAiB,EAAE,yCAAyC,CAAC;SACpE,MAAM,CACL,KAAK,EACH,OAA2B,EAC3B,OAA8C,EAC9C,EAAE;QACF,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;QAE/C,qDAAqD;QACrD,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC;YACjC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACrB,OAAO,CAAC,KAAK,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;gBACvD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;YACtD,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAE9C,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,CACrC,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAE1D,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM;YAC/B,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;YAC7B,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QAErC,MAAM,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,wBAAwB,UAAU,EAAE,CAAC,CAClD,CAAC;IACJ,CAAC,CACF,CAAC;AACN,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * `codeprobe generate-rules [path]` — Generate AI tool config files
3
+ * for Cursor (.cursorrules), Windsurf (.windsurfrules), and GitHub Copilot
4
+ * (.github/copilot-instructions.md) based on repository analysis.
5
+ *
6
+ * Detects tech stack, reads existing CLAUDE.md if present, and produces
7
+ * config files that help each AI tool understand the project.
8
+ */
9
+ import { Command } from 'commander';
10
+ export declare function registerGenerateRulesCommand(program: Command): void;
11
+ //# sourceMappingURL=generateRules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateRules.d.ts","sourceRoot":"","sources":["../../src/commands/generateRules.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAicpC,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6FnE"}