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,688 @@
1
+ import type { GraphAnalyticsSummary } from '../analysis/graph-analytics.js';
2
+ import type {
3
+ AnalysisLens,
4
+ AnalysisSignal,
5
+ BoundaryRoleHint,
6
+ CfgFlags,
7
+ EffectProfile,
8
+ FileEntry,
9
+ Finding,
10
+ FlowTraceStep,
11
+ HotFile,
12
+ RecommendedValidation,
13
+ SymbolUsageSummary,
14
+ } from '../types/index.js';
15
+
16
+ export interface ReportAnalysisSummary {
17
+ graphSignals: AnalysisSignal[];
18
+ astSignals: AnalysisSignal[];
19
+ combinedSignals: AnalysisSignal[];
20
+ strongestGraphSignal: AnalysisSignal | null;
21
+ strongestAstSignal: AnalysisSignal | null;
22
+ combinedInterpretation: AnalysisSignal | null;
23
+ recommendedValidation: RecommendedValidation | null;
24
+ investigationPrompts: string[];
25
+ }
26
+
27
+ function buildEffectProfile(entry: FileEntry): EffectProfile | undefined {
28
+ const effects = entry.topLevelEffects || [];
29
+ if (effects.length === 0) return undefined;
30
+ const byKind: EffectProfile['byKind'] = {};
31
+ let totalWeight = 0;
32
+ let highestRisk: EffectProfile['highestRisk'] = null;
33
+ let highestWeight = -1;
34
+ for (const effect of effects) {
35
+ byKind[effect.kind] = (byKind[effect.kind] || 0) + 1;
36
+ totalWeight += effect.weight;
37
+ if (effect.weight > highestWeight) {
38
+ highestWeight = effect.weight;
39
+ highestRisk = effect.kind;
40
+ }
41
+ }
42
+ return {
43
+ totalEffects: effects.length,
44
+ totalWeight,
45
+ byKind: byKind as EffectProfile['byKind'],
46
+ highestRisk,
47
+ };
48
+ }
49
+
50
+ function buildSymbolUsageSummary(entry: FileEntry): SymbolUsageSummary {
51
+ const internalImports = entry.dependencyProfile.importedSymbols.filter(
52
+ ref => !!ref.resolvedModule
53
+ );
54
+ const dominantInternalDependency =
55
+ internalImports.length === 0
56
+ ? null
57
+ : [
58
+ ...internalImports
59
+ .reduce((acc, ref) => {
60
+ const key = ref.resolvedModule || ref.sourceModule;
61
+ acc.set(key, (acc.get(key) || 0) + 1);
62
+ return acc;
63
+ }, new Map<string, number>())
64
+ .entries(),
65
+ ].sort((a, b) => b[1] - a[1])[0]?.[0] || null;
66
+ return {
67
+ declaredExportCount: entry.dependencyProfile.declaredExports.length,
68
+ importedSymbolCount: entry.dependencyProfile.importedSymbols.length,
69
+ internalImportCount: internalImports.length,
70
+ externalImportCount: entry.dependencyProfile.externalDependencies.length,
71
+ reExportCount: entry.dependencyProfile.reExports.length,
72
+ dominantInternalDependency,
73
+ };
74
+ }
75
+
76
+ function buildBoundaryRoleHints(
77
+ entry: FileEntry
78
+ ): BoundaryRoleHint[] | undefined {
79
+ const normalized = entry.file.replace(/\\/g, '/').toLowerCase();
80
+ const hints: BoundaryRoleHint[] = [];
81
+ const addHint = (
82
+ role: string,
83
+ confidence: BoundaryRoleHint['confidence'],
84
+ reasons: string[]
85
+ ): void => {
86
+ hints.push({ role, confidence, reasons });
87
+ };
88
+
89
+ if (/(^|\/)(index|main|app|server|cli)\.[mc]?[jt]sx?$/.test(normalized)) {
90
+ addHint('entrypoint', 'high', [
91
+ 'path matches a conventional entrypoint filename',
92
+ ]);
93
+ }
94
+ if (/(^|\/)(components|ui|pages|screens)\//.test(normalized)) {
95
+ addHint('ui', 'high', ['path indicates UI-facing code']);
96
+ }
97
+ if (/(^|\/)(routes|controllers|handlers|http|api)\//.test(normalized)) {
98
+ addHint('transport', 'medium', [
99
+ 'path indicates controller, handler, or API transport code',
100
+ ]);
101
+ }
102
+ if (/(^|\/)(service|services|use-cases|usecases)\//.test(normalized)) {
103
+ addHint('service', 'medium', [
104
+ 'path indicates orchestration or service logic',
105
+ ]);
106
+ }
107
+ if (
108
+ /(^|\/)(repo|repos|repository|repositories|db|persistence)\//.test(
109
+ normalized
110
+ )
111
+ ) {
112
+ addHint('persistence', 'high', [
113
+ 'path indicates persistence or repository code',
114
+ ]);
115
+ }
116
+ if ((entry.topLevelEffects?.length || 0) > 0) {
117
+ addHint('runtime-bootstrap', 'medium', [
118
+ 'module has import-time side effects',
119
+ ]);
120
+ }
121
+ if (
122
+ entry.dependencyProfile.declaredExports.length >= 8 &&
123
+ entry.dependencyProfile.importedSymbols.length <= 2
124
+ ) {
125
+ addHint('shared-utility', 'medium', [
126
+ 'exports many symbols and imports little internal behavior',
127
+ ]);
128
+ }
129
+
130
+ if (hints.length === 0) return undefined;
131
+ return hints.slice(0, 3);
132
+ }
133
+
134
+ function buildCfgFlags(entry: FileEntry): CfgFlags | undefined {
135
+ const hasValidationChecks = (entry.inputSources || []).some(
136
+ source => source.hasValidation
137
+ );
138
+ const hasCleanupHooks = !!entry.testProfile?.setupCalls.some(
139
+ call => call.kind === 'afterAll' || call.kind === 'afterEach'
140
+ );
141
+ const exitPointCount = entry.functions.reduce(
142
+ (sum, fn) => sum + fn.returns,
143
+ 0
144
+ );
145
+ const asyncBoundaryCount = entry.functions.reduce(
146
+ (sum, fn) => sum + fn.awaits,
147
+ 0
148
+ );
149
+ const hasTopLevelEffects = (entry.topLevelEffects?.length || 0) > 0;
150
+ return {
151
+ hasValidationChecks,
152
+ hasCleanupHooks,
153
+ exitPointCount,
154
+ asyncBoundaryCount,
155
+ hasTopLevelEffects,
156
+ };
157
+ }
158
+
159
+ export function enrichFileInventoryEntries(
160
+ fileEntries: FileEntry[],
161
+ options: { flowEnabled?: boolean } = {}
162
+ ): FileEntry[] {
163
+ const { flowEnabled = false } = options;
164
+ return fileEntries.map(entry => ({
165
+ ...entry,
166
+ effectProfile: entry.effectProfile || buildEffectProfile(entry),
167
+ symbolUsageSummary:
168
+ entry.symbolUsageSummary || buildSymbolUsageSummary(entry),
169
+ boundaryRoleHints:
170
+ entry.boundaryRoleHints || buildBoundaryRoleHints(entry) || [],
171
+ cfgFlags: flowEnabled ? entry.cfgFlags || buildCfgFlags(entry) : undefined,
172
+ }));
173
+ }
174
+
175
+ function inferAnalysisLens(category: string): AnalysisLens {
176
+ if (
177
+ [
178
+ 'dependency-cycle',
179
+ 'dependency-critical-path',
180
+ 'architecture-sdp-violation',
181
+ 'high-coupling',
182
+ 'god-module-coupling',
183
+ 'orphan-module',
184
+ 'unreachable-module',
185
+ 'cycle-cluster',
186
+ 'broker-module',
187
+ 'bridge-module',
188
+ 'mega-folder',
189
+ ].includes(category)
190
+ )
191
+ return 'graph';
192
+
193
+ if (
194
+ [
195
+ 'layer-violation',
196
+ 'low-cohesion',
197
+ 'feature-envy',
198
+ 'import-side-effect-risk',
199
+ 'package-boundary-chatter',
200
+ 'startup-risk-hub',
201
+ 'unvalidated-input-sink',
202
+ 'input-passthrough-risk',
203
+ 'missing-test-cleanup',
204
+ 'fake-timer-no-restore',
205
+ 'missing-mock-restoration',
206
+ ].includes(category)
207
+ )
208
+ return 'hybrid';
209
+
210
+ if (category.startsWith('dependency-')) return 'graph';
211
+ if (category.startsWith('test-') || category === 'focused-test')
212
+ return 'hybrid';
213
+ if (
214
+ [
215
+ 'hardcoded-secret',
216
+ 'eval-usage',
217
+ 'unsafe-html',
218
+ 'sql-injection-risk',
219
+ 'unsafe-regex',
220
+ 'prototype-pollution-risk',
221
+ 'path-traversal-risk',
222
+ 'command-injection-risk',
223
+ 'debug-log-leakage',
224
+ 'sensitive-data-logging',
225
+ ].includes(category)
226
+ ) {
227
+ return 'hybrid';
228
+ }
229
+
230
+ if (
231
+ [
232
+ 'over-abstraction',
233
+ 'concrete-dependency',
234
+ 'circular-type-dependency',
235
+ 'unused-parameter',
236
+ 'deep-override-chain',
237
+ 'interface-compliance',
238
+ 'unused-import',
239
+ 'orphan-implementation',
240
+ 'shotgun-surgery',
241
+ 'move-to-caller',
242
+ 'narrowable-type',
243
+ 'semantic-dead-export',
244
+ ].includes(category)
245
+ ) {
246
+ return 'hybrid';
247
+ }
248
+
249
+ return 'ast';
250
+ }
251
+
252
+ function defaultConfidence(finding: Finding): Finding['confidence'] {
253
+ if (finding.confidence) return finding.confidence;
254
+ if (finding.severity === 'critical') return 'high';
255
+ if (finding.analysisLens === 'graph') return 'medium';
256
+ if (finding.analysisLens === 'hybrid') return 'medium';
257
+ return 'low';
258
+ }
259
+
260
+ function parseFlowTraceSteps(
261
+ finding: Finding,
262
+ flowEnabled: boolean
263
+ ): FlowTraceStep[] | undefined {
264
+ if (!flowEnabled) return undefined;
265
+ if (finding.flowTrace && finding.flowTrace.length > 0)
266
+ return finding.flowTrace;
267
+ const raw = finding.evidence?.propagationSteps;
268
+ if (!Array.isArray(raw)) return undefined;
269
+ const steps = raw
270
+ .map(entry => {
271
+ if (typeof entry !== 'string') return null;
272
+ const match = entry.match(/^(.*?):(\d+)(?:-(\d+))?$/);
273
+ if (!match) return null;
274
+ return {
275
+ file: match[1],
276
+ lineStart: Number(match[2]),
277
+ lineEnd: Number(match[3] || match[2]),
278
+ label: 'propagation step',
279
+ } satisfies FlowTraceStep;
280
+ })
281
+ .filter((step): step is FlowTraceStep => step !== null);
282
+ return steps.length > 0 ? steps : undefined;
283
+ }
284
+
285
+ function buildRecommendedValidation(finding: Finding): RecommendedValidation {
286
+ const primaryHint = finding.lspHints?.[0];
287
+ if (primaryHint) {
288
+ return {
289
+ summary: primaryHint.expectedResult,
290
+ tools: ['localSearchCode', primaryHint.tool],
291
+ };
292
+ }
293
+ if (finding.analysisLens === 'graph') {
294
+ return {
295
+ summary:
296
+ 'Confirm the dependency edge or hub behavior with localSearchCode and an LSP navigation step.',
297
+ tools: ['localSearchCode', 'lspGotoDefinition'],
298
+ };
299
+ }
300
+ if (finding.analysisLens === 'hybrid') {
301
+ return {
302
+ summary:
303
+ 'Validate both the structural location and the behavioral path before presenting the claim as fact.',
304
+ tools: ['localSearchCode', 'lspCallHierarchy'],
305
+ };
306
+ }
307
+ return {
308
+ summary:
309
+ 'Confirm the code location and inspect the matched structure before proposing a refactor.',
310
+ tools: ['localSearchCode'],
311
+ };
312
+ }
313
+
314
+ export function enrichFindings(
315
+ findings: Finding[],
316
+ fileEntries: FileEntry[],
317
+ hotFiles: HotFile[],
318
+ graphAnalytics: GraphAnalyticsSummary | null,
319
+ options: { flowEnabled?: boolean } = {}
320
+ ): Finding[] {
321
+ const { flowEnabled = false } = options;
322
+ const byFile = new Map(fileEntries.map(entry => [entry.file, entry]));
323
+ const hotFileSet = new Set(hotFiles.map(entry => entry.file));
324
+ const cycleFiles = new Set<string>();
325
+ const criticalPathFiles = new Set<string>();
326
+ if (graphAnalytics) {
327
+ for (const cluster of graphAnalytics.sccClusters) {
328
+ for (const file of cluster.files) cycleFiles.add(file);
329
+ }
330
+ for (const chokepoint of graphAnalytics.chokepoints) {
331
+ if (chokepoint.onCriticalPath) criticalPathFiles.add(chokepoint.file);
332
+ }
333
+ }
334
+ const relatedByFile = new Map<string, Set<string>>();
335
+ for (const finding of findings) {
336
+ if (!relatedByFile.has(finding.file))
337
+ relatedByFile.set(finding.file, new Set());
338
+ relatedByFile.get(finding.file)!.add(finding.category);
339
+ }
340
+
341
+ return findings.map(finding => {
342
+ const analysisLens =
343
+ finding.analysisLens || inferAnalysisLens(finding.category);
344
+ const entry = byFile.get(finding.file);
345
+ const correlatedSignals = new Set<string>(finding.correlatedSignals || []);
346
+ if (hotFileSet.has(finding.file)) correlatedSignals.add('hot-file');
347
+ if (cycleFiles.has(finding.file)) correlatedSignals.add('cycle-context');
348
+ if (criticalPathFiles.has(finding.file))
349
+ correlatedSignals.add('critical-path-context');
350
+ if (entry?.effectProfile?.totalEffects)
351
+ correlatedSignals.add('top-level-effects');
352
+ for (const category of relatedByFile.get(finding.file) ||
353
+ new Set<string>()) {
354
+ if (category !== finding.category)
355
+ correlatedSignals.add(`paired:${category}`);
356
+ }
357
+
358
+ const evidence = {
359
+ category: finding.category,
360
+ location: `${finding.file}:${finding.lineStart}-${finding.lineEnd}`,
361
+ ...(finding.evidence || {}),
362
+ };
363
+
364
+ return {
365
+ ...finding,
366
+ ruleId: finding.ruleId || `${analysisLens}.${finding.category}`,
367
+ analysisLens,
368
+ confidence: defaultConfidence({ ...finding, analysisLens }),
369
+ evidence,
370
+ correlatedSignals: [...correlatedSignals].slice(0, 8),
371
+ recommendedValidation:
372
+ finding.recommendedValidation ||
373
+ buildRecommendedValidation({ ...finding, analysisLens }),
374
+ flowTrace: parseFlowTraceSteps({ ...finding, evidence }, flowEnabled),
375
+ };
376
+ });
377
+ }
378
+
379
+ function makeSignal(
380
+ kind: string,
381
+ lens: AnalysisLens,
382
+ title: string,
383
+ summary: string,
384
+ confidence: AnalysisSignal['confidence'],
385
+ score: number,
386
+ files: string[],
387
+ categories: string[],
388
+ evidence: Record<string, unknown>
389
+ ): AnalysisSignal {
390
+ return {
391
+ kind,
392
+ lens,
393
+ title,
394
+ summary,
395
+ confidence,
396
+ score,
397
+ files,
398
+ categories,
399
+ evidence,
400
+ };
401
+ }
402
+
403
+ export function computeReportAnalysisSummary(
404
+ findings: Finding[],
405
+ fileEntries: FileEntry[],
406
+ hotFiles: HotFile[],
407
+ graphAnalytics: GraphAnalyticsSummary | null
408
+ ): ReportAnalysisSummary {
409
+ const categoriesByFile = new Map<string, Set<string>>();
410
+ for (const finding of findings) {
411
+ if (!categoriesByFile.has(finding.file))
412
+ categoriesByFile.set(finding.file, new Set());
413
+ categoriesByFile.get(finding.file)!.add(finding.category);
414
+ }
415
+
416
+ const graphSignals: AnalysisSignal[] = [];
417
+ const astSignals: AnalysisSignal[] = [];
418
+
419
+ if (graphAnalytics?.chokepoints.length) {
420
+ const top = graphAnalytics.chokepoints[0];
421
+ graphSignals.push(
422
+ makeSignal(
423
+ 'structural-chokepoint',
424
+ 'graph',
425
+ 'Structural chokepoint',
426
+ `${top.file} concentrates dependency pressure (${top.reasons.join(', ')}).`,
427
+ top.articulation ? 'high' : 'medium',
428
+ top.score,
429
+ [top.file],
430
+ ['broker-module', 'bridge-module'],
431
+ { score: top.score, reasons: top.reasons }
432
+ )
433
+ );
434
+ }
435
+
436
+ if (graphAnalytics?.sccClusters.length) {
437
+ const cluster = graphAnalytics.sccClusters[0];
438
+ graphSignals.push(
439
+ makeSignal(
440
+ 'cycle-cluster',
441
+ 'graph',
442
+ 'Cycle cluster',
443
+ `${cluster.id} links ${cluster.nodeCount} files into a single strongly connected group.`,
444
+ cluster.nodeCount >= 5 ? 'high' : 'medium',
445
+ cluster.nodeCount * 6 + cluster.edgeCount,
446
+ cluster.files,
447
+ ['dependency-cycle', 'cycle-cluster'],
448
+ {
449
+ clusterId: cluster.id,
450
+ nodeCount: cluster.nodeCount,
451
+ hubFiles: cluster.hubFiles,
452
+ }
453
+ )
454
+ );
455
+ }
456
+
457
+ if (graphAnalytics?.packageGraphSummary.hotspots.length) {
458
+ const hotspot = graphAnalytics.packageGraphSummary.hotspots[0];
459
+ graphSignals.push(
460
+ makeSignal(
461
+ 'package-chatter',
462
+ 'graph',
463
+ 'Package boundary chatter',
464
+ `${hotspot.from} and ${hotspot.to} exchange ${hotspot.edges} cross-package dependency edge(s).`,
465
+ hotspot.edges >= 8 ? 'high' : 'medium',
466
+ hotspot.edges * 4,
467
+ [hotspot.from, hotspot.to],
468
+ ['package-boundary-chatter'],
469
+ hotspot
470
+ )
471
+ );
472
+ }
473
+
474
+ const megaFolderFindings = findings
475
+ .filter(finding => finding.category === 'mega-folder')
476
+ .sort((a, b) => {
477
+ const aCount = Number(
478
+ (a.evidence as Record<string, unknown> | undefined)?.fileCount || 0
479
+ );
480
+ const bCount = Number(
481
+ (b.evidence as Record<string, unknown> | undefined)?.fileCount || 0
482
+ );
483
+ return bCount - aCount;
484
+ });
485
+ if (megaFolderFindings.length > 0) {
486
+ const top = megaFolderFindings[0];
487
+ const evidence =
488
+ (top.evidence as Record<string, unknown> | undefined) || {};
489
+ const folderPath =
490
+ typeof evidence.folderPath === 'string'
491
+ ? evidence.folderPath
492
+ : folderOf(top.file);
493
+ const fileCount = Number(evidence.fileCount || top.files.length || 0);
494
+ const concentration = Number(evidence.concentration || 0);
495
+ graphSignals.push(
496
+ makeSignal(
497
+ 'mega-folder-cluster',
498
+ 'graph',
499
+ 'Mega folder concentration',
500
+ `${folderPath} concentrates ${fileCount} files (${(concentration * 100).toFixed(1)}% of analyzed production files), which is a structural decomposition risk.`,
501
+ concentration >= 0.5 || fileCount >= 50 ? 'high' : 'medium',
502
+ Math.round(fileCount * 3 + concentration * 100),
503
+ top.files.length > 0 ? top.files : [top.file],
504
+ ['mega-folder'],
505
+ {
506
+ folderPath,
507
+ fileCount,
508
+ concentration,
509
+ }
510
+ )
511
+ );
512
+ }
513
+
514
+ for (const entry of fileEntries) {
515
+ const categories = categoriesByFile.get(entry.file) || new Set<string>();
516
+ if (categories.has('low-cohesion') && categories.has('feature-envy')) {
517
+ astSignals.push(
518
+ makeSignal(
519
+ 'boundary-leak-shape',
520
+ 'ast',
521
+ 'Boundary leak shape',
522
+ `${entry.file} shows both low cohesion and feature envy, suggesting the module boundary is doing multiple jobs.`,
523
+ 'high',
524
+ 90,
525
+ [entry.file],
526
+ ['low-cohesion', 'feature-envy'],
527
+ { file: entry.file }
528
+ )
529
+ );
530
+ }
531
+ if (
532
+ (entry.effectProfile?.totalEffects || 0) > 0 &&
533
+ categories.has('import-side-effect-risk')
534
+ ) {
535
+ astSignals.push(
536
+ makeSignal(
537
+ 'hidden-initialization',
538
+ 'ast',
539
+ 'Hidden initialization logic',
540
+ `${entry.file} performs import-time work that matches the reported side-effect risk.`,
541
+ 'medium',
542
+ 75,
543
+ [entry.file],
544
+ ['import-side-effect-risk'],
545
+ {
546
+ totalEffects: entry.effectProfile?.totalEffects,
547
+ highestRisk: entry.effectProfile?.highestRisk,
548
+ }
549
+ )
550
+ );
551
+ }
552
+ if (
553
+ categories.has('duplicate-flow-structure') &&
554
+ categories.has('function-optimization')
555
+ ) {
556
+ astSignals.push(
557
+ makeSignal(
558
+ 'orchestration-duplication',
559
+ 'ast',
560
+ 'Repeated orchestration shape',
561
+ `${entry.file} combines repeated control-flow shape with complex functions, which usually means orchestration duplication.`,
562
+ 'medium',
563
+ 70,
564
+ [entry.file],
565
+ ['duplicate-flow-structure', 'function-optimization'],
566
+ { file: entry.file }
567
+ )
568
+ );
569
+ }
570
+ }
571
+
572
+ const strongestGraphSignal =
573
+ graphSignals.sort((a, b) => b.score - a.score)[0] || null;
574
+ const strongestAstSignal =
575
+ astSignals.sort((a, b) => b.score - a.score)[0] || null;
576
+
577
+ let combinedInterpretation: AnalysisSignal | null = null;
578
+ if (strongestGraphSignal && strongestAstSignal) {
579
+ const sharedFile = strongestGraphSignal.files.find(file =>
580
+ strongestAstSignal.files.includes(file)
581
+ );
582
+ const confidence = sharedFile ? 'high' : 'medium';
583
+ combinedInterpretation = makeSignal(
584
+ 'combined-interpretation',
585
+ 'hybrid',
586
+ 'Combined interpretation',
587
+ sharedFile
588
+ ? `${sharedFile} is both a structural hotspot and a suspicious code-shape hotspot, so it should be investigated first.`
589
+ : `${strongestGraphSignal.title} and ${strongestAstSignal.title} both appear in this scan, so use a hybrid investigation instead of a single-lens conclusion.`,
590
+ confidence,
591
+ Math.round((strongestGraphSignal.score + strongestAstSignal.score) / 2),
592
+ sharedFile
593
+ ? [sharedFile]
594
+ : [
595
+ ...new Set([
596
+ ...strongestGraphSignal.files,
597
+ ...strongestAstSignal.files,
598
+ ]),
599
+ ].slice(0, 4),
600
+ [
601
+ ...new Set([
602
+ ...strongestGraphSignal.categories,
603
+ ...strongestAstSignal.categories,
604
+ ]),
605
+ ],
606
+ {
607
+ graphKind: strongestGraphSignal.kind,
608
+ astKind: strongestAstSignal.kind,
609
+ sharedFile: sharedFile || null,
610
+ }
611
+ );
612
+ } else if (strongestGraphSignal || strongestAstSignal) {
613
+ const signal = strongestGraphSignal || strongestAstSignal!;
614
+ combinedInterpretation = makeSignal(
615
+ 'combined-interpretation',
616
+ signal.lens,
617
+ 'Combined interpretation',
618
+ signal.summary,
619
+ signal.confidence,
620
+ signal.score,
621
+ signal.files,
622
+ signal.categories,
623
+ signal.evidence
624
+ );
625
+ }
626
+
627
+ const relevantFiles = new Set(combinedInterpretation?.files || []);
628
+ const relevantCategories = new Set(combinedInterpretation?.categories || []);
629
+ const prioritizedFinding =
630
+ findings.find(
631
+ finding =>
632
+ relevantFiles.has(finding.file) ||
633
+ relevantCategories.has(finding.category)
634
+ ) || findings[0];
635
+ const recommendedValidation =
636
+ prioritizedFinding?.recommendedValidation || null;
637
+
638
+ const prompts = new Set<string>();
639
+ if (strongestGraphSignal) {
640
+ prompts.add(
641
+ `Inspect ${strongestGraphSignal.files[0]} first and validate the graph claim with localSearchCode plus LSP navigation.`
642
+ );
643
+ }
644
+ if (strongestAstSignal) {
645
+ prompts.add(
646
+ `Use file-inventory.json for ${strongestAstSignal.files[0]} to explain why the code shape matches the finding.`
647
+ );
648
+ }
649
+ if (combinedInterpretation?.confidence === 'high') {
650
+ prompts.add(
651
+ 'Treat the aligned graph and AST signal as an architecture priority, not just a local cleanup task.'
652
+ );
653
+ } else if (combinedInterpretation) {
654
+ prompts.add(
655
+ 'Use a hybrid investigation before proposing a refactor because the signals do not fully align yet.'
656
+ );
657
+ }
658
+ if (hotFiles.length > 0) {
659
+ prompts.add(
660
+ `Cross-check the top hotspot ${hotFiles[0].file} with the strongest architecture finding before editing code.`
661
+ );
662
+ }
663
+ const megaFolderSignal = graphSignals.find(
664
+ signal => signal.kind === 'mega-folder-cluster'
665
+ );
666
+ if (megaFolderSignal) {
667
+ prompts.add(
668
+ `Map the import graph of ${megaFolderSignal.evidence.folderPath}, identify domain clusters, and restructure with an automated migration script that moves files and rewrites import paths atomically. Validate with tsc + lint + tests after each phase.`
669
+ );
670
+ }
671
+
672
+ return {
673
+ graphSignals: graphSignals.sort((a, b) => b.score - a.score),
674
+ astSignals: astSignals.sort((a, b) => b.score - a.score),
675
+ combinedSignals: combinedInterpretation ? [combinedInterpretation] : [],
676
+ strongestGraphSignal,
677
+ strongestAstSignal,
678
+ combinedInterpretation,
679
+ recommendedValidation,
680
+ investigationPrompts: [...prompts],
681
+ };
682
+ }
683
+
684
+ function folderOf(filePath: string): string {
685
+ const normalized = filePath.replace(/\\/g, '/');
686
+ const idx = normalized.lastIndexOf('/');
687
+ return idx === -1 ? '.' : normalized.slice(0, idx);
688
+ }