octocode-cli 1.2.8 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/README.md +42 -35
  2. package/out/octocode-cli.js +36 -11767
  3. package/package.json +36 -36
  4. package/skills/README.md +42 -114
  5. package/skills/{octocode-code-engineer → octocode-engineer}/.claude/settings.local.json +2 -1
  6. package/skills/octocode-engineer/README.md +99 -0
  7. package/skills/octocode-engineer/SKILL.md +499 -0
  8. package/skills/octocode-engineer/build.mjs +29 -0
  9. package/skills/{octocode-code-engineer → octocode-engineer}/eslint.config.mjs +3 -13
  10. package/skills/{octocode-code-engineer → octocode-engineer}/package.json +28 -27
  11. package/skills/octocode-engineer/references/ast-reference.md +166 -0
  12. package/skills/{octocode-code-engineer → octocode-engineer}/references/cli-reference.md +80 -6
  13. package/skills/octocode-engineer/references/externals.md +86 -0
  14. package/skills/{octocode-code-engineer → octocode-engineer}/references/output-files.md +46 -6
  15. package/skills/octocode-engineer/references/quality-indicators.md +202 -0
  16. package/skills/octocode-engineer/references/tool-workflows.md +298 -0
  17. package/skills/octocode-engineer/references/validation-playbooks.md +99 -0
  18. package/skills/octocode-engineer/scripts/ast/search.js +45 -0
  19. package/skills/octocode-engineer/scripts/ast/tree-search.js +27 -0
  20. package/skills/octocode-engineer/scripts/index.js +173 -0
  21. package/skills/octocode-engineer/scripts/run.js +179 -0
  22. package/skills/octocode-engineer/src/analysis/dependencies.ts +378 -0
  23. package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/discovery.test.ts +57 -0
  24. package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/discovery.ts +43 -0
  25. package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/search.test.ts +113 -0
  26. package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/search.ts +64 -1
  27. package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/tree-sitter.test.ts +118 -2
  28. package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/tree-sitter.ts +65 -3
  29. package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/ts-analyzer.test.ts +281 -1
  30. package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/ts-analyzer.ts +173 -3
  31. package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/security.test.ts +73 -0
  32. package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/security.ts +62 -4
  33. package/skills/octocode-engineer/src/detector-gating.test.ts +59 -0
  34. package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/code-quality.ts +342 -0
  35. package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/index.ts +8 -0
  36. package/skills/{octocode-code-engineer → octocode-engineer}/src/index.test.ts +565 -11
  37. package/skills/octocode-engineer/src/index.ts +468 -0
  38. package/skills/octocode-engineer/src/pipeline/affected.test.ts +147 -0
  39. package/skills/octocode-engineer/src/pipeline/affected.ts +68 -0
  40. package/skills/octocode-engineer/src/pipeline/baseline.test.ts +276 -0
  41. package/skills/octocode-engineer/src/pipeline/baseline.ts +76 -0
  42. package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/cli.test.ts +300 -53
  43. package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/cli.ts +180 -36
  44. package/skills/octocode-engineer/src/pipeline/config-loader.test.ts +264 -0
  45. package/skills/octocode-engineer/src/pipeline/config-loader.ts +109 -0
  46. package/skills/octocode-engineer/src/pipeline/create-options.ts +55 -0
  47. package/skills/octocode-engineer/src/pipeline/health-score.test.ts +65 -0
  48. package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/main.ts +130 -17
  49. package/skills/octocode-engineer/src/pipeline/progress.ts +51 -0
  50. package/skills/octocode-engineer/src/pipeline/reporters.test.ts +155 -0
  51. package/skills/octocode-engineer/src/pipeline/reporters.ts +64 -0
  52. package/skills/octocode-engineer/src/reporting/graph-features.test.ts +279 -0
  53. package/skills/{octocode-code-engineer → octocode-engineer}/src/reporting/output-contract.test.ts +6 -0
  54. package/skills/octocode-engineer/src/reporting/summary-md.test.ts +1066 -0
  55. package/skills/octocode-engineer/src/reporting/summary-md.ts +1604 -0
  56. package/skills/{octocode-code-engineer → octocode-engineer}/src/reporting/writer.ts +136 -13
  57. package/skills/octocode-engineer/src/run.ts +78 -0
  58. package/skills/{octocode-code-engineer → octocode-engineer}/src/sanity.test.ts +1 -1
  59. package/skills/octocode-engineer/src/types/analysis.ts +25 -0
  60. package/skills/octocode-engineer/src/types/collectors.ts +134 -0
  61. package/skills/{octocode-code-engineer → octocode-engineer}/src/types/constants.ts +75 -41
  62. package/skills/octocode-engineer/src/types/core.ts +203 -0
  63. package/skills/octocode-engineer/src/types/dependency.ts +215 -0
  64. package/skills/octocode-engineer/src/types/file-entry.ts +108 -0
  65. package/skills/octocode-engineer/src/types/findings.ts +105 -0
  66. package/skills/{octocode-code-engineer → octocode-engineer}/src/types/index.ts +60 -30
  67. package/skills/octocode-engineer/src/types/tree-sitter.ts +38 -0
  68. package/skills/{octocode-code-engineer → octocode-engineer}/tsconfig.json +1 -0
  69. package/skills/octocode-research/.octocode/scan/.cache/analysis-cache.json +1 -0
  70. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/architecture.json +1 -0
  71. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/ast-trees.txt +5566 -0
  72. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/code-quality.json +1 -0
  73. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/dead-code.json +1 -0
  74. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/file-inventory.json +1 -0
  75. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/findings.json +1 -0
  76. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/graph.md +189 -0
  77. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/security.json +1 -0
  78. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/summary.json +1 -0
  79. package/skills/octocode-research/.octocode/scan/2026-03-22T10-32-27-073Z/summary.md +265 -0
  80. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/architecture.json +1 -0
  81. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/ast-trees.txt +5555 -0
  82. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/code-quality.json +1 -0
  83. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/dead-code.json +1 -0
  84. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/file-inventory.json +1 -0
  85. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/findings.json +1 -0
  86. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/graph.md +190 -0
  87. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/security.json +1 -0
  88. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/summary.json +1 -0
  89. package/skills/octocode-research/.octocode/scan/2026-03-22T10-40-10-469Z/summary.md +265 -0
  90. package/skills/octocode-research/CHANGELOG.md +60 -0
  91. package/skills/octocode-research/README.md +102 -388
  92. package/skills/octocode-research/SKILL.md +169 -498
  93. package/skills/octocode-research/package.json +19 -31
  94. package/skills/octocode-research/references/PARALLEL_AGENT_PROTOCOL.md +19 -0
  95. package/skills/octocode-research/references/SESSION_MANAGEMENT.md +38 -0
  96. package/skills/octocode-research/scripts/server-init.js +1 -1
  97. package/skills/octocode-research/scripts/server.d.ts +2 -1
  98. package/skills/octocode-research/scripts/server.js +329 -233
  99. package/skills/octocode-research/src/__tests__/integration/promptsRoutes.test.ts +180 -0
  100. package/skills/octocode-research/src/__tests__/integration/serverHttp.test.ts +221 -0
  101. package/skills/octocode-research/src/__tests__/integration/serverLifecycle.test.ts +194 -0
  102. package/skills/octocode-research/src/__tests__/integration/toolsRoutes.test.ts +501 -0
  103. package/skills/octocode-research/src/__tests__/unit/readiness.test.ts +61 -0
  104. package/skills/octocode-research/src/__tests__/unit/resilience.test.ts +192 -0
  105. package/skills/octocode-research/src/__tests__/unit/responseFactory.test.ts +172 -0
  106. package/skills/octocode-research/src/__tests__/unit/responseParser.test.ts +288 -0
  107. package/skills/octocode-research/src/__tests__/unit/schemas.test.ts +509 -0
  108. package/skills/octocode-research/src/index.ts +4 -124
  109. package/skills/octocode-research/src/middleware/queryParser.ts +0 -26
  110. package/skills/octocode-research/src/routes/lsp.ts +58 -59
  111. package/skills/octocode-research/src/routes/package.ts +35 -65
  112. package/skills/octocode-research/src/routes/prompts.ts +3 -3
  113. package/skills/octocode-research/src/routes/tools.ts +8 -20
  114. package/skills/octocode-research/src/server-init.ts +30 -237
  115. package/skills/octocode-research/src/server.ts +50 -23
  116. package/skills/octocode-research/src/types/errorGuards.ts +9 -80
  117. package/skills/octocode-research/src/types/guards.ts +0 -28
  118. package/skills/octocode-research/src/types/mcp.ts +11 -66
  119. package/skills/octocode-research/src/types/responses.ts +11 -129
  120. package/skills/octocode-research/src/utils/circuitBreaker.ts +0 -21
  121. package/skills/octocode-research/src/utils/logger.ts +1 -97
  122. package/skills/octocode-research/src/utils/resilience.ts +2 -12
  123. package/skills/octocode-research/src/utils/responseFactory.ts +0 -42
  124. package/skills/octocode-research/src/utils/responseParser.ts +3 -25
  125. package/skills/octocode-research/src/utils/retry.ts +0 -63
  126. package/skills/octocode-research/src/utils/routeFactory.ts +1 -1
  127. package/skills/octocode-research/src/validation/httpPreprocess.ts +0 -3
  128. package/skills/octocode-research/src/validation/index.ts +0 -1
  129. package/skills/octocode-research/src/validation/schemas.ts +0 -63
  130. package/skills/octocode-research/src/validation/toolCallSchema.ts +3 -3
  131. package/skills/octocode-research/tsdown.config.ts +4 -0
  132. package/skills/octocode-research/vitest.config.ts +3 -0
  133. package/skills/octocode-code-engineer/.plan/VALIDATED_PLAN.md +0 -223
  134. package/skills/octocode-code-engineer/README.md +0 -178
  135. package/skills/octocode-code-engineer/SKILL.md +0 -418
  136. package/skills/octocode-code-engineer/minify-scripts.mjs +0 -32
  137. package/skills/octocode-code-engineer/references/agent-ast-reading-rfc.md +0 -95
  138. package/skills/octocode-code-engineer/references/architecture-techniques.md +0 -121
  139. package/skills/octocode-code-engineer/references/ast-search.md +0 -210
  140. package/skills/octocode-code-engineer/references/ast-tree-search.md +0 -151
  141. package/skills/octocode-code-engineer/references/concepts.md +0 -107
  142. package/skills/octocode-code-engineer/references/finding-categories.md +0 -128
  143. package/skills/octocode-code-engineer/references/improvement-roadmap.md +0 -304
  144. package/skills/octocode-code-engineer/references/playbooks.md +0 -204
  145. package/skills/octocode-code-engineer/references/present-results.md +0 -136
  146. package/skills/octocode-code-engineer/references/tool-workflows.md +0 -566
  147. package/skills/octocode-code-engineer/references/validate-investigate.md +0 -225
  148. package/skills/octocode-code-engineer/scripts/analysis/dependencies.js +0 -1
  149. package/skills/octocode-code-engineer/scripts/analysis/dependency-summary.js +0 -1
  150. package/skills/octocode-code-engineer/scripts/analysis/discovery.js +0 -1
  151. package/skills/octocode-code-engineer/scripts/analysis/graph-analytics.js +0 -1
  152. package/skills/octocode-code-engineer/scripts/analysis/semantic.js +0 -1
  153. package/skills/octocode-code-engineer/scripts/ast/helpers.js +0 -1
  154. package/skills/octocode-code-engineer/scripts/ast/metrics.js +0 -1
  155. package/skills/octocode-code-engineer/scripts/ast/search.js +0 -2
  156. package/skills/octocode-code-engineer/scripts/ast/tree-search.js +0 -2
  157. package/skills/octocode-code-engineer/scripts/ast/tree-sitter.js +0 -1
  158. package/skills/octocode-code-engineer/scripts/ast/ts-analyzer.js +0 -1
  159. package/skills/octocode-code-engineer/scripts/collectors/chains.js +0 -1
  160. package/skills/octocode-code-engineer/scripts/collectors/effects.js +0 -1
  161. package/skills/octocode-code-engineer/scripts/collectors/input-sources.js +0 -1
  162. package/skills/octocode-code-engineer/scripts/collectors/performance.js +0 -1
  163. package/skills/octocode-code-engineer/scripts/collectors/prototype-pollution.js +0 -1
  164. package/skills/octocode-code-engineer/scripts/collectors/security.js +0 -1
  165. package/skills/octocode-code-engineer/scripts/collectors/test-profile.js +0 -1
  166. package/skills/octocode-code-engineer/scripts/common/is-direct-run.js +0 -1
  167. package/skills/octocode-code-engineer/scripts/common/utils.js +0 -1
  168. package/skills/octocode-code-engineer/scripts/detectors/code-quality.js +0 -1
  169. package/skills/octocode-code-engineer/scripts/detectors/cohesion.js +0 -1
  170. package/skills/octocode-code-engineer/scripts/detectors/coupling.js +0 -1
  171. package/skills/octocode-code-engineer/scripts/detectors/cycle.js +0 -1
  172. package/skills/octocode-code-engineer/scripts/detectors/dead-code.js +0 -1
  173. package/skills/octocode-code-engineer/scripts/detectors/import-style.js +0 -1
  174. package/skills/octocode-code-engineer/scripts/detectors/index.js +0 -1
  175. package/skills/octocode-code-engineer/scripts/detectors/security.js +0 -1
  176. package/skills/octocode-code-engineer/scripts/detectors/semantic.js +0 -1
  177. package/skills/octocode-code-engineer/scripts/detectors/shared.js +0 -1
  178. package/skills/octocode-code-engineer/scripts/detectors/test-quality.js +0 -1
  179. package/skills/octocode-code-engineer/scripts/index.js +0 -1
  180. package/skills/octocode-code-engineer/scripts/pipeline/cache.js +0 -1
  181. package/skills/octocode-code-engineer/scripts/pipeline/cli.js +0 -1
  182. package/skills/octocode-code-engineer/scripts/pipeline/main.js +0 -2
  183. package/skills/octocode-code-engineer/scripts/reporting/analysis.js +0 -1
  184. package/skills/octocode-code-engineer/scripts/reporting/summary-md.js +0 -1
  185. package/skills/octocode-code-engineer/scripts/reporting/writer.js +0 -1
  186. package/skills/octocode-code-engineer/scripts/types/constants.js +0 -1
  187. package/skills/octocode-code-engineer/scripts/types/index.js +0 -1
  188. package/skills/octocode-code-engineer/scripts/types/interfaces.js +0 -1
  189. package/skills/octocode-code-engineer/src/analysis/dependencies.ts +0 -406
  190. package/skills/octocode-code-engineer/src/index.ts +0 -403
  191. package/skills/octocode-code-engineer/src/reporting/summary-md.test.ts +0 -421
  192. package/skills/octocode-code-engineer/src/reporting/summary-md.ts +0 -714
  193. package/skills/octocode-code-engineer/src/types/interfaces.ts +0 -682
  194. package/skills/octocode-research/src/types/toolTypes.ts +0 -33
  195. package/skills/octocode-research/src/utils/logEmoji.ts +0 -103
  196. /package/skills/{octocode-code-engineer → octocode-engineer}/.octocode/rfc/RFC-code-engineer-weakness-fixes.md +0 -0
  197. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/architecture.ts.html +0 -0
  198. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/ast-helpers.ts.html +0 -0
  199. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/ast-search.ts.html +0 -0
  200. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/base.css +0 -0
  201. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/block-navigation.js +0 -0
  202. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/cache.ts.html +0 -0
  203. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/cli.ts.html +0 -0
  204. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/clover.xml +0 -0
  205. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-effects.ts.html +0 -0
  206. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-input-sources.ts.html +0 -0
  207. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-performance.ts.html +0 -0
  208. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-prototype-pollution.ts.html +0 -0
  209. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-security.ts.html +0 -0
  210. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/collect-test-profile.ts.html +0 -0
  211. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/coverage-final.json +0 -0
  212. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/dependencies.ts.html +0 -0
  213. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/dependency-summary.ts.html +0 -0
  214. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/discovery.ts.html +0 -0
  215. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/favicon.png +0 -0
  216. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/graph-analytics.ts.html +0 -0
  217. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/index.html +0 -0
  218. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/index.ts.html +0 -0
  219. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/metrics.ts.html +0 -0
  220. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/pipeline.ts.html +0 -0
  221. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/prettify.css +0 -0
  222. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/prettify.js +0 -0
  223. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/report-analysis.ts.html +0 -0
  224. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/report-writer.ts.html +0 -0
  225. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/security-detectors.ts.html +0 -0
  226. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/semantic-detectors.ts.html +0 -0
  227. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/semantic.ts.html +0 -0
  228. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/sort-arrow-sprite.png +0 -0
  229. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/sorter.js +0 -0
  230. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/summary-md.ts.html +0 -0
  231. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/test-quality-detectors.ts.html +0 -0
  232. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/tree-sitter-analyzer.ts.html +0 -0
  233. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/ts-analyzer.ts.html +0 -0
  234. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/types.ts.html +0 -0
  235. /package/skills/{octocode-code-engineer → octocode-engineer}/coverage/utils.ts.html +0 -0
  236. /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/dependencies.test.ts +0 -0
  237. /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/dependency-summary.test.ts +0 -0
  238. /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/dependency-summary.ts +0 -0
  239. /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/graph-analytics.test.ts +0 -0
  240. /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/graph-analytics.ts +0 -0
  241. /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/semantic.test.ts +0 -0
  242. /package/skills/{octocode-code-engineer → octocode-engineer}/src/analysis/semantic.ts +0 -0
  243. /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/helpers.test.ts +0 -0
  244. /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/helpers.ts +0 -0
  245. /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/metrics.test.ts +0 -0
  246. /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/metrics.ts +0 -0
  247. /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/tree-search.test.ts +0 -0
  248. /package/skills/{octocode-code-engineer → octocode-engineer}/src/ast/tree-search.ts +0 -0
  249. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/chains.ts +0 -0
  250. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/effects.test.ts +0 -0
  251. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/effects.ts +0 -0
  252. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/input-sources.test.ts +0 -0
  253. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/input-sources.ts +0 -0
  254. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/performance.test.ts +0 -0
  255. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/performance.ts +0 -0
  256. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/prototype-pollution.test.ts +0 -0
  257. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/prototype-pollution.ts +0 -0
  258. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/test-profile.test.ts +0 -0
  259. /package/skills/{octocode-code-engineer → octocode-engineer}/src/collectors/test-profile.ts +0 -0
  260. /package/skills/{octocode-code-engineer → octocode-engineer}/src/common/is-direct-run.test.ts +0 -0
  261. /package/skills/{octocode-code-engineer → octocode-engineer}/src/common/is-direct-run.ts +0 -0
  262. /package/skills/{octocode-code-engineer → octocode-engineer}/src/common/utils.test.ts +0 -0
  263. /package/skills/{octocode-code-engineer → octocode-engineer}/src/common/utils.ts +0 -0
  264. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/cohesion.ts +0 -0
  265. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/coupling.ts +0 -0
  266. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/cycle.ts +0 -0
  267. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/dead-code.ts +0 -0
  268. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/import-style.ts +0 -0
  269. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/index.test.ts +0 -0
  270. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/security.test.ts +0 -0
  271. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/security.ts +0 -0
  272. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/semantic.ts +0 -0
  273. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/shared.ts +0 -0
  274. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/test-quality.test.ts +0 -0
  275. /package/skills/{octocode-code-engineer → octocode-engineer}/src/detectors/test-quality.ts +0 -0
  276. /package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/cache.test.ts +0 -0
  277. /package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/cache.ts +0 -0
  278. /package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline/main.test.ts +0 -0
  279. /package/skills/{octocode-code-engineer → octocode-engineer}/src/pipeline.test.ts +0 -0
  280. /package/skills/{octocode-code-engineer → octocode-engineer}/src/reporting/analysis.test.ts +0 -0
  281. /package/skills/{octocode-code-engineer → octocode-engineer}/src/reporting/analysis.ts +0 -0
  282. /package/skills/{octocode-code-engineer → octocode-engineer}/vitest.config.ts +0 -0
