octocode-cli 1.2.5 → 1.2.7

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 (303) hide show
  1. package/LICENSE +21 -63
  2. package/README.md +86 -109
  3. package/out/octocode-cli.js +7027 -7014
  4. package/package.json +8 -6
  5. package/skills/README.md +97 -120
  6. package/skills/octocode-code-engineer/.claude/settings.local.json +18 -0
  7. package/skills/octocode-code-engineer/.octocode/rfc/RFC-code-engineer-weakness-fixes.md +255 -0
  8. package/skills/octocode-code-engineer/.plan/VALIDATED_PLAN.md +223 -0
  9. package/skills/octocode-code-engineer/README.md +178 -0
  10. package/skills/octocode-code-engineer/SKILL.md +418 -0
  11. package/skills/octocode-code-engineer/coverage/architecture.ts.html +7828 -0
  12. package/skills/octocode-code-engineer/coverage/ast-helpers.ts.html +211 -0
  13. package/skills/octocode-code-engineer/coverage/ast-search.ts.html +1795 -0
  14. package/skills/octocode-code-engineer/coverage/base.css +224 -0
  15. package/skills/octocode-code-engineer/coverage/block-navigation.js +87 -0
  16. package/skills/octocode-code-engineer/coverage/cache.ts.html +376 -0
  17. package/skills/octocode-code-engineer/coverage/cli.ts.html +982 -0
  18. package/skills/octocode-code-engineer/coverage/clover.xml +3217 -0
  19. package/skills/octocode-code-engineer/coverage/collect-effects.ts.html +664 -0
  20. package/skills/octocode-code-engineer/coverage/collect-input-sources.ts.html +577 -0
  21. package/skills/octocode-code-engineer/coverage/collect-performance.ts.html +331 -0
  22. package/skills/octocode-code-engineer/coverage/collect-prototype-pollution.ts.html +421 -0
  23. package/skills/octocode-code-engineer/coverage/collect-security.ts.html +604 -0
  24. package/skills/octocode-code-engineer/coverage/collect-test-profile.ts.html +589 -0
  25. package/skills/octocode-code-engineer/coverage/coverage-final.json +30 -0
  26. package/skills/octocode-code-engineer/coverage/dependencies.ts.html +997 -0
  27. package/skills/octocode-code-engineer/coverage/dependency-summary.ts.html +688 -0
  28. package/skills/octocode-code-engineer/coverage/discovery.ts.html +322 -0
  29. package/skills/octocode-code-engineer/coverage/favicon.png +0 -0
  30. package/skills/octocode-code-engineer/coverage/graph-analytics.ts.html +1510 -0
  31. package/skills/octocode-code-engineer/coverage/index.html +536 -0
  32. package/skills/octocode-code-engineer/coverage/index.ts.html +826 -0
  33. package/skills/octocode-code-engineer/coverage/metrics.ts.html +553 -0
  34. package/skills/octocode-code-engineer/coverage/pipeline.ts.html +2044 -0
  35. package/skills/octocode-code-engineer/coverage/prettify.css +1 -0
  36. package/skills/octocode-code-engineer/coverage/prettify.js +2 -0
  37. package/skills/octocode-code-engineer/coverage/report-analysis.ts.html +1570 -0
  38. package/skills/octocode-code-engineer/coverage/report-writer.ts.html +1102 -0
  39. package/skills/octocode-code-engineer/coverage/security-detectors.ts.html +1747 -0
  40. package/skills/octocode-code-engineer/coverage/semantic-detectors.ts.html +2152 -0
  41. package/skills/octocode-code-engineer/coverage/semantic.ts.html +1897 -0
  42. package/skills/octocode-code-engineer/coverage/sort-arrow-sprite.png +0 -0
  43. package/skills/octocode-code-engineer/coverage/sorter.js +210 -0
  44. package/skills/octocode-code-engineer/coverage/summary-md.ts.html +1222 -0
  45. package/skills/octocode-code-engineer/coverage/test-quality-detectors.ts.html +1039 -0
  46. package/skills/octocode-code-engineer/coverage/tree-sitter-analyzer.ts.html +955 -0
  47. package/skills/octocode-code-engineer/coverage/ts-analyzer.ts.html +1213 -0
  48. package/skills/octocode-code-engineer/coverage/types.ts.html +2473 -0
  49. package/skills/octocode-code-engineer/coverage/utils.ts.html +820 -0
  50. package/skills/octocode-code-engineer/eslint.config.mjs +54 -0
  51. package/skills/octocode-code-engineer/minify-scripts.mjs +32 -0
  52. package/skills/octocode-code-engineer/package.json +54 -0
  53. package/skills/octocode-code-engineer/references/agent-ast-reading-rfc.md +95 -0
  54. package/skills/octocode-code-engineer/references/architecture-techniques.md +121 -0
  55. package/skills/octocode-code-engineer/references/ast-search.md +210 -0
  56. package/skills/octocode-code-engineer/references/ast-tree-search.md +151 -0
  57. package/skills/octocode-code-engineer/references/cli-reference.md +167 -0
  58. package/skills/octocode-code-engineer/references/concepts.md +107 -0
  59. package/skills/octocode-code-engineer/references/finding-categories.md +128 -0
  60. package/skills/octocode-code-engineer/references/improvement-roadmap.md +304 -0
  61. package/skills/octocode-code-engineer/references/output-files.md +144 -0
  62. package/skills/octocode-code-engineer/references/playbooks.md +204 -0
  63. package/skills/octocode-code-engineer/references/present-results.md +136 -0
  64. package/skills/octocode-code-engineer/references/tool-workflows.md +566 -0
  65. package/skills/octocode-code-engineer/references/validate-investigate.md +225 -0
  66. package/skills/octocode-code-engineer/scripts/analysis/dependencies.js +1 -0
  67. package/skills/octocode-code-engineer/scripts/analysis/dependency-summary.js +1 -0
  68. package/skills/octocode-code-engineer/scripts/analysis/discovery.js +1 -0
  69. package/skills/octocode-code-engineer/scripts/analysis/graph-analytics.js +1 -0
  70. package/skills/octocode-code-engineer/scripts/analysis/semantic.js +1 -0
  71. package/skills/octocode-code-engineer/scripts/ast/helpers.js +1 -0
  72. package/skills/octocode-code-engineer/scripts/ast/metrics.js +1 -0
  73. package/skills/octocode-code-engineer/scripts/ast/search.js +2 -0
  74. package/skills/octocode-code-engineer/scripts/ast/tree-search.js +2 -0
  75. package/skills/octocode-code-engineer/scripts/ast/tree-sitter.js +1 -0
  76. package/skills/octocode-code-engineer/scripts/ast/ts-analyzer.js +1 -0
  77. package/skills/octocode-code-engineer/scripts/collectors/chains.js +1 -0
  78. package/skills/octocode-code-engineer/scripts/collectors/effects.js +1 -0
  79. package/skills/octocode-code-engineer/scripts/collectors/input-sources.js +1 -0
  80. package/skills/octocode-code-engineer/scripts/collectors/performance.js +1 -0
  81. package/skills/octocode-code-engineer/scripts/collectors/prototype-pollution.js +1 -0
  82. package/skills/octocode-code-engineer/scripts/collectors/security.js +1 -0
  83. package/skills/octocode-code-engineer/scripts/collectors/test-profile.js +1 -0
  84. package/skills/octocode-code-engineer/scripts/common/is-direct-run.js +1 -0
  85. package/skills/octocode-code-engineer/scripts/common/utils.js +1 -0
  86. package/skills/octocode-code-engineer/scripts/detectors/code-quality.js +1 -0
  87. package/skills/octocode-code-engineer/scripts/detectors/cohesion.js +1 -0
  88. package/skills/octocode-code-engineer/scripts/detectors/coupling.js +1 -0
  89. package/skills/octocode-code-engineer/scripts/detectors/cycle.js +1 -0
  90. package/skills/octocode-code-engineer/scripts/detectors/dead-code.js +1 -0
  91. package/skills/octocode-code-engineer/scripts/detectors/import-style.js +1 -0
  92. package/skills/octocode-code-engineer/scripts/detectors/index.js +1 -0
  93. package/skills/octocode-code-engineer/scripts/detectors/security.js +1 -0
  94. package/skills/octocode-code-engineer/scripts/detectors/semantic.js +1 -0
  95. package/skills/octocode-code-engineer/scripts/detectors/shared.js +1 -0
  96. package/skills/octocode-code-engineer/scripts/detectors/test-quality.js +1 -0
  97. package/skills/octocode-code-engineer/scripts/index.js +1 -0
  98. package/skills/octocode-code-engineer/scripts/pipeline/cache.js +1 -0
  99. package/skills/octocode-code-engineer/scripts/pipeline/cli.js +1 -0
  100. package/skills/octocode-code-engineer/scripts/pipeline/main.js +2 -0
  101. package/skills/octocode-code-engineer/scripts/reporting/analysis.js +1 -0
  102. package/skills/octocode-code-engineer/scripts/reporting/summary-md.js +1 -0
  103. package/skills/octocode-code-engineer/scripts/reporting/writer.js +1 -0
  104. package/skills/octocode-code-engineer/scripts/types/constants.js +1 -0
  105. package/skills/octocode-code-engineer/scripts/types/index.js +1 -0
  106. package/skills/octocode-code-engineer/scripts/types/interfaces.js +1 -0
  107. package/skills/octocode-code-engineer/src/analysis/dependencies.test.ts +545 -0
  108. package/skills/octocode-code-engineer/src/analysis/dependencies.ts +406 -0
  109. package/skills/octocode-code-engineer/src/analysis/dependency-summary.test.ts +566 -0
  110. package/skills/octocode-code-engineer/src/analysis/dependency-summary.ts +257 -0
  111. package/skills/octocode-code-engineer/src/analysis/discovery.test.ts +420 -0
  112. package/skills/octocode-code-engineer/src/analysis/discovery.ts +87 -0
  113. package/skills/octocode-code-engineer/src/analysis/graph-analytics.test.ts +449 -0
  114. package/skills/octocode-code-engineer/src/analysis/graph-analytics.ts +534 -0
  115. package/skills/octocode-code-engineer/src/analysis/semantic.test.ts +1533 -0
  116. package/skills/octocode-code-engineer/src/analysis/semantic.ts +830 -0
  117. package/skills/octocode-code-engineer/src/ast/helpers.test.ts +185 -0
  118. package/skills/octocode-code-engineer/src/ast/helpers.ts +62 -0
  119. package/skills/octocode-code-engineer/src/ast/metrics.test.ts +304 -0
  120. package/skills/octocode-code-engineer/src/ast/metrics.ts +204 -0
  121. package/skills/octocode-code-engineer/src/ast/search.test.ts +647 -0
  122. package/skills/octocode-code-engineer/src/ast/search.ts +648 -0
  123. package/skills/octocode-code-engineer/src/ast/tree-search.test.ts +199 -0
  124. package/skills/octocode-code-engineer/src/ast/tree-search.ts +392 -0
  125. package/skills/octocode-code-engineer/src/ast/tree-sitter.test.ts +407 -0
  126. package/skills/octocode-code-engineer/src/ast/tree-sitter.ts +402 -0
  127. package/skills/octocode-code-engineer/src/ast/ts-analyzer.test.ts +1864 -0
  128. package/skills/octocode-code-engineer/src/ast/ts-analyzer.ts +509 -0
  129. package/skills/octocode-code-engineer/src/collectors/chains.ts +74 -0
  130. package/skills/octocode-code-engineer/src/collectors/effects.test.ts +490 -0
  131. package/skills/octocode-code-engineer/src/collectors/effects.ts +332 -0
  132. package/skills/octocode-code-engineer/src/collectors/input-sources.test.ts +144 -0
  133. package/skills/octocode-code-engineer/src/collectors/input-sources.ts +196 -0
  134. package/skills/octocode-code-engineer/src/collectors/performance.test.ts +82 -0
  135. package/skills/octocode-code-engineer/src/collectors/performance.ts +141 -0
  136. package/skills/octocode-code-engineer/src/collectors/prototype-pollution.test.ts +55 -0
  137. package/skills/octocode-code-engineer/src/collectors/prototype-pollution.ts +162 -0
  138. package/skills/octocode-code-engineer/src/collectors/security.test.ts +124 -0
  139. package/skills/octocode-code-engineer/src/collectors/security.ts +309 -0
  140. package/skills/octocode-code-engineer/src/collectors/test-profile.test.ts +97 -0
  141. package/skills/octocode-code-engineer/src/collectors/test-profile.ts +269 -0
  142. package/skills/octocode-code-engineer/src/common/is-direct-run.test.ts +32 -0
  143. package/skills/octocode-code-engineer/src/common/is-direct-run.ts +13 -0
  144. package/skills/octocode-code-engineer/src/common/utils.test.ts +463 -0
  145. package/skills/octocode-code-engineer/src/common/utils.ts +304 -0
  146. package/skills/octocode-code-engineer/src/detectors/code-quality.ts +966 -0
  147. package/skills/octocode-code-engineer/src/detectors/cohesion.ts +539 -0
  148. package/skills/octocode-code-engineer/src/detectors/coupling.ts +323 -0
  149. package/skills/octocode-code-engineer/src/detectors/cycle.ts +349 -0
  150. package/skills/octocode-code-engineer/src/detectors/dead-code.ts +320 -0
  151. package/skills/octocode-code-engineer/src/detectors/import-style.ts +376 -0
  152. package/skills/octocode-code-engineer/src/detectors/index.test.ts +3061 -0
  153. package/skills/octocode-code-engineer/src/detectors/index.ts +88 -0
  154. package/skills/octocode-code-engineer/src/detectors/security.test.ts +882 -0
  155. package/skills/octocode-code-engineer/src/detectors/security.ts +821 -0
  156. package/skills/octocode-code-engineer/src/detectors/semantic.ts +758 -0
  157. package/skills/octocode-code-engineer/src/detectors/shared.ts +49 -0
  158. package/skills/octocode-code-engineer/src/detectors/test-quality.test.ts +388 -0
  159. package/skills/octocode-code-engineer/src/detectors/test-quality.ts +367 -0
  160. package/skills/octocode-code-engineer/src/index.test.ts +4425 -0
  161. package/skills/octocode-code-engineer/src/index.ts +403 -0
  162. package/skills/octocode-code-engineer/src/pipeline/cache.test.ts +199 -0
  163. package/skills/octocode-code-engineer/src/pipeline/cache.ts +130 -0
  164. package/skills/octocode-code-engineer/src/pipeline/cli.test.ts +493 -0
  165. package/skills/octocode-code-engineer/src/pipeline/cli.ts +344 -0
  166. package/skills/octocode-code-engineer/src/pipeline/main.test.ts +174 -0
  167. package/skills/octocode-code-engineer/src/pipeline/main.ts +1074 -0
  168. package/skills/octocode-code-engineer/src/pipeline.test.ts +84 -0
  169. package/skills/octocode-code-engineer/src/reporting/analysis.test.ts +782 -0
  170. package/skills/octocode-code-engineer/src/reporting/analysis.ts +688 -0
  171. package/skills/octocode-code-engineer/src/reporting/output-contract.test.ts +463 -0
  172. package/skills/octocode-code-engineer/src/reporting/summary-md.test.ts +421 -0
  173. package/skills/octocode-code-engineer/src/reporting/summary-md.ts +714 -0
  174. package/skills/octocode-code-engineer/src/reporting/writer.ts +430 -0
  175. package/skills/octocode-code-engineer/src/sanity.test.ts +47 -0
  176. package/skills/octocode-code-engineer/src/types/constants.ts +248 -0
  177. package/skills/octocode-code-engineer/src/types/index.ts +80 -0
  178. package/skills/octocode-code-engineer/src/types/interfaces.ts +682 -0
  179. package/skills/octocode-code-engineer/tsconfig.json +17 -0
  180. package/skills/octocode-code-engineer/vitest.config.ts +8 -0
  181. package/skills/octocode-documentation-writer/README.md +113 -0
  182. package/skills/octocode-documentation-writer/SKILL.md +886 -0
  183. package/skills/octocode-documentation-writer/references/agent-discovery-analysis.md +453 -0
  184. package/skills/octocode-documentation-writer/references/agent-documentation-writer.md +255 -0
  185. package/skills/octocode-documentation-writer/references/agent-engineer-questions.md +247 -0
  186. package/skills/octocode-documentation-writer/references/agent-orchestrator.md +370 -0
  187. package/skills/octocode-documentation-writer/references/agent-qa-validator.md +227 -0
  188. package/skills/octocode-documentation-writer/references/agent-researcher.md +250 -0
  189. package/skills/octocode-documentation-writer/schemas/analysis-schema.json +886 -0
  190. package/skills/octocode-documentation-writer/schemas/discovery-tasks.json +96 -0
  191. package/skills/octocode-documentation-writer/schemas/documentation-structure.json +373 -0
  192. package/skills/octocode-documentation-writer/schemas/partial-discovery-schema.json +102 -0
  193. package/skills/octocode-documentation-writer/schemas/partial-research-schema.json +98 -0
  194. package/skills/octocode-documentation-writer/schemas/qa-results-schema.json +113 -0
  195. package/skills/octocode-documentation-writer/schemas/questions-schema.json +228 -0
  196. package/skills/octocode-documentation-writer/schemas/research-schema.json +104 -0
  197. package/skills/octocode-documentation-writer/schemas/state-schema.json +222 -0
  198. package/skills/octocode-documentation-writer/schemas/work-assignments-schema.json +74 -0
  199. package/skills/octocode-plan/SKILL.md +122 -116
  200. package/skills/octocode-prompt-optimizer/SKILL.md +617 -0
  201. package/skills/octocode-pull-request-reviewer/README.md +249 -0
  202. package/skills/octocode-pull-request-reviewer/SKILL.md +479 -0
  203. package/skills/octocode-pull-request-reviewer/references/dependency-check.md +74 -0
  204. package/skills/octocode-pull-request-reviewer/references/domain-reviewers.md +24 -0
  205. package/skills/octocode-pull-request-reviewer/references/execution-lifecycle.md +441 -0
  206. package/skills/octocode-pull-request-reviewer/references/flow-analysis-protocol.md +64 -0
  207. package/skills/octocode-pull-request-reviewer/references/output-template.md +174 -0
  208. package/skills/octocode-pull-request-reviewer/references/parallel-agent-protocol.md +182 -0
  209. package/skills/octocode-pull-request-reviewer/references/review-guidelines.md +26 -0
  210. package/skills/octocode-pull-request-reviewer/references/verification-checklist.md +40 -0
  211. package/skills/octocode-research/.claude/settings.local.json +46 -0
  212. package/skills/octocode-research/.octocode/plan/code-review-fixes/plan.md +312 -0
  213. package/skills/octocode-research/.octocode/plan/code-review-fixes/research.md +212 -0
  214. package/skills/octocode-research/.octocode/plans/NODE_SERVER_START_PLAN.md +755 -0
  215. package/skills/octocode-research/.octocode/research/code-review/research.md +371 -0
  216. package/skills/octocode-research/.octocode/review/IMPROVEMENTS.md +391 -0
  217. package/skills/octocode-research/.octocode/review/REVIEW_PLAN.md +289 -0
  218. package/skills/octocode-research/.octocode/review/REVIEW_REPORT.md +356 -0
  219. package/skills/octocode-research/AGENTS.md +349 -0
  220. package/skills/octocode-research/README.md +494 -0
  221. package/skills/octocode-research/SKILL.md +652 -274
  222. package/skills/octocode-research/docs/API_REFERENCE.md +562 -0
  223. package/skills/octocode-research/docs/ARCHITECTURE.md +554 -0
  224. package/skills/octocode-research/docs/FLOWS.md +577 -0
  225. package/skills/octocode-research/docs/OVERVIEW.md +564 -0
  226. package/skills/octocode-research/docs/SERVER_FLOWS.md +631 -0
  227. package/skills/octocode-research/ecosystem.config.cjs +88 -0
  228. package/skills/octocode-research/eslint.config.mjs +27 -0
  229. package/skills/octocode-research/package.json +84 -0
  230. package/skills/octocode-research/references/GUARDRAILS.md +40 -0
  231. package/skills/octocode-research/references/PARALLEL_AGENT_PROTOCOL.md +178 -0
  232. package/skills/octocode-research/references/roast-prompt.md +149 -0
  233. package/skills/octocode-research/scripts/server-init.d.ts +2 -0
  234. package/skills/octocode-research/scripts/server-init.js +2 -0
  235. package/skills/octocode-research/scripts/server.d.ts +8 -0
  236. package/skills/octocode-research/scripts/server.js +445 -0
  237. package/skills/octocode-research/src/__tests__/integration/circuitBreaker.test.ts +205 -0
  238. package/skills/octocode-research/src/__tests__/integration/routes.test.ts +374 -0
  239. package/skills/octocode-research/src/__tests__/unit/circuitBreaker.test.ts +245 -0
  240. package/skills/octocode-research/src/__tests__/unit/errorHandler.test.ts +183 -0
  241. package/skills/octocode-research/src/__tests__/unit/httpPreprocess.test.ts +157 -0
  242. package/skills/octocode-research/src/__tests__/unit/logger.test.ts +143 -0
  243. package/skills/octocode-research/src/__tests__/unit/queryParser.test.ts +130 -0
  244. package/skills/octocode-research/src/__tests__/unit/responseBuilder.test.ts +469 -0
  245. package/skills/octocode-research/src/__tests__/unit/retry.test.ts +205 -0
  246. package/skills/octocode-research/src/index.ts +186 -0
  247. package/skills/octocode-research/src/mcpCache.ts +49 -0
  248. package/skills/octocode-research/src/middleware/errorHandler.ts +65 -0
  249. package/skills/octocode-research/src/middleware/logger.ts +61 -0
  250. package/skills/octocode-research/src/middleware/queryParser.ts +115 -0
  251. package/skills/octocode-research/src/middleware/readiness.ts +17 -0
  252. package/skills/octocode-research/src/routes/github.ts +197 -0
  253. package/skills/octocode-research/src/routes/local.ts +175 -0
  254. package/skills/octocode-research/src/routes/lsp.ts +177 -0
  255. package/skills/octocode-research/src/routes/package.ts +127 -0
  256. package/skills/octocode-research/src/routes/prompts.ts +138 -0
  257. package/skills/octocode-research/src/routes/tools.ts +677 -0
  258. package/skills/octocode-research/src/server-init.ts +363 -0
  259. package/skills/octocode-research/src/server.ts +285 -0
  260. package/skills/octocode-research/src/types/errorGuards.ts +151 -0
  261. package/skills/octocode-research/src/types/express.d.ts +76 -0
  262. package/skills/octocode-research/src/types/guards.ts +98 -0
  263. package/skills/octocode-research/src/types/mcp.ts +119 -0
  264. package/skills/octocode-research/src/types/responses.ts +199 -0
  265. package/skills/octocode-research/src/types/toolTypes.ts +33 -0
  266. package/skills/octocode-research/src/utils/asyncTimeout.ts +116 -0
  267. package/skills/octocode-research/src/utils/circuitBreaker.ts +492 -0
  268. package/skills/octocode-research/src/utils/colors.ts +53 -0
  269. package/skills/octocode-research/src/utils/errorQueue.ts +71 -0
  270. package/skills/octocode-research/src/utils/logEmoji.ts +103 -0
  271. package/skills/octocode-research/src/utils/logger.ts +413 -0
  272. package/skills/octocode-research/src/utils/resilience.ts +169 -0
  273. package/skills/octocode-research/src/utils/responseBuilder.ts +495 -0
  274. package/skills/octocode-research/src/utils/responseFactory.ts +100 -0
  275. package/skills/octocode-research/src/utils/responseParser.ts +272 -0
  276. package/skills/octocode-research/src/utils/retry.ts +280 -0
  277. package/skills/octocode-research/src/utils/routeFactory.ts +117 -0
  278. package/skills/octocode-research/src/utils/url.ts +20 -0
  279. package/skills/octocode-research/src/validation/httpPreprocess.ts +155 -0
  280. package/skills/octocode-research/src/validation/index.ts +2 -0
  281. package/skills/octocode-research/src/validation/schemas.ts +578 -0
  282. package/skills/octocode-research/src/validation/toolCallSchema.ts +132 -0
  283. package/skills/octocode-research/tsconfig.json +21 -0
  284. package/skills/octocode-research/tsdown.config.ts +42 -0
  285. package/skills/octocode-research/vitest.config.ts +20 -0
  286. package/skills/octocode-researcher/SKILL.md +461 -0
  287. package/skills/octocode-researcher/references/fallbacks.md +120 -0
  288. package/skills/{octocode-local-search → octocode-researcher}/references/tool-reference.md +132 -49
  289. package/skills/{octocode-local-search → octocode-researcher}/references/workflow-patterns.md +204 -4
  290. package/skills/octocode-rfc-generator/SKILL.md +223 -0
  291. package/skills/octocode-rfc-generator/references/rfc-template.md +193 -0
  292. package/skills/octocode-roast/SKILL.md +63 -21
  293. package/skills/octocode-implement/SKILL.md +0 -293
  294. package/skills/octocode-implement/references/execution-phases.md +0 -317
  295. package/skills/octocode-implement/references/tool-reference.md +0 -403
  296. package/skills/octocode-implement/references/workflow-patterns.md +0 -385
  297. package/skills/octocode-local-search/SKILL.md +0 -449
  298. package/skills/octocode-pr-review/SKILL.md +0 -391
  299. package/skills/octocode-pr-review/references/domain-reviewers.md +0 -105
  300. package/skills/octocode-pr-review/references/execution-lifecycle.md +0 -116
  301. package/skills/octocode-pr-review/references/research-flows.md +0 -75
  302. package/skills/octocode-research/references/tool-reference.md +0 -304
  303. package/skills/octocode-research/references/workflow-patterns.md +0 -325
