octocode-cli 1.2.6 → 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 +85 -142
  3. package/out/octocode-cli.js +7026 -6945
  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,245 @@
1
+ /**
2
+ * Unit tests for circuit breaker utilities.
3
+ *
4
+ * @module tests/unit/circuitBreaker
5
+ */
6
+
7
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
8
+ import {
9
+ withCircuitBreaker,
10
+ getCircuitState,
11
+ resetCircuit,
12
+ configureCircuit,
13
+ CircuitOpenError,
14
+ getAllCircuitStates,
15
+ } from '../../utils/circuitBreaker.js';
16
+
17
+ describe('withCircuitBreaker', () => {
18
+ beforeEach(() => {
19
+ // Reset test circuit before each test
20
+ resetCircuit('test');
21
+ vi.useFakeTimers();
22
+ });
23
+
24
+ afterEach(() => {
25
+ vi.useRealTimers();
26
+ });
27
+
28
+ it('executes operation successfully when circuit is closed', async () => {
29
+ const operation = vi.fn().mockResolvedValue('success');
30
+
31
+ const result = await withCircuitBreaker('test', operation);
32
+
33
+ expect(result).toBe('success');
34
+ expect(operation).toHaveBeenCalledTimes(1);
35
+ expect(getCircuitState('test').state).toBe('closed');
36
+ });
37
+
38
+ it('opens circuit after failure threshold', async () => {
39
+ configureCircuit('test', { failureThreshold: 3 });
40
+ const operation = vi.fn().mockRejectedValue(new Error('fail'));
41
+
42
+ // First 3 failures should open the circuit
43
+ for (let i = 0; i < 3; i++) {
44
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow('fail');
45
+ }
46
+
47
+ expect(getCircuitState('test').state).toBe('open');
48
+ });
49
+
50
+ it('uses fallback when circuit is open', async () => {
51
+ configureCircuit('test', { failureThreshold: 1, resetTimeoutMs: 10000 });
52
+ const operation = vi.fn().mockRejectedValue(new Error('fail'));
53
+ const fallback = vi.fn().mockReturnValue('fallback');
54
+
55
+ // Open the circuit
56
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
57
+
58
+ // Should use fallback
59
+ const result = await withCircuitBreaker('test', operation, fallback);
60
+
61
+ expect(result).toBe('fallback');
62
+ expect(fallback).toHaveBeenCalled();
63
+ });
64
+
65
+ it('throws CircuitOpenError when open and no fallback', async () => {
66
+ configureCircuit('test', { failureThreshold: 1, resetTimeoutMs: 10000 });
67
+ const operation = vi.fn().mockRejectedValue(new Error('fail'));
68
+
69
+ // Open the circuit
70
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
71
+
72
+ // Should throw CircuitOpenError
73
+ await expect(withCircuitBreaker('test', operation)).rejects.toBeInstanceOf(
74
+ CircuitOpenError
75
+ );
76
+ });
77
+
78
+ it('enters half-open state after reset timeout', async () => {
79
+ configureCircuit('test', { failureThreshold: 1, resetTimeoutMs: 1000 });
80
+ const operation = vi
81
+ .fn()
82
+ .mockRejectedValueOnce(new Error('fail'))
83
+ .mockResolvedValue('success');
84
+
85
+ // Open the circuit
86
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
87
+ expect(getCircuitState('test').state).toBe('open');
88
+
89
+ // Advance time past reset timeout
90
+ vi.advanceTimersByTime(1001);
91
+
92
+ // Next attempt should try (half-open)
93
+ const result = await withCircuitBreaker('test', operation);
94
+ expect(result).toBe('success');
95
+ });
96
+
97
+ it('closes circuit after success threshold in half-open', async () => {
98
+ configureCircuit('test', {
99
+ failureThreshold: 1,
100
+ successThreshold: 2,
101
+ resetTimeoutMs: 1000,
102
+ });
103
+
104
+ const failOp = vi.fn().mockRejectedValue(new Error('fail'));
105
+ const successOp = vi.fn().mockResolvedValue('success');
106
+
107
+ // Open the circuit
108
+ await expect(withCircuitBreaker('test', failOp)).rejects.toThrow();
109
+
110
+ // Advance time to half-open
111
+ vi.advanceTimersByTime(1001);
112
+
113
+ // First success - still half-open
114
+ await withCircuitBreaker('test', successOp);
115
+ expect(getCircuitState('test').state).toBe('half-open');
116
+
117
+ // Second success - should close
118
+ await withCircuitBreaker('test', successOp);
119
+ expect(getCircuitState('test').state).toBe('closed');
120
+ });
121
+
122
+ it('reopens circuit if half-open attempt fails', async () => {
123
+ configureCircuit('test', { failureThreshold: 1, resetTimeoutMs: 1000 });
124
+
125
+ const operation = vi.fn().mockRejectedValue(new Error('fail'));
126
+
127
+ // Open the circuit
128
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
129
+
130
+ // Advance time to half-open
131
+ vi.advanceTimersByTime(1001);
132
+
133
+ // Fail in half-open - should go back to open
134
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
135
+ expect(getCircuitState('test').state).toBe('open');
136
+ });
137
+
138
+ it('resets failures on success in closed state', async () => {
139
+ configureCircuit('test', { failureThreshold: 3 });
140
+
141
+ const failOp = vi.fn().mockRejectedValue(new Error('fail'));
142
+ const successOp = vi.fn().mockResolvedValue('success');
143
+
144
+ // 2 failures
145
+ await expect(withCircuitBreaker('test', failOp)).rejects.toThrow();
146
+ await expect(withCircuitBreaker('test', failOp)).rejects.toThrow();
147
+ expect(getCircuitState('test').failures).toBe(2);
148
+
149
+ // 1 success resets failures
150
+ await withCircuitBreaker('test', successOp);
151
+ expect(getCircuitState('test').failures).toBe(0);
152
+
153
+ // Still closed
154
+ expect(getCircuitState('test').state).toBe('closed');
155
+ });
156
+ });
157
+
158
+ describe('getCircuitState', () => {
159
+ beforeEach(() => {
160
+ resetCircuit('test');
161
+ });
162
+
163
+ it('returns initial state for new circuit', () => {
164
+ const state = getCircuitState('new-circuit');
165
+
166
+ expect(state.state).toBe('closed');
167
+ expect(state.failures).toBe(0);
168
+ expect(state.isHealthy).toBe(true);
169
+ });
170
+
171
+ it('returns accurate failure count', async () => {
172
+ configureCircuit('test', { failureThreshold: 5 });
173
+ const operation = vi.fn().mockRejectedValue(new Error('fail'));
174
+
175
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
176
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
177
+
178
+ const state = getCircuitState('test');
179
+ expect(state.failures).toBe(2);
180
+ });
181
+
182
+ it('reports unhealthy when circuit is open', async () => {
183
+ configureCircuit('test', { failureThreshold: 1 });
184
+ const operation = vi.fn().mockRejectedValue(new Error('fail'));
185
+
186
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
187
+
188
+ const state = getCircuitState('test');
189
+ expect(state.isHealthy).toBe(false);
190
+ });
191
+ });
192
+
193
+ describe('resetCircuit', () => {
194
+ it('resets circuit to closed state', async () => {
195
+ configureCircuit('test', { failureThreshold: 1 });
196
+ const operation = vi.fn().mockRejectedValue(new Error('fail'));
197
+
198
+ // Open the circuit
199
+ await expect(withCircuitBreaker('test', operation)).rejects.toThrow();
200
+ expect(getCircuitState('test').state).toBe('open');
201
+
202
+ // Reset
203
+ resetCircuit('test');
204
+
205
+ expect(getCircuitState('test').state).toBe('closed');
206
+ expect(getCircuitState('test').failures).toBe(0);
207
+ });
208
+ });
209
+
210
+ describe('getAllCircuitStates', () => {
211
+ beforeEach(() => {
212
+ resetCircuit('circuit-a');
213
+ resetCircuit('circuit-b');
214
+ });
215
+
216
+ it('returns states for all known circuits', async () => {
217
+ configureCircuit('circuit-a', { failureThreshold: 1 });
218
+ const failOp = vi.fn().mockRejectedValue(new Error('fail'));
219
+ const successOp = vi.fn().mockResolvedValue('success');
220
+
221
+ // Open circuit-a
222
+ await expect(withCircuitBreaker('circuit-a', failOp)).rejects.toThrow();
223
+
224
+ // Keep circuit-b closed
225
+ await withCircuitBreaker('circuit-b', successOp);
226
+
227
+ const states = getAllCircuitStates();
228
+
229
+ expect(states['circuit-a'].state).toBe('open');
230
+ expect(states['circuit-a'].isHealthy).toBe(false);
231
+ expect(states['circuit-b'].state).toBe('closed');
232
+ expect(states['circuit-b'].isHealthy).toBe(true);
233
+ });
234
+ });
235
+
236
+ describe('CircuitOpenError', () => {
237
+ it('contains circuit name and retry info', () => {
238
+ const error = new CircuitOpenError('test', 5000);
239
+
240
+ expect(error.circuitName).toBe('test');
241
+ expect(error.retryAfterMs).toBe(5000);
242
+ expect(error.message).toContain('test');
243
+ expect(error.message).toContain('5s');
244
+ });
245
+ });
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Unit tests for error handler middleware.
3
+ *
4
+ * @module tests/unit/errorHandler
5
+ */
6
+
7
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
8
+ import type { Request, Response, NextFunction } from 'express';
9
+ import { errorHandler, type ApiError } from '../../middleware/errorHandler.js';
10
+ import type { z } from 'zod/v4';
11
+ import { fireAndForgetWithTimeout } from '../../utils/asyncTimeout.js';
12
+
13
+ // Mock the logger
14
+ vi.mock('../../utils/logger.js', () => ({
15
+ logError: vi.fn(),
16
+ logWarn: vi.fn(),
17
+ sanitizeQueryParams: vi.fn((q) => q),
18
+ }));
19
+
20
+ // Mock the session error logging
21
+ vi.mock('../../index.js', () => ({
22
+ logSessionError: vi.fn().mockResolvedValue(undefined),
23
+ }));
24
+
25
+ // Mock the async timeout
26
+ vi.mock('../../utils/asyncTimeout.js', () => ({
27
+ fireAndForgetWithTimeout: vi.fn(),
28
+ }));
29
+
30
+ describe('errorHandler', () => {
31
+ let mockReq: Partial<Request>;
32
+ let mockRes: Partial<Response>;
33
+ let mockNext: NextFunction;
34
+ let jsonMock: ReturnType<typeof vi.fn>;
35
+ let statusMock: ReturnType<typeof vi.fn>;
36
+
37
+ beforeEach(() => {
38
+ jsonMock = vi.fn();
39
+ statusMock = vi.fn().mockReturnValue({ json: jsonMock });
40
+
41
+ mockReq = {
42
+ method: 'POST',
43
+ path: '/tools/call/localSearchCode',
44
+ query: {},
45
+ };
46
+
47
+ mockRes = {
48
+ status: statusMock as unknown as Response['status'],
49
+ };
50
+
51
+ mockNext = vi.fn();
52
+ });
53
+
54
+ describe('status code handling', () => {
55
+ it('uses error statusCode if provided', () => {
56
+ const error: ApiError = new Error('Bad request');
57
+ error.statusCode = 400;
58
+
59
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
60
+
61
+ expect(statusMock).toHaveBeenCalledWith(400);
62
+ });
63
+
64
+ it('defaults to 500 for server errors', () => {
65
+ const error: ApiError = new Error('Internal error');
66
+
67
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
68
+
69
+ expect(statusMock).toHaveBeenCalledWith(500);
70
+ });
71
+ });
72
+
73
+ describe('response format', () => {
74
+ it('returns success: false', () => {
75
+ const error: ApiError = new Error('Test error');
76
+
77
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
78
+
79
+ expect(jsonMock).toHaveBeenCalledWith(
80
+ expect.objectContaining({
81
+ success: false,
82
+ })
83
+ );
84
+ });
85
+
86
+ it('includes error message', () => {
87
+ const error: ApiError = new Error('Test error message');
88
+
89
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
90
+
91
+ expect(jsonMock).toHaveBeenCalledWith(
92
+ expect.objectContaining({
93
+ error: expect.objectContaining({
94
+ message: 'Test error message',
95
+ }),
96
+ })
97
+ );
98
+ });
99
+
100
+ it('uses error code if provided', () => {
101
+ const error: ApiError = new Error('Test error');
102
+ error.code = 'CUSTOM_ERROR';
103
+
104
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
105
+
106
+ expect(jsonMock).toHaveBeenCalledWith(
107
+ expect.objectContaining({
108
+ error: expect.objectContaining({
109
+ code: 'CUSTOM_ERROR',
110
+ }),
111
+ })
112
+ );
113
+ });
114
+
115
+ it('defaults to INTERNAL_ERROR code', () => {
116
+ const error: ApiError = new Error('Test error');
117
+
118
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
119
+
120
+ expect(jsonMock).toHaveBeenCalledWith(
121
+ expect.objectContaining({
122
+ error: expect.objectContaining({
123
+ code: 'INTERNAL_ERROR',
124
+ }),
125
+ })
126
+ );
127
+ });
128
+ });
129
+
130
+ describe('validation error details', () => {
131
+ it('includes details for 400 errors', () => {
132
+ const error: ApiError = new Error('Validation failed');
133
+ error.statusCode = 400;
134
+ error.details = [
135
+ { path: ['queries'], message: 'Required', code: 'invalid_type', expected: 'array' } as z.core.$ZodIssue,
136
+ ];
137
+
138
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
139
+
140
+ expect(jsonMock).toHaveBeenCalledWith(
141
+ expect.objectContaining({
142
+ error: expect.objectContaining({
143
+ details: expect.arrayContaining([
144
+ expect.objectContaining({ path: ['queries'] }),
145
+ ]),
146
+ }),
147
+ })
148
+ );
149
+ });
150
+
151
+ it('excludes details for 500 errors', () => {
152
+ const error: ApiError = new Error('Server error');
153
+ error.details = [{ path: ['internal'], message: 'Debug info', code: 'custom' } as z.core.$ZodIssue];
154
+
155
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
156
+
157
+ const response = jsonMock.mock.calls[0][0];
158
+ expect(response.error.details).toBeUndefined();
159
+ });
160
+ });
161
+
162
+ describe('tool name extraction', () => {
163
+ it('extracts tool name from /tools/call/:toolName path', () => {
164
+ mockReq.path = '/tools/call/localSearchCode';
165
+ const error: ApiError = new Error('Test');
166
+
167
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
168
+
169
+ // Verify fireAndForgetWithTimeout was called (tool name is passed to logSessionError)
170
+ expect(fireAndForgetWithTimeout).toHaveBeenCalled();
171
+ });
172
+
173
+ it('uses unknown for non-tool paths', () => {
174
+ mockReq.path = '/prompts/list';
175
+ const error: ApiError = new Error('Test');
176
+
177
+ errorHandler(error, mockReq as Request, mockRes as Response, mockNext);
178
+
179
+ // Tool name should be 'unknown' for non-tool paths
180
+ expect(fireAndForgetWithTimeout).toHaveBeenCalled();
181
+ });
182
+ });
183
+ });
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Unit tests for HTTP preprocessing utilities.
3
+ *
4
+ * Tests type coercion, path safety, and array handling for HTTP query strings.
5
+ *
6
+ * @module tests/unit/httpPreprocess
7
+ */
8
+
9
+ import { describe, it, expect } from 'vitest';
10
+ import { toNumber, toBoolean, toArray, safePath, numericString, booleanString, stringArray } from '../../validation/httpPreprocess.js';
11
+
12
+ describe('toNumber', () => {
13
+ it('passes through numbers', () => {
14
+ expect(toNumber(42)).toBe(42);
15
+ expect(toNumber(0)).toBe(0);
16
+ });
17
+
18
+ it('converts numeric strings to integers', () => {
19
+ expect(toNumber('42')).toBe(42);
20
+ expect(toNumber('0')).toBe(0);
21
+ expect(toNumber('100')).toBe(100);
22
+ });
23
+
24
+ it('returns non-numeric strings as-is', () => {
25
+ expect(toNumber('abc')).toBe('abc');
26
+ expect(toNumber('12.5')).toBe('12.5'); // floats not supported
27
+ expect(toNumber('12abc')).toBe('12abc');
28
+ });
29
+
30
+ it('returns non-string/non-number values as-is', () => {
31
+ expect(toNumber(null)).toBeNull();
32
+ expect(toNumber(undefined)).toBeUndefined();
33
+ expect(toNumber(true)).toBe(true);
34
+ expect(toNumber([])).toEqual([]);
35
+ });
36
+ });
37
+
38
+ describe('toBoolean', () => {
39
+ it('passes through booleans', () => {
40
+ expect(toBoolean(true)).toBe(true);
41
+ expect(toBoolean(false)).toBe(false);
42
+ });
43
+
44
+ it('converts string "true" and "false"', () => {
45
+ expect(toBoolean('true')).toBe(true);
46
+ expect(toBoolean('false')).toBe(false);
47
+ });
48
+
49
+ it('returns other values as-is', () => {
50
+ expect(toBoolean('yes')).toBe('yes');
51
+ expect(toBoolean('1')).toBe('1');
52
+ expect(toBoolean(null)).toBeNull();
53
+ expect(toBoolean(undefined)).toBeUndefined();
54
+ });
55
+ });
56
+
57
+ describe('toArray', () => {
58
+ it('passes through arrays', () => {
59
+ expect(toArray(['a', 'b'])).toEqual(['a', 'b']);
60
+ expect(toArray([])).toEqual([]);
61
+ });
62
+
63
+ it('splits comma-separated strings', () => {
64
+ expect(toArray('a,b,c')).toEqual(['a', 'b', 'c']);
65
+ expect(toArray('ts,js')).toEqual(['ts', 'js']);
66
+ });
67
+
68
+ it('trims whitespace around items', () => {
69
+ expect(toArray('a , b , c')).toEqual(['a', 'b', 'c']);
70
+ });
71
+
72
+ it('returns empty array for empty string', () => {
73
+ expect(toArray('')).toEqual([]);
74
+ });
75
+
76
+ it('returns empty array for whitespace-only string', () => {
77
+ expect(toArray(' ')).toEqual([]);
78
+ });
79
+
80
+ it('filters out empty items from trailing commas', () => {
81
+ expect(toArray('a,b,')).toEqual(['a', 'b']);
82
+ expect(toArray(',a')).toEqual(['a']);
83
+ });
84
+
85
+ it('handles single value strings', () => {
86
+ expect(toArray('typescript')).toEqual(['typescript']);
87
+ });
88
+
89
+ it('returns non-string/non-array values as-is', () => {
90
+ expect(toArray(null)).toBeNull();
91
+ expect(toArray(undefined)).toBeUndefined();
92
+ expect(toArray(42)).toBe(42);
93
+ });
94
+ });
95
+
96
+ describe('safePath', () => {
97
+ it('accepts valid paths', () => {
98
+ expect(safePath.safeParse('/Users/dev/project').success).toBe(true);
99
+ expect(safePath.safeParse('/tmp/test').success).toBe(true);
100
+ expect(safePath.safeParse('src/utils.ts').success).toBe(true);
101
+ });
102
+
103
+ it('rejects null bytes', () => {
104
+ expect(safePath.safeParse('/path/\0/exploit').success).toBe(false);
105
+ });
106
+
107
+ it('rejects directory traversal', () => {
108
+ expect(safePath.safeParse('../../../etc/passwd').success).toBe(false);
109
+ expect(safePath.safeParse('src/../../etc/passwd').success).toBe(false);
110
+ });
111
+
112
+ it('rejects URL-encoded traversal', () => {
113
+ expect(safePath.safeParse('%2e%2e%2fetc/passwd').success).toBe(false);
114
+ expect(safePath.safeParse('/path/%2e%2e/exploit').success).toBe(false);
115
+ });
116
+
117
+ it('rejects backslashes on non-Windows', () => {
118
+ if (process.platform !== 'win32') {
119
+ expect(safePath.safeParse('path\\to\\file').success).toBe(false);
120
+ }
121
+ });
122
+ });
123
+
124
+ describe('numericString (Zod schema)', () => {
125
+ it('parses string numbers', () => {
126
+ expect(numericString.parse('10')).toBe(10);
127
+ });
128
+
129
+ it('handles undefined', () => {
130
+ expect(numericString.parse(undefined)).toBeUndefined();
131
+ });
132
+ });
133
+
134
+ describe('booleanString (Zod schema)', () => {
135
+ it('parses string booleans', () => {
136
+ expect(booleanString.parse('true')).toBe(true);
137
+ expect(booleanString.parse('false')).toBe(false);
138
+ });
139
+
140
+ it('handles undefined', () => {
141
+ expect(booleanString.parse(undefined)).toBeUndefined();
142
+ });
143
+ });
144
+
145
+ describe('stringArray (Zod schema)', () => {
146
+ it('parses comma-separated strings', () => {
147
+ expect(stringArray.parse('a,b,c')).toEqual(['a', 'b', 'c']);
148
+ });
149
+
150
+ it('passes through arrays', () => {
151
+ expect(stringArray.parse(['x', 'y'])).toEqual(['x', 'y']);
152
+ });
153
+
154
+ it('handles empty string', () => {
155
+ expect(stringArray.parse('')).toEqual([]);
156
+ });
157
+ });