@@ -1,6 +1,7 @@
1
1
  import { describe, expect, it, vi } from 'vitest';
2
2
 
3
- import { parseArgs } from './cli.js';
3
+ import { parseArgs, HELP_TEXT } from './cli.js';
4
+ import { OptionsError } from './create-options.js';
4
5
  import { DEFAULT_OPTS } from '../types/index.js';
5
6
 
6
7
  describe('parseArgs', () => {
@@ -12,9 +13,9 @@ describe('parseArgs', () => {
12
13
  expect(opts.graph).toBe(false);
13
14
  expect(opts.parser).toBe('auto');
14
15
  expect(opts.findingsLimit).toBe(Infinity);
15
- expect(opts.minFunctionStatements).toBe(6);
16
- expect(opts.minFlowStatements).toBe(6);
17
- expect(opts.criticalComplexityThreshold).toBe(30);
16
+ expect(opts.thresholds.minFunctionStatements).toBe(6);
17
+ expect(opts.thresholds.minFlowStatements).toBe(6);
18
+ expect(opts.thresholds.criticalComplexityThreshold).toBe(30);
18
19
  expect(opts.deepLinkTopN).toBe(12);
19
20
  expect(opts.treeDepth).toBe(4);
20
21
  expect(opts.packageRoot).toMatch(/packages$/);
@@ -64,18 +65,18 @@ describe('parseArgs', () => {
64
65
 
65
66
  it('parses --min-function-statements', () => {
66
67
  expect(
67
- parseArgs(['--min-function-statements', '12']).minFunctionStatements
68
+ parseArgs(['--min-function-statements', '12']).thresholds.minFunctionStatements
68
69
  ).toBe(12);
69
70
  });
70
71
 
71
72
  it('parses --min-flow-statements', () => {
72
- expect(parseArgs(['--min-flow-statements', '8']).minFlowStatements).toBe(8);
73
+ expect(parseArgs(['--min-flow-statements', '8']).thresholds.minFlowStatements).toBe(8);
73
74
  });
74
75
 
75
76
  it('parses --critical-complexity-threshold', () => {
76
77
  expect(
77
78
  parseArgs(['--critical-complexity-threshold', '25'])
78
- .criticalComplexityThreshold
79
+ .thresholds.criticalComplexityThreshold
79
80
  ).toBe(25);
80
81
  });
81
82
 
@@ -88,56 +89,56 @@ describe('parseArgs', () => {
88
89
  });
89
90
 
90
91
  it('parses --coupling-threshold', () => {
91
- expect(parseArgs(['--coupling-threshold', '20']).couplingThreshold).toBe(
92
+ expect(parseArgs(['--coupling-threshold', '20']).thresholds.couplingThreshold).toBe(
92
93
  20
93
94
  );
94
95
  });
95
96
 
96
97
  it('parses --fan-in-threshold', () => {
97
- expect(parseArgs(['--fan-in-threshold', '25']).fanInThreshold).toBe(25);
98
+ expect(parseArgs(['--fan-in-threshold', '25']).thresholds.fanInThreshold).toBe(25);
98
99
  });
99
100
 
100
101
  it('parses --fan-out-threshold', () => {
101
- expect(parseArgs(['--fan-out-threshold', '18']).fanOutThreshold).toBe(18);
102
+ expect(parseArgs(['--fan-out-threshold', '18']).thresholds.fanOutThreshold).toBe(18);
102
103
  });
103
104
 
104
105
  it('parses --god-module-statements', () => {
105
106
  expect(
106
- parseArgs(['--god-module-statements', '600']).godModuleStatements
107
+ parseArgs(['--god-module-statements', '600']).thresholds.godModuleStatements
107
108
  ).toBe(600);
108
109
  });
109
110
 
110
111
  it('parses --god-module-exports', () => {
111
- expect(parseArgs(['--god-module-exports', '30']).godModuleExports).toBe(30);
112
+ expect(parseArgs(['--god-module-exports', '30']).thresholds.godModuleExports).toBe(30);
112
113
  });
113
114
 
114
115
  it('parses --god-function-statements', () => {
115
116
  expect(
116
- parseArgs(['--god-function-statements', '150']).godFunctionStatements
117
+ parseArgs(['--god-function-statements', '150']).thresholds.godFunctionStatements
117
118
  ).toBe(150);
118
119
  });
119
120
 
120
121
  it('parses --cognitive-complexity-threshold', () => {
121
122
  expect(
122
123
  parseArgs(['--cognitive-complexity-threshold', '20'])
123
- .cognitiveComplexityThreshold
124
+ .thresholds.cognitiveComplexityThreshold
124
125
  ).toBe(20);
125
126
  });
126
127
 
127
128
  it('parses --barrel-symbol-threshold', () => {
128
129
  expect(
129
- parseArgs(['--barrel-symbol-threshold', '50']).barrelSymbolThreshold
130
+ parseArgs(['--barrel-symbol-threshold', '50']).thresholds.barrelSymbolThreshold
130
131
  ).toBe(50);
131
132
  });
132
133
 
133
134
  it('parses --layer-order as comma-separated list', () => {
134
135
  const opts = parseArgs(['--layer-order', 'ui,service,repository']);
135
- expect(opts.layerOrder).toEqual(['ui', 'service', 'repository']);
136
+ expect(opts.thresholds.layerOrder).toEqual(['ui', 'service', 'repository']);
136
137
  });
137
138
 
138
139
  it('trims whitespace in --layer-order values', () => {
139
140
  const opts = parseArgs(['--layer-order', ' ui , service , repo ']);
140
- expect(opts.layerOrder).toEqual(['ui', 'service', 'repo']);
141
+ expect(opts.thresholds.layerOrder).toEqual(['ui', 'service', 'repo']);
141
142
  });
142
143
 
143
144
  it('parses --features with pillar name', () => {
@@ -220,20 +221,20 @@ describe('parseArgs', () => {
220
221
  'no',
221
222
  ]);
222
223
  expect(opts.findingsLimit).toBe(DEFAULT_OPTS.findingsLimit);
223
- expect(opts.couplingThreshold).toBe(DEFAULT_OPTS.couplingThreshold);
224
- expect(opts.fanInThreshold).toBe(DEFAULT_OPTS.fanInThreshold);
225
- expect(opts.fanOutThreshold).toBe(DEFAULT_OPTS.fanOutThreshold);
226
- expect(opts.godModuleStatements).toBe(DEFAULT_OPTS.godModuleStatements);
227
- expect(opts.godModuleExports).toBe(DEFAULT_OPTS.godModuleExports);
228
- expect(opts.godFunctionStatements).toBe(DEFAULT_OPTS.godFunctionStatements);
229
- expect(opts.cognitiveComplexityThreshold).toBe(
230
- DEFAULT_OPTS.cognitiveComplexityThreshold
224
+ expect(opts.thresholds.couplingThreshold).toBe(DEFAULT_OPTS.thresholds.couplingThreshold);
225
+ expect(opts.thresholds.fanInThreshold).toBe(DEFAULT_OPTS.thresholds.fanInThreshold);
226
+ expect(opts.thresholds.fanOutThreshold).toBe(DEFAULT_OPTS.thresholds.fanOutThreshold);
227
+ expect(opts.thresholds.godModuleStatements).toBe(DEFAULT_OPTS.thresholds.godModuleStatements);
228
+ expect(opts.thresholds.godModuleExports).toBe(DEFAULT_OPTS.thresholds.godModuleExports);
229
+ expect(opts.thresholds.godFunctionStatements).toBe(DEFAULT_OPTS.thresholds.godFunctionStatements);
230
+ expect(opts.thresholds.cognitiveComplexityThreshold).toBe(
231
+ DEFAULT_OPTS.thresholds.cognitiveComplexityThreshold
231
232
  );
232
- expect(opts.barrelSymbolThreshold).toBe(DEFAULT_OPTS.barrelSymbolThreshold);
233
- expect(opts.minFunctionStatements).toBe(DEFAULT_OPTS.minFunctionStatements);
234
- expect(opts.minFlowStatements).toBe(DEFAULT_OPTS.minFlowStatements);
235
- expect(opts.criticalComplexityThreshold).toBe(
236
- DEFAULT_OPTS.criticalComplexityThreshold
233
+ expect(opts.thresholds.barrelSymbolThreshold).toBe(DEFAULT_OPTS.thresholds.barrelSymbolThreshold);
234
+ expect(opts.thresholds.minFunctionStatements).toBe(DEFAULT_OPTS.thresholds.minFunctionStatements);
235
+ expect(opts.thresholds.minFlowStatements).toBe(DEFAULT_OPTS.thresholds.minFlowStatements);
236
+ expect(opts.thresholds.criticalComplexityThreshold).toBe(
237
+ DEFAULT_OPTS.thresholds.criticalComplexityThreshold
237
238
  );
238
239
  expect(opts.deepLinkTopN).toBe(DEFAULT_OPTS.deepLinkTopN);
239
240
  expect(opts.treeDepth).toBe(DEFAULT_OPTS.treeDepth);
@@ -260,8 +261,8 @@ describe('parseArgs', () => {
260
261
  expect(opts.graph).toBe(true);
261
262
  expect(opts.parser).toBe('typescript');
262
263
  expect(opts.findingsLimit).toBe(100);
263
- expect(opts.couplingThreshold).toBe(10);
264
- expect(opts.layerOrder).toEqual(['a', 'b', 'c']);
264
+ expect(opts.thresholds.couplingThreshold).toBe(10);
265
+ expect(opts.thresholds.layerOrder).toEqual(['a', 'b', 'c']);
265
266
  });
266
267
 
267
268
  it('sets packageRoot relative to root', () => {
@@ -282,12 +283,12 @@ describe('parseArgs', () => {
282
283
 
283
284
  it('--override-chain-threshold sets threshold', () => {
284
285
  const opts = parseArgs(['--override-chain-threshold', '5']);
285
- expect(opts.overrideChainThreshold).toBe(5);
286
+ expect(opts.thresholds.overrideChainThreshold).toBe(5);
286
287
  });
287
288
 
288
289
  it('NaN guards for semantic thresholds', () => {
289
290
  const opts = parseArgs(['--override-chain-threshold', 'xyz']);
290
- expect(opts.overrideChainThreshold).toBe(3);
291
+ expect(opts.thresholds.overrideChainThreshold).toBe(3);
291
292
  });
292
293
 
293
294
  it('--no-diversify sets noDiversify to true', () => {
@@ -360,8 +361,8 @@ describe('parseArgs', () => {
360
361
  '30',
361
362
  ]);
362
363
  expect(opts.findingsLimit).toBe(10);
363
- expect(opts.minFunctionStatements).toBe(8);
364
- expect(opts.criticalComplexityThreshold).toBe(30);
364
+ expect(opts.thresholds.minFunctionStatements).toBe(8);
365
+ expect(opts.thresholds.criticalComplexityThreshold).toBe(30);
365
366
  });
366
367
 
367
368
  it('parses --secret-entropy-threshold 4.0 and --similarity-threshold 0.9', () => {
@@ -371,16 +372,16 @@ describe('parseArgs', () => {
371
372
  '--similarity-threshold',
372
373
  '0.9',
373
374
  ]);
374
- expect(opts.secretEntropyThreshold).toBe(4);
375
- expect(opts.similarityThreshold).toBe(0.9);
375
+ expect(opts.thresholds.secretEntropyThreshold).toBe(4);
376
+ expect(opts.thresholds.similarityThreshold).toBe(0.9);
376
377
  });
377
378
 
378
379
  it('parses float flags with decimal values', () => {
379
380
  expect(
380
- parseArgs(['--secret-entropy-threshold', '5.5']).secretEntropyThreshold
381
+ parseArgs(['--secret-entropy-threshold', '5.5']).thresholds.secretEntropyThreshold
381
382
  ).toBe(5.5);
382
383
  expect(
383
- parseArgs(['--similarity-threshold', '0.75']).similarityThreshold
384
+ parseArgs(['--similarity-threshold', '0.75']).thresholds.similarityThreshold
384
385
  ).toBe(0.75);
385
386
  });
386
387
 
@@ -398,7 +399,7 @@ describe('parseArgs', () => {
398
399
  expect(opts.parser).toBe('typescript');
399
400
  expect(opts.root).toBe('/some/path');
400
401
  expect(opts.out).toBe('result.json');
401
- expect(opts.layerOrder).toEqual(['ui', 'service', 'repo']);
402
+ expect(opts.thresholds.layerOrder).toEqual(['ui', 'service', 'repo']);
402
403
  });
403
404
 
404
405
  it('parses --out=output.json form', () => {
@@ -436,6 +437,24 @@ describe('parseArgs', () => {
436
437
  }
437
438
  });
438
439
 
440
+ it('parses --scope with Windows absolute paths without splitting drive letters', () => {
441
+ const opts = parseArgs(['--scope=C:\\repo\\pkg\\src\\a.ts']);
442
+ expect(opts.scope).toBeInstanceOf(Array);
443
+ expect(opts.scope).toHaveLength(1);
444
+ expect(opts.scopeSymbols).toBeNull();
445
+ expect(opts.scope![0]).toContain('C:\\repo\\pkg\\src\\a.ts');
446
+ });
447
+
448
+ it('parses --scope with Windows absolute path and file:symbol syntax', () => {
449
+ const opts = parseArgs(['--scope=C:\\repo\\pkg\\src\\a.ts:initSession']);
450
+ expect(opts.scope).toBeInstanceOf(Array);
451
+ expect(opts.scope).toHaveLength(1);
452
+ expect(opts.scopeSymbols).toBeInstanceOf(Map);
453
+ const [filePath, symbols] = [...opts.scopeSymbols!.entries()][0];
454
+ expect(filePath).toContain('C:\\repo\\pkg\\src\\a.ts');
455
+ expect(symbols).toEqual(['initSession']);
456
+ });
457
+
439
458
  it('parses --features with pillar name architecture', () => {
440
459
  const opts = parseArgs(['--features=architecture']);
441
460
  expect(opts.features).toBeInstanceOf(Set);
@@ -472,22 +491,250 @@ describe('parseArgs', () => {
472
491
  expect(opts.includeTests).toBe(true);
473
492
  });
474
493
 
475
- it('throws when --features and --exclude are both provided', () => {
476
- const exitSpy = vi
477
- .spyOn(process, 'exit')
478
- .mockImplementation((() => {}) as never);
479
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
480
- parseArgs(['--features=architecture', '--exclude=dead-code']);
481
- expect(consoleSpy).toHaveBeenCalledWith(
482
- '--features and --exclude are mutually exclusive. Use one or the other.'
483
- );
484
- expect(exitSpy).toHaveBeenCalledWith(1);
485
- exitSpy.mockRestore();
486
- consoleSpy.mockRestore();
494
+ it('throws OptionsError when --features and --exclude are both provided', () => {
495
+ expect(() =>
496
+ parseArgs(['--features=architecture', '--exclude=dead-code'])
497
+ ).toThrow(OptionsError);
498
+ expect(() =>
499
+ parseArgs(['--features=architecture', '--exclude=dead-code'])
500
+ ).toThrow('mutually exclusive');
501
+ });
502
+
503
+ it('exports HELP_TEXT as a constant', () => {
504
+ expect(typeof HELP_TEXT).toBe('string');
505
+ expect(HELP_TEXT).toContain('--root');
506
+ expect(HELP_TEXT).toContain('--scope');
507
+ expect(HELP_TEXT).toContain('--features');
487
508
  });
488
509
 
489
510
  it('auto-enables includeTests when features include any test-quality category', () => {
490
511
  const opts = parseArgs(['--features=missing-mock-restoration']);
491
512
  expect(opts.includeTests).toBe(true);
492
513
  });
514
+
515
+ describe('Tier 1+2 flags', () => {
516
+ it('--affected defaults to HEAD', () => {
517
+ const opts = parseArgs(['--affected']);
518
+ expect(opts.affected).toBe('HEAD');
519
+ });
520
+
521
+ it('--affected accepts revision', () => {
522
+ const opts = parseArgs(['--affected', 'main']);
523
+ expect(opts.affected).toBe('main');
524
+ });
525
+
526
+ it('--affected=value inline syntax', () => {
527
+ const opts = parseArgs(['--affected=HEAD~3']);
528
+ expect(opts.affected).toBe('HEAD~3');
529
+ });
530
+
531
+ it('--save-baseline sets boolean', () => {
532
+ const opts = parseArgs(['--save-baseline']);
533
+ expect(opts.saveBaseline).toBe(true);
534
+ });
535
+
536
+ it('--ignore-known defaults to .octocode/baseline.json', () => {
537
+ const opts = parseArgs(['--ignore-known']);
538
+ expect(opts.ignoreKnown).toBe('.octocode/baseline.json');
539
+ });
540
+
541
+ it('--ignore-known accepts custom path', () => {
542
+ const opts = parseArgs(['--ignore-known', 'my-baseline.json']);
543
+ expect(opts.ignoreKnown).toBe('my-baseline.json');
544
+ });
545
+
546
+ it('--reporter accepts valid formats', () => {
547
+ expect(parseArgs(['--reporter', 'compact']).reporter).toBe('compact');
548
+ expect(parseArgs(['--reporter', 'github-actions']).reporter).toBe('github-actions');
549
+ expect(parseArgs(['--reporter', 'default']).reporter).toBe('default');
550
+ });
551
+
552
+ it('--focus sets module path', () => {
553
+ const opts = parseArgs(['--focus', 'src/session.ts']);
554
+ expect(opts.focus).toBe('src/session.ts');
555
+ });
556
+
557
+ it('--focus=value inline syntax', () => {
558
+ const opts = parseArgs(['--focus=src/session.ts']);
559
+ expect(opts.focus).toBe('src/session.ts');
560
+ });
561
+
562
+ it('--focus-depth sets depth', () => {
563
+ const opts = parseArgs(['--focus-depth', '3']);
564
+ expect(opts.focusDepth).toBe(3);
565
+ });
566
+
567
+ it('--collapse sets folder depth', () => {
568
+ const opts = parseArgs(['--collapse', '2']);
569
+ expect(opts.collapse).toBe(2);
570
+ });
571
+
572
+ it('--collapse=N inline syntax', () => {
573
+ const opts = parseArgs(['--collapse=3']);
574
+ expect(opts.collapse).toBe(3);
575
+ });
576
+
577
+ it('--at-least sets score threshold', () => {
578
+ const opts = parseArgs(['--at-least', '60']);
579
+ expect(opts.atLeast).toBe(60);
580
+ });
581
+
582
+ it('--at-least=N inline syntax', () => {
583
+ const opts = parseArgs(['--at-least=75']);
584
+ expect(opts.atLeast).toBe(75);
585
+ });
586
+
587
+ it('--config sets config file path', () => {
588
+ const opts = parseArgs(['--config', '.my-config.json']);
589
+ expect(opts.configFile).toBe('.my-config.json');
590
+ });
591
+
592
+ it('new flags have correct defaults', () => {
593
+ const opts = parseArgs([]);
594
+ expect(opts.affected).toBeNull();
595
+ expect(opts.saveBaseline).toBe(false);
596
+ expect(opts.ignoreKnown).toBeNull();
597
+ expect(opts.reporter).toBe('default');
598
+ expect(opts.focus).toBeNull();
599
+ expect(opts.focusDepth).toBe(1);
600
+ expect(opts.collapse).toBeNull();
601
+ expect(opts.atLeast).toBeNull();
602
+ expect(opts.configFile).toBeNull();
603
+ });
604
+
605
+ it('HELP_TEXT includes new flags', () => {
606
+ expect(HELP_TEXT).toContain('--affected');
607
+ expect(HELP_TEXT).toContain('--save-baseline');
608
+ expect(HELP_TEXT).toContain('--ignore-known');
609
+ expect(HELP_TEXT).toContain('--reporter');
610
+ expect(HELP_TEXT).toContain('--focus');
611
+ expect(HELP_TEXT).toContain('--focus-depth');
612
+ expect(HELP_TEXT).toContain('--collapse');
613
+ expect(HELP_TEXT).toContain('--at-least');
614
+ expect(HELP_TEXT).toContain('--config');
615
+ });
616
+
617
+ it('--affected does not consume the next flag as revision', () => {
618
+ const opts = parseArgs(['--affected', '--graph']);
619
+ expect(opts.affected).toBe('HEAD');
620
+ expect(opts.graph).toBe(true);
621
+ });
622
+
623
+ it('--ignore-known does not consume the next flag as path', () => {
624
+ const opts = parseArgs(['--ignore-known', '--graph']);
625
+ expect(opts.ignoreKnown).toBe('.octocode/baseline.json');
626
+ expect(opts.graph).toBe(true);
627
+ });
628
+ });
629
+
630
+ describe('documented common profiles parse without error', () => {
631
+ it('CI gate profile', () => {
632
+ const opts = parseArgs(['--reporter', 'github-actions', '--at-least', '60']);
633
+ expect(opts.reporter).toBe('github-actions');
634
+ expect(opts.atLeast).toBe(60);
635
+ });
636
+
637
+ it('PR diff check profile', () => {
638
+ const opts = parseArgs(['--affected', 'HEAD~1', '--reporter', 'compact']);
639
+ expect(opts.affected).toBe('HEAD~1');
640
+ expect(opts.reporter).toBe('compact');
641
+ });
642
+
643
+ it('progressive adoption save profile', () => {
644
+ const opts = parseArgs(['--save-baseline']);
645
+ expect(opts.saveBaseline).toBe(true);
646
+ });
647
+
648
+ it('progressive adoption check profile', () => {
649
+ const opts = parseArgs(['--ignore-known', '--at-least', '60']);
650
+ expect(opts.ignoreKnown).toBe('.octocode/baseline.json');
651
+ expect(opts.atLeast).toBe(60);
652
+ });
653
+
654
+ it('module zoom profile', () => {
655
+ const opts = parseArgs([
656
+ '--graph',
657
+ '--focus', 'src/session.ts',
658
+ '--focus-depth', '2',
659
+ ]);
660
+ expect(opts.graph).toBe(true);
661
+ expect(opts.focus).toBe('src/session.ts');
662
+ expect(opts.focusDepth).toBe(2);
663
+ });
664
+
665
+ it('high-level arch profile', () => {
666
+ const opts = parseArgs(['--graph', '--collapse', '2']);
667
+ expect(opts.graph).toBe(true);
668
+ expect(opts.collapse).toBe(2);
669
+ });
670
+
671
+ it('full combination profile', () => {
672
+ const opts = parseArgs([
673
+ '--affected', 'main',
674
+ '--reporter', 'compact',
675
+ '--save-baseline',
676
+ '--at-least', '70',
677
+ '--graph',
678
+ '--focus', 'src/tools',
679
+ '--focus-depth', '3',
680
+ '--config', '.my-scan.json',
681
+ ]);
682
+ expect(opts.affected).toBe('main');
683
+ expect(opts.reporter).toBe('compact');
684
+ expect(opts.saveBaseline).toBe(true);
685
+ expect(opts.atLeast).toBe(70);
686
+ expect(opts.graph).toBe(true);
687
+ expect(opts.focus).toBe('src/tools');
688
+ expect(opts.focusDepth).toBe(3);
689
+ expect(opts.configFile).toBe('.my-scan.json');
690
+ });
691
+ });
692
+
693
+ describe('v2 quality threshold flags', () => {
694
+ it('parses --deep-nesting-threshold', () => {
695
+ expect(
696
+ parseArgs(['--deep-nesting-threshold', '8']).thresholds.deepNestingThreshold
697
+ ).toBe(8);
698
+ });
699
+
700
+ it('parses --multiple-return-threshold', () => {
701
+ expect(
702
+ parseArgs(['--multiple-return-threshold', '10']).thresholds.multipleReturnThreshold
703
+ ).toBe(10);
704
+ });
705
+
706
+ it('parses --magic-string-min-occurrences', () => {
707
+ expect(
708
+ parseArgs(['--magic-string-min-occurrences', '5']).thresholds.magicStringMinOccurrences
709
+ ).toBe(5);
710
+ });
711
+
712
+ it('parses --boolean-param-threshold', () => {
713
+ expect(
714
+ parseArgs(['--boolean-param-threshold', '4']).thresholds.booleanParamThreshold
715
+ ).toBe(4);
716
+ });
717
+
718
+ it('defaults are correct for new thresholds', () => {
719
+ const opts = parseArgs([]);
720
+ expect(opts.thresholds.deepNestingThreshold).toBe(5);
721
+ expect(opts.thresholds.multipleReturnThreshold).toBe(6);
722
+ expect(opts.thresholds.magicStringMinOccurrences).toBe(3);
723
+ expect(opts.thresholds.booleanParamThreshold).toBe(3);
724
+ });
725
+
726
+ it('warns on unknown flags', () => {
727
+ const spy = vi.spyOn(console, 'warn').mockImplementation(() => {});
728
+ parseArgs(['--sematic']);
729
+ expect(spy).toHaveBeenCalledWith(expect.stringContaining('unknown flag'));
730
+ spy.mockRestore();
731
+ });
732
+
733
+ it('new threshold flags appear in HELP_TEXT', () => {
734
+ expect(HELP_TEXT).toContain('--deep-nesting-threshold');
735
+ expect(HELP_TEXT).toContain('--multiple-return-threshold');
736
+ expect(HELP_TEXT).toContain('--magic-string-min-occurrences');
737
+ expect(HELP_TEXT).toContain('--boolean-param-threshold');
738
+ });
739
+ });
493
740
  });