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,363 @@
1
+ /**
2
+ * Server Init Script
3
+ *
4
+ * Handles server initialization with mutex lock:
5
+ * 1. Acquires atomic lock to prevent concurrent startups
6
+ * 2. Checks if server is running (health check)
7
+ * 3. Starts server if not running
8
+ * 4. Waits for status "ok"
9
+ * 5. Outputs "ok" on success
10
+ *
11
+ * Improvements:
12
+ * - Atomic lock using O_CREAT | O_EXCL | O_WRONLY (no race condition)
13
+ * - Exponential backoff retry for lock acquisition
14
+ * - Environment variable configuration
15
+ * - Spawn error handling
16
+ * - Better health check error logging
17
+ *
18
+ * Usage: npm run server-init
19
+ * Exit codes: 0 = success, 1 = error
20
+ */
21
+
22
+ import { spawn } from 'child_process';
23
+ import {
24
+ existsSync,
25
+ mkdirSync,
26
+ unlinkSync,
27
+ readFileSync,
28
+ constants,
29
+ openSync,
30
+ writeSync,
31
+ closeSync,
32
+ statSync,
33
+ } from 'fs';
34
+ import { join } from 'path';
35
+ import { homedir } from 'os';
36
+
37
+ // =============================================================================
38
+ // Configuration (Environment Variables)
39
+ // =============================================================================
40
+
41
+ const PORT = parseInt(process.env.OCTOCODE_PORT || '1987', 10);
42
+ const HEALTH_URL = `http://localhost:${PORT}/health`;
43
+ const LOCK_DIR = join(homedir(), '.octocode');
44
+ const LOCK_FILE = join(LOCK_DIR, 'server-init.lock');
45
+ const LOCK_TIMEOUT_MS = parseInt(process.env.OCTOCODE_LOCK_TIMEOUT || '60000', 10);
46
+ const MAX_WAIT_MS = parseInt(process.env.OCTOCODE_INIT_TIMEOUT || '30000', 10);
47
+ const POLL_INTERVAL_MS = parseInt(process.env.OCTOCODE_POLL_INTERVAL || '500', 10);
48
+
49
+ interface LockData {
50
+ pid: number;
51
+ timestamp: number;
52
+ }
53
+
54
+ interface HealthResponse {
55
+ status: 'ok' | 'initializing' | string;
56
+ }
57
+
58
+ // =============================================================================
59
+ // Atomic Mutex Lock (Based on Snyk pattern - O_EXCL for atomic creation)
60
+ // =============================================================================
61
+
62
+ function ensureLockDir(): void {
63
+ if (!existsSync(LOCK_DIR)) {
64
+ mkdirSync(LOCK_DIR, { recursive: true });
65
+ }
66
+ }
67
+
68
+ function isLockStale(lockPath: string): boolean {
69
+ if (!existsSync(lockPath)) return true;
70
+
71
+ try {
72
+ const content = readFileSync(lockPath, 'utf-8');
73
+ if (content && content.trim().length > 0) {
74
+ const data: LockData = JSON.parse(content);
75
+
76
+ // Check timestamp
77
+ if (Date.now() - data.timestamp > LOCK_TIMEOUT_MS) {
78
+ return true;
79
+ }
80
+
81
+ // Check if process exists
82
+ try {
83
+ process.kill(data.pid, 0);
84
+ return false; // Process exists, lock is valid
85
+ } catch {
86
+ return true; // Process doesn't exist
87
+ }
88
+ }
89
+ } catch {
90
+ // Fall back to mtime check
91
+ }
92
+
93
+ // Fallback: check file modification time
94
+ try {
95
+ const stats = statSync(lockPath);
96
+ return Date.now() - stats.mtimeMs > LOCK_TIMEOUT_MS;
97
+ } catch {
98
+ return true;
99
+ }
100
+ }
101
+
102
+ function safeUnlink(filePath: string): void {
103
+ try {
104
+ if (existsSync(filePath)) {
105
+ unlinkSync(filePath);
106
+ }
107
+ } catch {
108
+ // Ignore errors
109
+ }
110
+ }
111
+
112
+ async function acquireLock(): Promise<boolean> {
113
+ ensureLockDir();
114
+
115
+ // Only retry for stale lock removal race condition, not for valid locks
116
+ const STALE_RETRY_LIMIT = 3;
117
+
118
+ for (let attempt = 0; attempt < STALE_RETRY_LIMIT; attempt++) {
119
+ try {
120
+ // Atomic create - fails with EEXIST if file exists
121
+ const fd = openSync(LOCK_FILE, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY);
122
+
123
+ const lockData: LockData = {
124
+ pid: process.pid,
125
+ timestamp: Date.now(),
126
+ };
127
+
128
+ writeSync(fd, JSON.stringify(lockData));
129
+ closeSync(fd);
130
+ return true;
131
+ } catch (err: unknown) {
132
+ const nodeErr = err as NodeJS.ErrnoException;
133
+
134
+ if (nodeErr.code === 'EEXIST') {
135
+ // Lock exists - check if stale
136
+ if (isLockStale(LOCK_FILE)) {
137
+ safeUnlink(LOCK_FILE);
138
+ // Small delay to avoid tight loop on stale lock race
139
+ await new Promise((r) => setTimeout(r, 50));
140
+ continue; // Retry after removing stale lock
141
+ }
142
+
143
+ // Lock is VALID - another process is starting server
144
+ // Don't retry, let caller fall back to waiting for server
145
+ return false;
146
+ } else {
147
+ // Unexpected error
148
+ console.error(`[server-init] Lock error: ${nodeErr.message}`);
149
+ return false;
150
+ }
151
+ }
152
+ }
153
+
154
+ return false; // Failed after stale lock retries
155
+ }
156
+
157
+ function releaseLock(): void {
158
+ try {
159
+ if (existsSync(LOCK_FILE)) {
160
+ const data: LockData = JSON.parse(readFileSync(LOCK_FILE, 'utf-8'));
161
+ // Only release if we own the lock
162
+ if (data.pid === process.pid) {
163
+ unlinkSync(LOCK_FILE);
164
+ }
165
+ }
166
+ } catch {
167
+ // Ignore errors during cleanup
168
+ }
169
+ }
170
+
171
+ // =============================================================================
172
+ // Health Check (Improved error handling)
173
+ // =============================================================================
174
+
175
+ async function checkHealth(): Promise<HealthResponse | null> {
176
+ try {
177
+ const response = await fetch(HEALTH_URL, {
178
+ signal: AbortSignal.timeout(5000),
179
+ });
180
+
181
+ if (!response.ok) {
182
+ return null;
183
+ }
184
+
185
+ return (await response.json()) as HealthResponse;
186
+ } catch (error: unknown) {
187
+ // Only log unexpected errors, not connection refused (expected when server down)
188
+ if (error instanceof Error && !error.message.includes('ECONNREFUSED')) {
189
+ console.error(`[server-init] Health check error: ${error.message}`);
190
+ }
191
+ return null;
192
+ }
193
+ }
194
+
195
+ // =============================================================================
196
+ // Server Start (Improved with error handling)
197
+ // =============================================================================
198
+
199
+ function startServer(): Promise<void> {
200
+ return new Promise((resolve, reject) => {
201
+ const scriptDir = new URL('.', import.meta.url).pathname;
202
+ const serverScript = join(scriptDir, 'server.js');
203
+
204
+ const child = spawn('node', [serverScript], {
205
+ detached: true,
206
+ stdio: 'ignore',
207
+ cwd: scriptDir,
208
+ });
209
+
210
+ // Handle spawn errors (e.g., ENOENT if node not found)
211
+ child.on('error', (err) => {
212
+ console.error(`[server-init] Failed to start server: ${err.message}`);
213
+ reject(err);
214
+ });
215
+
216
+ // Give a small window for immediate spawn errors
217
+ setTimeout(() => {
218
+ child.unref();
219
+ console.log(`[server-init] Started server process (pid: ${child.pid})`);
220
+ resolve();
221
+ }, 100);
222
+ });
223
+ }
224
+
225
+ // =============================================================================
226
+ // Wait for Ready (with exponential backoff)
227
+ // =============================================================================
228
+
229
+ async function waitForReady(): Promise<boolean> {
230
+ const startTime = Date.now();
231
+ let pollInterval = POLL_INTERVAL_MS;
232
+
233
+ while (Date.now() - startTime < MAX_WAIT_MS) {
234
+ const health = await checkHealth();
235
+
236
+ if (health?.status === 'ok') {
237
+ return true;
238
+ }
239
+
240
+ if (health?.status === 'initializing') {
241
+ console.log('[server-init] Server initializing...');
242
+ }
243
+
244
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
245
+ // Gradual backoff up to 2s
246
+ pollInterval = Math.min(pollInterval * 1.5, 2000);
247
+ }
248
+
249
+ return false;
250
+ }
251
+
252
+ // =============================================================================
253
+ // Main
254
+ // =============================================================================
255
+
256
+ async function main(): Promise<void> {
257
+ // ==========================================================================
258
+ // FAST PATH: Check if server is already running (no lock needed)
259
+ // ==========================================================================
260
+ const initialHealth = await checkHealth();
261
+
262
+ if (initialHealth?.status === 'ok') {
263
+ // Server is running - immediate success, no lock needed
264
+ console.log('ok');
265
+ process.exit(0);
266
+ }
267
+
268
+ if (initialHealth?.status === 'initializing') {
269
+ // Server is starting - just wait for it, no lock needed
270
+ console.log('[server-init] Server is initializing, waiting...');
271
+ const ready = await waitForReady();
272
+ if (ready) {
273
+ console.log('ok');
274
+ process.exit(0);
275
+ } else {
276
+ console.error('[server-init] ERROR: Server stuck in initializing state');
277
+ process.exit(1);
278
+ }
279
+ }
280
+
281
+ // ==========================================================================
282
+ // SLOW PATH: Server not running - need lock to start it
283
+ // ==========================================================================
284
+ const lockAcquired = await acquireLock();
285
+
286
+ if (!lockAcquired) {
287
+ // Another process is starting the server - wait for it
288
+ console.log('[server-init] Another process is starting server, waiting...');
289
+ const ready = await waitForReady();
290
+ if (ready) {
291
+ console.log('ok');
292
+ process.exit(0);
293
+ } else {
294
+ console.error('[server-init] ERROR: Timeout waiting for server');
295
+ process.exit(1);
296
+ }
297
+ }
298
+
299
+ try {
300
+ // Double-check health after acquiring lock (another process may have started it)
301
+ const health = await checkHealth();
302
+
303
+ if (health?.status === 'ok') {
304
+ console.log('ok');
305
+ releaseLock();
306
+ process.exit(0);
307
+ }
308
+
309
+ if (health?.status === 'initializing') {
310
+ console.log('[server-init] Server is initializing, waiting...');
311
+ const ready = await waitForReady();
312
+ if (ready) {
313
+ console.log('ok');
314
+ releaseLock();
315
+ process.exit(0);
316
+ } else {
317
+ console.error('[server-init] ERROR: Server stuck in initializing state');
318
+ releaseLock();
319
+ process.exit(1);
320
+ }
321
+ }
322
+
323
+ // Server not running - start it
324
+ console.log('[server-init] Server not running, starting...');
325
+
326
+ try {
327
+ await startServer();
328
+ } catch {
329
+ console.error('[server-init] ERROR: Failed to spawn server process');
330
+ releaseLock();
331
+ process.exit(1);
332
+ }
333
+
334
+ // Wait for server to be ready
335
+ const ready = await waitForReady();
336
+ if (ready) {
337
+ console.log('ok');
338
+ releaseLock();
339
+ process.exit(0);
340
+ } else {
341
+ console.error('[server-init] ERROR: Server failed to start within timeout');
342
+ releaseLock();
343
+ process.exit(1);
344
+ }
345
+ } catch (error) {
346
+ console.error('[server-init] ERROR:', error instanceof Error ? error.message : error);
347
+ releaseLock();
348
+ process.exit(1);
349
+ }
350
+ }
351
+
352
+ // Cleanup on exit
353
+ process.on('SIGINT', () => {
354
+ releaseLock();
355
+ process.exit(130);
356
+ });
357
+
358
+ process.on('SIGTERM', () => {
359
+ releaseLock();
360
+ process.exit(143);
361
+ });
362
+
363
+ main();
@@ -0,0 +1,285 @@
1
+ import express, { type Express, type Request, type Response, type NextFunction } from 'express';
2
+ import type { Server } from 'http';
3
+ import { toolsRoutes } from './routes/tools.js';
4
+ import { promptsRoutes } from './routes/prompts.js';
5
+ import { errorHandler } from './middleware/errorHandler.js';
6
+ import { requestLogger } from './middleware/logger.js';
7
+ import { initializeProviders, initializeSession, logSessionInit } from './index.js';
8
+ import { initializeMcpContent, isMcpInitialized } from './mcpCache.js';
9
+ import { getLogsPath, initializeLogger } from './utils/logger.js';
10
+ import { getAllCircuitStates, clearAllCircuits, stopCircuitCleanup } from './utils/circuitBreaker.js';
11
+ import { agentLog, successLog, errorLog, dimLog, warnLog } from './utils/colors.js';
12
+ import { fireAndForgetWithTimeout } from './utils/asyncTimeout.js';
13
+ import { errorQueue } from './utils/errorQueue.js';
14
+
15
+ const HOST = process.env.OCTOCODE_RESEARCH_HOST || 'localhost';
16
+
17
+ const getPort = (raw?: string): number => {
18
+ const DEFAULT_PORT = 1987;
19
+ if (!raw) return DEFAULT_PORT;
20
+
21
+ const port = Number(raw);
22
+
23
+ // Strictly allow only the non-privileged, user-registered range
24
+ if (!Number.isInteger(port) || port < 1024 || port > 65535) {
25
+ throw new Error(
26
+ `Invalid OCTOCODE_RESEARCH_PORT: "${raw}". ` +
27
+ `Please provide an integer between 1024 and 65535.`
28
+ );
29
+ }
30
+
31
+ return port;
32
+ };
33
+
34
+ const PORT = getPort(process.env.OCTOCODE_RESEARCH_PORT);
35
+
36
+ const MAX_IDLE_TIME_MS = 30 * 60 * 1000; // 30 minutes idle before restart
37
+ const IDLE_CHECK_INTERVAL_MS = 120 * 1000; // Check every 2 minute
38
+
39
+ let server: Server | null = null;
40
+ let lastRequestTime: number = Date.now();
41
+ let idleCheckInterval: NodeJS.Timeout | null = null;
42
+ let isShuttingDown = false;
43
+
44
+ /**
45
+ * Check if server has been idle and should restart
46
+ */
47
+ function checkIdleRestart(): void {
48
+ const idleTime = Date.now() - lastRequestTime;
49
+ const idleSeconds = Math.floor(idleTime / 1000);
50
+
51
+ if (idleTime > MAX_IDLE_TIME_MS) {
52
+ console.log(warnLog(`āš ļø Server idle for ${idleSeconds}s (>${MAX_IDLE_TIME_MS / 1000}s). Initiating restart...`));
53
+ gracefulShutdown('IDLE_TIMEOUT');
54
+ } else if (idleTime > MAX_IDLE_TIME_MS / 2) {
55
+ // Log warning at 50% threshold (30 minutes)
56
+ console.log(dimLog(`ā° Idle: ${idleSeconds}s / ${MAX_IDLE_TIME_MS / 1000}s`));
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Start periodic idle checking
62
+ */
63
+ function startIdleCheck(): void {
64
+ if (idleCheckInterval) return;
65
+
66
+ idleCheckInterval = setInterval(checkIdleRestart, IDLE_CHECK_INTERVAL_MS);
67
+
68
+ // Unref so it doesn't prevent process exit
69
+ idleCheckInterval.unref();
70
+
71
+ console.log(dimLog(`ā±ļø Idle check started (${IDLE_CHECK_INTERVAL_MS / 1000}s interval, ${MAX_IDLE_TIME_MS / 1000}s threshold)`));
72
+ }
73
+
74
+ /**
75
+ * Stop idle checking
76
+ */
77
+ function stopIdleCheck(): void {
78
+ if (idleCheckInterval) {
79
+ clearInterval(idleCheckInterval);
80
+ idleCheckInterval = null;
81
+ console.log(successLog('āœ… Idle check interval stopped'));
82
+ }
83
+ }
84
+
85
+ export async function createServer(): Promise<Express> {
86
+ // Initialize logger first (sync for startup, async after)
87
+ initializeLogger();
88
+
89
+ // Initialize session for telemetry tracking
90
+ initializeSession();
91
+
92
+ const app = express();
93
+ app.use(express.json());
94
+
95
+ // Track activity for idle restart
96
+ app.use((_req: Request, _res: Response, next: NextFunction) => {
97
+ lastRequestTime = Date.now();
98
+ next();
99
+ });
100
+
101
+ app.use(requestLogger);
102
+
103
+ app.get('/health', (_req: Request, res: Response) => {
104
+ const memoryUsage = process.memoryUsage();
105
+ const recentErrors = errorQueue.getRecent(5);
106
+ const initialized = isMcpInitialized();
107
+ const idleTimeMs = Date.now() - lastRequestTime;
108
+
109
+ res.json({
110
+ status: initialized ? 'ok' : 'initializing',
111
+ host: HOST,
112
+ port: PORT,
113
+ version: '2.2.0',
114
+ uptime: Math.floor(process.uptime()),
115
+ processManager: 'pm2',
116
+ // Idle tracking info
117
+ idle: {
118
+ currentMs: idleTimeMs,
119
+ thresholdMs: MAX_IDLE_TIME_MS,
120
+ checkIntervalMs: IDLE_CHECK_INTERVAL_MS,
121
+ percentToRestart: Math.round((idleTimeMs / MAX_IDLE_TIME_MS) * 100),
122
+ },
123
+ memory: {
124
+ heapUsed: Math.round(memoryUsage.heapUsed / 1024 / 1024),
125
+ heapTotal: Math.round(memoryUsage.heapTotal / 1024 / 1024),
126
+ rss: Math.round(memoryUsage.rss / 1024 / 1024),
127
+ },
128
+ circuits: getAllCircuitStates(),
129
+ errors: {
130
+ queueSize: errorQueue.size,
131
+ recentErrors: recentErrors.map((e) => ({
132
+ timestamp: e.timestamp.toISOString(),
133
+ context: e.context,
134
+ message: e.error.message,
135
+ })),
136
+ },
137
+ });
138
+ });
139
+
140
+ // All tool execution via /tools/call/:toolName (readiness check applied in route files)
141
+ app.use('/tools', toolsRoutes);
142
+ app.use('/prompts', promptsRoutes);
143
+
144
+ // 404 handler for undefined routes
145
+ app.use((_req: Request, res: Response) => {
146
+ res.status(404).json({
147
+ success: false,
148
+ error: {
149
+ message: 'Route not found',
150
+ code: 'NOT_FOUND',
151
+ availableRoutes: [
152
+ 'GET /health',
153
+ 'GET /tools/list',
154
+ 'GET /tools/info/:toolName',
155
+ 'GET /tools/schemas',
156
+ 'GET /tools/system',
157
+ 'GET /tools/initContext',
158
+ 'POST /tools/call/:toolName',
159
+ 'GET /prompts/list',
160
+ 'GET /prompts/info/:promptName',
161
+ ],
162
+ hint: 'All tools are called via POST /tools/call/{toolName}',
163
+ },
164
+ });
165
+ });
166
+
167
+ app.use(errorHandler);
168
+
169
+ return app;
170
+ }
171
+
172
+ /**
173
+ * Graceful shutdown handler for PM2
174
+ * PM2 sends SIGINT, we clean up and exit (PM2 handles restart)
175
+ */
176
+ function gracefulShutdown(signal: string): void {
177
+ // Prevent double-shutdown (e.g., SIGINT + SIGTERM in quick succession)
178
+ if (isShuttingDown) {
179
+ console.log(dimLog(`Already shutting down, ignoring ${signal}`));
180
+ return;
181
+ }
182
+ isShuttingDown = true;
183
+
184
+ console.log(agentLog(`\nšŸ›‘ Received ${signal}. Starting graceful shutdown...`));
185
+
186
+ // Force exit safety net (PM2 kill_timeout is 120s, we exit at 110s)
187
+ const FORCE_EXIT_TIMEOUT_MS = 110 * 1000;
188
+ setTimeout(() => {
189
+ console.log(warnLog('āš ļø Force exiting due to drain timeout'));
190
+ process.exit(1);
191
+ }, FORCE_EXIT_TIMEOUT_MS).unref();
192
+
193
+ // 1. Stop idle check interval first
194
+ stopIdleCheck();
195
+
196
+ // 2. Stop circuit cleanup interval
197
+ stopCircuitCleanup();
198
+ console.log(successLog('āœ… Circuit cleanup interval stopped'));
199
+
200
+ // 3. Clear circuit breakers
201
+ clearAllCircuits();
202
+ console.log(successLog('āœ… Circuit breakers cleared'));
203
+
204
+ // 4. Close HTTP server (waits for connections to drain)
205
+ if (server) {
206
+ console.log(dimLog('ā³ Waiting for connections to drain...'));
207
+ server.close((err) => {
208
+ if (err) {
209
+ console.error(errorLog('āŒ Error closing server:'), err);
210
+ process.exit(1);
211
+ }
212
+ console.log(successLog('āœ… HTTP server closed'));
213
+ process.exit(0); // PM2 handles restart
214
+ });
215
+ } else {
216
+ process.exit(0);
217
+ }
218
+ }
219
+
220
+ export async function startServer(): Promise<void> {
221
+ const app = await createServer();
222
+
223
+ await new Promise<void>((resolve) => {
224
+ const httpServer = app.listen(PORT, HOST, () => {
225
+ server = httpServer;
226
+ console.log(agentLog(`šŸ” Octocode Research Server running on http://${HOST}:${PORT}`));
227
+ console.log(dimLog(`ā³ initializing context...`));
228
+
229
+ // Start background initialization (Warm Start)
230
+ initializeMcpContent()
231
+ .then(() => initializeProviders())
232
+ .then(() => {
233
+ console.log(successLog('āœ… Context initialized - Server Ready'));
234
+
235
+ // Reset idle timer after init (prevents early timeout)
236
+ lastRequestTime = Date.now();
237
+
238
+ // Start idle check after initialization
239
+ startIdleCheck();
240
+
241
+ console.log(agentLog(`šŸ“ Logs: ${getLogsPath()}`));
242
+ console.log(agentLog(`\nRoutes:`));
243
+ console.log(dimLog(` GET /health - Server health`));
244
+ console.log(dimLog(` GET /tools/initContext - System prompt + schemas (LOAD FIRST)`));
245
+ console.log(dimLog(` GET /tools/system - System prompt only`));
246
+ console.log(dimLog(` GET /tools/list - List all tools`));
247
+ console.log(dimLog(` GET /tools/info/:toolName - Tool schema (BEFORE calling)`));
248
+ console.log(dimLog(` GET /tools/schemas - All tools schemas`));
249
+ console.log(dimLog(` POST /tools/call/:toolName - Execute tool`));
250
+ console.log(dimLog(` GET /prompts/list - List prompts`));
251
+ console.log(dimLog(` GET /prompts/info/:name - Get prompt content`));
252
+
253
+ // Signal PM2 that we're ready
254
+ if (process.send) {
255
+ process.send('ready');
256
+ console.log(dimLog('šŸ“” PM2 ready signal sent'));
257
+ }
258
+
259
+ // Log session initialization after server is ready
260
+ fireAndForgetWithTimeout(
261
+ () => logSessionInit(),
262
+ 5000,
263
+ 'logSessionInit'
264
+ );
265
+ })
266
+ .catch((err) => {
267
+ console.error(errorLog('āŒ Initialization failed:'), err);
268
+ });
269
+
270
+ resolve();
271
+ });
272
+ });
273
+ }
274
+
275
+ // Signal handlers - PM2 sends SIGINT for graceful shutdown
276
+ process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
277
+ process.on('SIGINT', () => gracefulShutdown('SIGINT'));
278
+
279
+ const isMainModule = import.meta.url === `file://${process.argv[1]}`;
280
+ if (isMainModule) {
281
+ startServer().catch((err) => {
282
+ console.error(errorLog('āŒ Failed to start server:'), err);
283
+ process.exit(1);
284
+ });
285
+ }