@@ -0,0 +1,403 @@
1
+ import { isDirectRun } from './common/is-direct-run.js';
2
+ import {
3
+ buildConsumedFromModule,
4
+ computeHotFiles,
5
+ detectAwaitInLoop,
6
+ detectBarrelExplosion,
7
+ detectBoundaryViolations,
8
+ detectCognitiveComplexity,
9
+ detectCommonJsInEsm,
10
+ detectCriticalPaths,
11
+ detectDeadExports,
12
+ detectDeadFiles,
13
+ detectDeadReExports,
14
+ detectDependencyCycles,
15
+ detectDistanceFromMainSequence,
16
+ detectDuplicateFlowStructures,
17
+ detectDuplicateFunctionBodies,
18
+ detectEmptyCatchBlocks,
19
+ detectExcessiveParameters,
20
+ detectExportStarLeak,
21
+ detectFeatureEnvy,
22
+ detectFunctionOptimization,
23
+ detectGodFunctions,
24
+ detectGodModuleCoupling,
25
+ detectGodModules,
26
+ detectHighCoupling,
27
+ detectHighHalsteadEffort,
28
+ detectImportSideEffectRisk,
29
+ detectLayerViolations,
30
+ detectListenerLeakRisk,
31
+ detectLowCohesion,
32
+ detectLowMaintainability,
33
+ detectMegaFolders,
34
+ detectMessageChains,
35
+ detectMissingErrorBoundary,
36
+ detectNamespaceImport,
37
+ detectOrphanModules,
38
+ detectPromiseMisuse,
39
+ detectSdpViolations,
40
+ detectSimilarFunctionBodies,
41
+ detectSwitchNoDefault,
42
+ detectSyncIo,
43
+ detectTestOnlyModules,
44
+ detectTypeAssertionEscape,
45
+ detectUnboundedCollection,
46
+ detectUnclearedTimers,
47
+ detectUnreachableModules,
48
+ detectUnsafeAny,
49
+ detectUntestedCriticalCode,
50
+ detectUnusedNpmDeps,
51
+ } from './detectors/index.js';
52
+ import {
53
+ detectCommandInjectionRisk,
54
+ detectDebugLogLeakage,
55
+ detectEvalUsage,
56
+ detectHardcodedSecrets,
57
+ detectInputPassthroughRisk,
58
+ detectPathTraversalRisk,
59
+ detectPrototypePollutionRisk,
60
+ detectSensitiveDataLogging,
61
+ detectSqlInjectionRisk,
62
+ detectUnsafeHtml,
63
+ detectUnsafeRegex,
64
+ detectUnvalidatedInputSink,
65
+ } from './detectors/security.js';
66
+ import {
67
+ detectExcessiveMocking,
68
+ detectFakeTimersWithoutRestore,
69
+ detectFocusedTests,
70
+ detectLowAssertionDensity,
71
+ detectMissingMockRestoration,
72
+ detectMissingTestCleanup,
73
+ detectSharedMutableState,
74
+ detectTestNoAssertion,
75
+ } from './detectors/test-quality.js';
76
+ import { diversifyFindings } from './reporting/summary-md.js';
77
+ import { SEVERITY_ORDER } from './types/index.js';
78
+
79
+ import type {
80
+ AnalysisOptions,
81
+ DependencyState,
82
+ DependencySummary,
83
+ DuplicateGroup,
84
+ FileCriticality,
85
+ FileEntry,
86
+ Finding,
87
+ FlowMapEntry,
88
+ RedundantFlowGroup,
89
+ } from './types/index.js';
90
+
91
+ export {
92
+ buildDependencySummary,
93
+ computeDependencyCycles,
94
+ computeDependencyCriticalPaths,
95
+ } from './analysis/dependency-summary.js';
96
+ export {
97
+ REPORT_SCHEMA_VERSION,
98
+ ARCHITECTURE_CATEGORIES,
99
+ CODE_QUALITY_CATEGORIES,
100
+ DEAD_CODE_CATEGORIES,
101
+ SECURITY_CATEGORIES,
102
+ TEST_QUALITY_CATEGORIES,
103
+ writeMultiFileReport,
104
+ generateMermaidGraph,
105
+ } from './reporting/writer.js';
106
+ export type { FullReport } from './reporting/writer.js';
107
+ export {
108
+ severityBreakdown,
109
+ categoryBreakdown,
110
+ computeHealthScore,
111
+ collectTagCloud,
112
+ formatFileSize,
113
+ diversifyFindings,
114
+ diverseTopRecommendations,
115
+ generateSummaryMd,
116
+ } from './reporting/summary-md.js';
117
+ export type { SummaryMdOptions } from './reporting/summary-md.js';
118
+
119
+ export function buildIssueCatalog(
120
+ duplicates: DuplicateGroup[],
121
+ controlDuplicates: RedundantFlowGroup[],
122
+ fileSummaries: FileEntry[],
123
+ dependencySummary: DependencySummary,
124
+ dependencyState: DependencyState,
125
+ options: AnalysisOptions,
126
+ pkgJsonDeps: Record<string, string> = {},
127
+ pkgJsonDevDeps: Record<string, string> = {},
128
+ fileCriticalityByPath: Map<string, FileCriticality> = new Map(),
129
+ semanticFindings: Array<Omit<Finding, 'id'>> = [],
130
+ flowMap: Map<string, FlowMapEntry[]> = new Map(),
131
+ additionalFindings: Array<Omit<Finding, 'id'>> = []
132
+ ): {
133
+ allFindings: Array<Omit<Finding, 'id'>>;
134
+ findings: Finding[];
135
+ byFile: Map<string, string[]>;
136
+ totalBeforeTruncation: number;
137
+ droppedCategories: string[];
138
+ } {
139
+ const rawFindings: Array<Omit<Finding, 'id'>> = [];
140
+
141
+ const addFinding = (finding: Omit<Finding, 'id'>): void => {
142
+ if (options.features && !options.features.has(finding.category)) return;
143
+ rawFindings.push(finding);
144
+ };
145
+
146
+ const { production: consumedFromModule, test: testConsumedFromModule } =
147
+ buildConsumedFromModule(dependencyState);
148
+
149
+ for (const f of detectDuplicateFunctionBodies(duplicates)) addFinding(f);
150
+ for (const f of detectDuplicateFlowStructures(
151
+ controlDuplicates,
152
+ options.flowDupThreshold
153
+ ))
154
+ addFinding(f);
155
+ for (const f of detectFunctionOptimization(
156
+ fileSummaries,
157
+ options.criticalComplexityThreshold
158
+ ))
159
+ addFinding(f);
160
+ for (const f of detectTestOnlyModules(dependencySummary)) addFinding(f);
161
+ for (const f of detectDependencyCycles(dependencySummary, dependencyState))
162
+ addFinding(f);
163
+ for (const f of detectCriticalPaths(
164
+ dependencySummary,
165
+ dependencyState,
166
+ options.criticalComplexityThreshold
167
+ ))
168
+ addFinding(f);
169
+ for (const f of detectDeadFiles(dependencySummary, dependencyState))
170
+ addFinding(f);
171
+ for (const f of detectDeadExports(
172
+ dependencyState,
173
+ consumedFromModule,
174
+ testConsumedFromModule
175
+ ))
176
+ addFinding(f);
177
+ for (const f of detectDeadReExports(dependencyState, consumedFromModule))
178
+ addFinding(f);
179
+ for (const f of detectSdpViolations(
180
+ dependencyState,
181
+ options.sdpMinDelta,
182
+ options.sdpMaxSourceInstability
183
+ ))
184
+ addFinding(f);
185
+ for (const f of detectHighCoupling(
186
+ dependencyState,
187
+ options.couplingThreshold
188
+ ))
189
+ addFinding(f);
190
+ for (const f of detectGodModuleCoupling(
191
+ dependencyState,
192
+ options.fanInThreshold,
193
+ options.fanOutThreshold
194
+ ))
195
+ addFinding(f);
196
+ for (const f of detectOrphanModules(dependencyState)) addFinding(f);
197
+ for (const f of detectUnreachableModules(dependencyState)) addFinding(f);
198
+
199
+ for (const f of detectUnusedNpmDeps(
200
+ dependencyState.externalCounts,
201
+ pkgJsonDeps,
202
+ pkgJsonDevDeps
203
+ ))
204
+ addFinding(f);
205
+ for (const f of detectBoundaryViolations(dependencyState)) addFinding(f);
206
+ for (const f of detectBarrelExplosion(
207
+ dependencyState,
208
+ options.barrelSymbolThreshold
209
+ ))
210
+ addFinding(f);
211
+ for (const f of detectGodModules(
212
+ fileSummaries,
213
+ dependencyState,
214
+ options.godModuleStatements,
215
+ options.godModuleExports
216
+ ))
217
+ addFinding(f);
218
+ for (const f of detectMegaFolders(fileSummaries)) addFinding(f);
219
+ for (const f of detectGodFunctions(
220
+ fileSummaries,
221
+ options.godFunctionStatements,
222
+ options.godFunctionMiThreshold
223
+ ))
224
+ addFinding(f);
225
+ for (const f of detectCognitiveComplexity(
226
+ fileSummaries,
227
+ options.cognitiveComplexityThreshold
228
+ ))
229
+ addFinding(f);
230
+ if (options.layerOrder.length >= 2) {
231
+ for (const f of detectLayerViolations(dependencyState, options.layerOrder))
232
+ addFinding(f);
233
+ }
234
+ for (const f of detectLowCohesion(dependencyState)) addFinding(f);
235
+ for (const f of detectDistanceFromMainSequence(dependencyState))
236
+ addFinding(f);
237
+ for (const f of detectFeatureEnvy(dependencyState)) addFinding(f);
238
+
239
+ const hotFilesForDetector = computeHotFiles(
240
+ dependencyState,
241
+ dependencySummary,
242
+ fileCriticalityByPath
243
+ );
244
+ for (const f of detectUntestedCriticalCode(
245
+ dependencyState,
246
+ hotFilesForDetector,
247
+ fileCriticalityByPath
248
+ ))
249
+ addFinding(f);
250
+
251
+ for (const f of detectImportSideEffectRisk(
252
+ fileSummaries,
253
+ dependencyState,
254
+ dependencySummary,
255
+ hotFilesForDetector
256
+ ))
257
+ addFinding(f);
258
+
259
+ for (const f of detectNamespaceImport(dependencyState)) addFinding(f);
260
+ for (const f of detectCommonJsInEsm(dependencyState)) addFinding(f);
261
+ for (const f of detectExportStarLeak(dependencyState)) addFinding(f);
262
+
263
+ for (const f of detectExcessiveParameters(
264
+ fileSummaries,
265
+ options.parameterThreshold
266
+ ))
267
+ addFinding(f);
268
+ for (const f of detectEmptyCatchBlocks(fileSummaries)) addFinding(f);
269
+ for (const f of detectSwitchNoDefault(fileSummaries)) addFinding(f);
270
+ for (const f of detectUnsafeAny(fileSummaries, options.anyThreshold))
271
+ addFinding(f);
272
+ for (const f of detectHighHalsteadEffort(
273
+ fileSummaries,
274
+ options.halsteadEffortThreshold
275
+ ))
276
+ addFinding(f);
277
+ for (const f of detectLowMaintainability(
278
+ fileSummaries,
279
+ options.maintainabilityIndexThreshold
280
+ ))
281
+ addFinding(f);
282
+ for (const f of detectTypeAssertionEscape(fileSummaries)) addFinding(f);
283
+ for (const f of detectMissingErrorBoundary(fileSummaries)) addFinding(f);
284
+ for (const f of detectPromiseMisuse(fileSummaries)) addFinding(f);
285
+
286
+ for (const f of detectAwaitInLoop(fileSummaries)) addFinding(f);
287
+ for (const f of detectSyncIo(fileSummaries)) addFinding(f);
288
+ for (const f of detectUnclearedTimers(fileSummaries)) addFinding(f);
289
+ for (const f of detectListenerLeakRisk(fileSummaries)) addFinding(f);
290
+ for (const f of detectUnboundedCollection(fileSummaries)) addFinding(f);
291
+ for (const f of detectMessageChains(fileSummaries)) addFinding(f);
292
+ for (const f of detectSimilarFunctionBodies(
293
+ flowMap,
294
+ options.similarityThreshold
295
+ ))
296
+ addFinding(f);
297
+
298
+ for (const f of detectHardcodedSecrets(fileSummaries)) addFinding(f);
299
+ for (const f of detectEvalUsage(fileSummaries)) addFinding(f);
300
+ for (const f of detectUnsafeHtml(fileSummaries)) addFinding(f);
301
+ for (const f of detectSqlInjectionRisk(fileSummaries)) addFinding(f);
302
+ for (const f of detectUnsafeRegex(fileSummaries)) addFinding(f);
303
+ for (const f of detectUnvalidatedInputSink(fileSummaries)) addFinding(f);
304
+ for (const f of detectInputPassthroughRisk(fileSummaries)) addFinding(f);
305
+ for (const f of detectPrototypePollutionRisk(fileSummaries)) addFinding(f);
306
+ for (const f of detectPathTraversalRisk(fileSummaries)) addFinding(f);
307
+ for (const f of detectCommandInjectionRisk(fileSummaries)) addFinding(f);
308
+ for (const f of detectDebugLogLeakage(fileSummaries)) addFinding(f);
309
+ for (const f of detectSensitiveDataLogging(fileSummaries)) addFinding(f);
310
+
311
+ for (const f of detectLowAssertionDensity(fileSummaries)) addFinding(f);
312
+ for (const f of detectTestNoAssertion(fileSummaries)) addFinding(f);
313
+ for (const f of detectExcessiveMocking(fileSummaries, options.mockThreshold))
314
+ addFinding(f);
315
+ for (const f of detectSharedMutableState(fileSummaries)) addFinding(f);
316
+ for (const f of detectMissingTestCleanup(fileSummaries)) addFinding(f);
317
+ for (const f of detectFocusedTests(fileSummaries)) addFinding(f);
318
+ for (const f of detectFakeTimersWithoutRestore(fileSummaries)) addFinding(f);
319
+ for (const f of detectMissingMockRestoration(fileSummaries)) addFinding(f);
320
+
321
+ for (const f of semanticFindings) addFinding(f);
322
+ for (const f of additionalFindings) addFinding(f);
323
+
324
+ const sorted = rawFindings.sort((a, b) => {
325
+ const bySeverity = SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity];
326
+ if (bySeverity !== 0) return bySeverity;
327
+ if (a.category < b.category) return -1;
328
+ if (a.category > b.category) return 1;
329
+ return 0;
330
+ });
331
+
332
+ const { findings: truncated, totalBeforeTruncation, droppedCategories } =
333
+ applyFindingsLimit(sorted, options);
334
+ const { findings, byFile } = assignFindingIds(truncated);
335
+
336
+ return {
337
+ allFindings: sorted,
338
+ findings,
339
+ byFile,
340
+ totalBeforeTruncation,
341
+ droppedCategories,
342
+ };
343
+ }
344
+
345
+ export function applyFindingsLimit<T extends Omit<Finding, 'id'>>(
346
+ sorted: T[],
347
+ options: Pick<AnalysisOptions, 'findingsLimit' | 'noDiversify'>
348
+ ): {
349
+ findings: T[];
350
+ totalBeforeTruncation: number;
351
+ droppedCategories: string[];
352
+ } {
353
+ const totalBeforeTruncation = sorted.length;
354
+ const allCategoriesBefore = new Set(sorted.map(f => f.category));
355
+ const limit = options.findingsLimit;
356
+ const truncated =
357
+ !Number.isFinite(limit) || limit == null
358
+ ? sorted
359
+ : options.noDiversify
360
+ ? sorted.slice(0, limit)
361
+ : diversifyFindings(sorted, limit);
362
+ const categoriesAfter = new Set(truncated.map(f => f.category));
363
+ const droppedCategories = [...allCategoriesBefore].filter(
364
+ c => !categoriesAfter.has(c)
365
+ );
366
+
367
+ return {
368
+ findings: truncated,
369
+ totalBeforeTruncation,
370
+ droppedCategories,
371
+ };
372
+ }
373
+
374
+ export function assignFindingIds(
375
+ rawFindings: Array<Omit<Finding, 'id'>>
376
+ ): {
377
+ findings: Finding[];
378
+ byFile: Map<string, string[]>;
379
+ } {
380
+ const findings: Finding[] = [];
381
+ const byFile = new Map<string, string[]>();
382
+
383
+ for (const [i, raw] of rawFindings.entries()) {
384
+ const id = `AST-ISSUE-${String(i + 1).padStart(4, '0')}`;
385
+ const full: Finding = { id, ...raw };
386
+ findings.push(full);
387
+ if (full.file) {
388
+ if (!byFile.has(full.file)) byFile.set(full.file, []);
389
+ byFile.get(full.file)!.push(id);
390
+ }
391
+ }
392
+
393
+ return { findings, byFile };
394
+ }
395
+
396
+ if (isDirectRun(import.meta.url)) {
397
+ import('./pipeline/main.js')
398
+ .then(m => m.main())
399
+ .catch((error: unknown) => {
400
+ console.error(error);
401
+ process.exit(1);
402
+ });
403
+ }
@@ -0,0 +1,199 @@
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+
5
+ import { beforeEach, describe, expect, it } from 'vitest';
6
+
7
+ import {
8
+ ANALYSIS_SCHEMA_VERSION,
9
+ clearCache,
10
+ createEmptyCache,
11
+ garbageCollect,
12
+ getCachedResult,
13
+ isCacheHit,
14
+ loadCache,
15
+ saveCache,
16
+ setCacheEntry,
17
+ } from './cache.js';
18
+
19
+ describe('cache', () => {
20
+ let tmpDir: string;
21
+
22
+ beforeEach(() => {
23
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cache-test-'));
24
+ });
25
+
26
+ describe('createEmptyCache', () => {
27
+ it('includes schemaVersion', () => {
28
+ const cache = createEmptyCache('/test');
29
+ expect(cache.schemaVersion).toBe(ANALYSIS_SCHEMA_VERSION);
30
+ expect(cache.version).toBe(1);
31
+ expect(cache.root).toBe('/test');
32
+ expect(cache.entries).toEqual({});
33
+ });
34
+ });
35
+
36
+ describe('loadCache', () => {
37
+ it('returns null for schema version mismatch', () => {
38
+ const cache = createEmptyCache(tmpDir);
39
+ saveCache(tmpDir, cache);
40
+
41
+ const cachePath = path.join(
42
+ tmpDir,
43
+ '.octocode',
44
+ 'scan',
45
+ '.cache',
46
+ 'analysis-cache.json'
47
+ );
48
+ const data = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
49
+ data.schemaVersion = '0.0.0';
50
+ fs.writeFileSync(cachePath, JSON.stringify(data), 'utf8');
51
+
52
+ expect(loadCache(tmpDir)).toBeNull();
53
+ });
54
+
55
+ it('returns null for version mismatch', () => {
56
+ const cache = createEmptyCache(tmpDir);
57
+ saveCache(tmpDir, cache);
58
+
59
+ const cachePath = path.join(
60
+ tmpDir,
61
+ '.octocode',
62
+ 'scan',
63
+ '.cache',
64
+ 'analysis-cache.json'
65
+ );
66
+ const data = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
67
+ data.version = 999;
68
+ fs.writeFileSync(cachePath, JSON.stringify(data), 'utf8');
69
+
70
+ expect(loadCache(tmpDir)).toBeNull();
71
+ });
72
+
73
+ it('returns null for root mismatch', () => {
74
+ const cache = createEmptyCache('/a');
75
+ saveCache(tmpDir, cache);
76
+
77
+ expect(loadCache('/b')).toBeNull();
78
+ });
79
+
80
+ it('returns valid cache', () => {
81
+ const cache = createEmptyCache(tmpDir);
82
+ setCacheEntry(
83
+ cache,
84
+ 'file.ts',
85
+ { mtimeMs: 100, size: 50 },
86
+ { issues: [] }
87
+ );
88
+ saveCache(tmpDir, cache);
89
+
90
+ const loaded = loadCache(tmpDir);
91
+ expect(loaded).not.toBeNull();
92
+ expect(loaded!.root).toBe(tmpDir);
93
+ expect(loaded!.schemaVersion).toBe(ANALYSIS_SCHEMA_VERSION);
94
+ expect(loaded!.entries['file.ts'].result).toEqual({ issues: [] });
95
+ });
96
+ });
97
+
98
+ describe('setCacheEntry', () => {
99
+ it('sets lastAccessMs', () => {
100
+ const cache = createEmptyCache('/test');
101
+ const before = Date.now();
102
+ setCacheEntry(cache, 'a.ts', { mtimeMs: 1, size: 100 }, {});
103
+ const after = Date.now();
104
+
105
+ const entry = cache.entries['a.ts'];
106
+ expect(entry.lastAccessMs).toBeGreaterThanOrEqual(before);
107
+ expect(entry.lastAccessMs).toBeLessThanOrEqual(after);
108
+ });
109
+ });
110
+
111
+ describe('getCachedResult', () => {
112
+ it('refreshes lastAccessMs on read', () => {
113
+ const cache = createEmptyCache('/test');
114
+ setCacheEntry(cache, 'b.ts', { mtimeMs: 2, size: 200 }, { data: 1 });
115
+
116
+ cache.entries['b.ts'].lastAccessMs = 1000;
117
+
118
+ const before = Date.now();
119
+ const result = getCachedResult(cache, 'b.ts');
120
+ const after = Date.now();
121
+
122
+ expect(result).toEqual({ data: 1 });
123
+ expect(cache.entries['b.ts'].lastAccessMs).toBeGreaterThanOrEqual(before);
124
+ expect(cache.entries['b.ts'].lastAccessMs).toBeLessThanOrEqual(after);
125
+ });
126
+
127
+ it('returns undefined for missing entry', () => {
128
+ const cache = createEmptyCache('/test');
129
+ expect(getCachedResult(cache, 'missing.ts')).toBeUndefined();
130
+ });
131
+ });
132
+
133
+ describe('garbageCollect', () => {
134
+ it('removes old entries and keeps recent ones', () => {
135
+ const cache = createEmptyCache('/test');
136
+ setCacheEntry(cache, 'old.ts', { mtimeMs: 1, size: 100 }, {});
137
+ cache.entries['old.ts'].lastAccessMs =
138
+ Date.now() - 8 * 24 * 60 * 60 * 1000;
139
+
140
+ setCacheEntry(cache, 'recent.ts', { mtimeMs: 2, size: 200 }, {});
141
+
142
+ const removed = garbageCollect(cache);
143
+ expect(removed).toBe(1);
144
+ expect(cache.entries['old.ts']).toBeUndefined();
145
+ expect(cache.entries['recent.ts']).toBeDefined();
146
+ });
147
+
148
+ it('returns 0 when no entries are expired', () => {
149
+ const cache = createEmptyCache('/test');
150
+ setCacheEntry(cache, 'a.ts', { mtimeMs: 1, size: 100 }, {});
151
+ setCacheEntry(cache, 'b.ts', { mtimeMs: 2, size: 200 }, {});
152
+
153
+ const removed = garbageCollect(cache);
154
+ expect(removed).toBe(0);
155
+ expect(Object.keys(cache.entries)).toHaveLength(2);
156
+ });
157
+ });
158
+
159
+ describe('isCacheHit', () => {
160
+ it('returns true when mtime and size match', () => {
161
+ const cache = createEmptyCache('/test');
162
+ setCacheEntry(cache, 'x.ts', { mtimeMs: 10, size: 50 }, {});
163
+ expect(isCacheHit(cache, 'x.ts', { mtimeMs: 10, size: 50 })).toBe(true);
164
+ });
165
+
166
+ it('returns false when mtime differs', () => {
167
+ const cache = createEmptyCache('/test');
168
+ setCacheEntry(cache, 'x.ts', { mtimeMs: 10, size: 50 }, {});
169
+ expect(isCacheHit(cache, 'x.ts', { mtimeMs: 99, size: 50 })).toBe(false);
170
+ });
171
+
172
+ it('returns false for null cache', () => {
173
+ expect(isCacheHit(null, 'x.ts', { mtimeMs: 10, size: 50 })).toBe(false);
174
+ });
175
+ });
176
+
177
+ describe('clearCache', () => {
178
+ it('removes the cache file', () => {
179
+ const cache = createEmptyCache(tmpDir);
180
+ saveCache(tmpDir, cache);
181
+
182
+ const cachePath = path.join(
183
+ tmpDir,
184
+ '.octocode',
185
+ 'scan',
186
+ '.cache',
187
+ 'analysis-cache.json'
188
+ );
189
+ expect(fs.existsSync(cachePath)).toBe(true);
190
+
191
+ clearCache(tmpDir);
192
+ expect(fs.existsSync(cachePath)).toBe(false);
193
+ });
194
+
195
+ it('does not throw if cache file does not exist', () => {
196
+ expect(() => clearCache(tmpDir)).not.toThrow();
197
+ });
198
+ });
199
+ });