aiwcli 0.15.5 → 0.17.0

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 (435) hide show
  1. package/README.md +108 -1124
  2. package/bin/run.js +0 -4
  3. package/dist/capabilities/branch/adapters.d.ts +2 -0
  4. package/dist/capabilities/branch/adapters.js +21 -0
  5. package/dist/capabilities/branch/contracts.d.ts +57 -0
  6. package/dist/capabilities/branch/contracts.js +1 -0
  7. package/dist/capabilities/branch/control-plane.d.ts +2 -0
  8. package/dist/capabilities/branch/control-plane.js +343 -0
  9. package/dist/capabilities/branch/runtime-core.d.ts +5 -0
  10. package/dist/capabilities/branch/runtime-core.js +36 -0
  11. package/dist/capabilities/installation/control-plane/clean-command.d.ts +41 -0
  12. package/dist/capabilities/installation/control-plane/clean-command.js +196 -0
  13. package/dist/capabilities/installation/control-plane/clear-command.d.ts +162 -0
  14. package/dist/capabilities/installation/control-plane/clear-command.js +1249 -0
  15. package/dist/capabilities/installation/control-plane/init-command.d.ts +81 -0
  16. package/dist/capabilities/installation/control-plane/init-command.js +449 -0
  17. package/dist/capabilities/launch/contracts.d.ts +86 -0
  18. package/dist/capabilities/launch/contracts.js +1 -0
  19. package/dist/capabilities/launch/control-plane/execute-launch.d.ts +2 -0
  20. package/dist/capabilities/launch/control-plane/execute-launch.js +261 -0
  21. package/dist/capabilities/launch/runtime-core/launch-decisions.d.ts +82 -0
  22. package/dist/capabilities/launch/runtime-core/launch-decisions.js +202 -0
  23. package/dist/capabilities/launch/runtime-core/launch-options.d.ts +14 -0
  24. package/dist/capabilities/launch/runtime-core/launch-options.js +69 -0
  25. package/dist/cli/base-command.d.ts +18 -0
  26. package/dist/cli/base-command.js +55 -0
  27. package/dist/commands/branch.d.ts +1 -21
  28. package/dist/commands/branch.js +25 -417
  29. package/dist/commands/clean.d.ts +1 -41
  30. package/dist/commands/clean.js +1 -196
  31. package/dist/commands/clear.d.ts +1 -161
  32. package/dist/commands/clear.js +1 -1121
  33. package/dist/commands/init/index.d.ts +1 -98
  34. package/dist/commands/init/index.js +4 -478
  35. package/dist/commands/launch.d.ts +32 -12
  36. package/dist/commands/launch.js +107 -166
  37. package/dist/lib/claude-settings-types.d.ts +31 -19
  38. package/dist/lib/config.js +1 -2
  39. package/dist/lib/context/context-formatter.d.ts +74 -0
  40. package/dist/lib/context/context-formatter.js +493 -0
  41. package/dist/lib/context/context-selector.d.ts +42 -0
  42. package/dist/lib/context/context-selector.js +451 -0
  43. package/dist/lib/context/context-store.d.ts +100 -0
  44. package/dist/lib/context/context-store.js +644 -0
  45. package/dist/lib/context/plan-manager.d.ts +54 -0
  46. package/dist/lib/context/plan-manager.js +282 -0
  47. package/dist/lib/context/task-tracker.d.ts +44 -0
  48. package/dist/lib/context/task-tracker.js +146 -0
  49. package/dist/lib/core-ide-base.d.ts +4 -0
  50. package/dist/lib/core-ide-base.js +77 -0
  51. package/dist/lib/core-installer.d.ts +5 -0
  52. package/dist/lib/core-installer.js +33 -0
  53. package/dist/lib/debug.d.ts +0 -10
  54. package/dist/lib/debug.js +0 -10
  55. package/dist/lib/env-sanitizer.d.ts +25 -0
  56. package/dist/lib/env-sanitizer.js +46 -0
  57. package/dist/lib/errors.d.ts +0 -13
  58. package/dist/lib/errors.js +0 -15
  59. package/dist/lib/git-exclude-manager.d.ts +2 -2
  60. package/dist/lib/git-exclude-manager.js +3 -3
  61. package/dist/lib/hooks/context-monitor-logic.d.ts +6 -0
  62. package/dist/lib/hooks/context-monitor-logic.js +25 -0
  63. package/dist/lib/hooks/hook-utils.d.ts +143 -0
  64. package/dist/lib/hooks/hook-utils.js +620 -0
  65. package/dist/lib/hooks/prompt-binding-logic.d.ts +7 -0
  66. package/dist/lib/hooks/prompt-binding-logic.js +50 -0
  67. package/dist/lib/hooks/session-end-logic.d.ts +5 -0
  68. package/dist/lib/hooks/session-end-logic.js +51 -0
  69. package/dist/lib/hooks-merger.js +25 -19
  70. package/dist/lib/ide-path-resolver.d.ts +19 -7
  71. package/dist/lib/ide-path-resolver.js +25 -9
  72. package/dist/lib/install-state.d.ts +34 -0
  73. package/dist/lib/install-state.js +154 -0
  74. package/dist/lib/json-io.d.ts +12 -0
  75. package/dist/lib/json-io.js +30 -0
  76. package/dist/lib/lsp-patch.d.ts +12 -0
  77. package/dist/lib/lsp-patch.js +156 -0
  78. package/dist/lib/multiplexer.d.ts +65 -0
  79. package/dist/lib/multiplexer.js +38 -0
  80. package/dist/lib/multiplexers/psmux.d.ts +55 -0
  81. package/dist/lib/multiplexers/psmux.js +324 -0
  82. package/dist/lib/multiplexers/tmux.d.ts +36 -0
  83. package/dist/lib/multiplexers/tmux.js +221 -0
  84. package/dist/lib/multiplexers/wezterm.d.ts +38 -0
  85. package/dist/lib/multiplexers/wezterm.js +225 -0
  86. package/dist/lib/mux-utils.d.ts +6 -0
  87. package/dist/lib/mux-utils.js +36 -0
  88. package/dist/lib/paths.d.ts +2 -2
  89. package/dist/lib/paths.js +2 -2
  90. package/dist/lib/platform-commands.d.ts +27 -0
  91. package/dist/lib/platform-commands.js +49 -0
  92. package/dist/lib/prompt-file-manager.d.ts +23 -0
  93. package/dist/lib/prompt-file-manager.js +41 -0
  94. package/dist/lib/runtime/agent-launcher.d.ts +67 -0
  95. package/dist/lib/runtime/agent-launcher.js +262 -0
  96. package/dist/lib/runtime/aiw-cli.d.ts +39 -0
  97. package/dist/lib/runtime/aiw-cli.js +76 -0
  98. package/dist/lib/runtime/atomic-write.d.ts +19 -0
  99. package/dist/lib/runtime/atomic-write.js +121 -0
  100. package/dist/lib/runtime/cli-args.d.ts +58 -0
  101. package/dist/lib/runtime/cli-args.js +200 -0
  102. package/dist/lib/runtime/constants.d.ts +56 -0
  103. package/dist/lib/runtime/constants.js +230 -0
  104. package/dist/lib/runtime/executable-policy.d.ts +16 -0
  105. package/dist/lib/runtime/executable-policy.js +57 -0
  106. package/dist/lib/runtime/git-state.d.ts +9 -0
  107. package/dist/lib/runtime/git-state.js +59 -0
  108. package/dist/lib/runtime/inference.d.ts +37 -0
  109. package/dist/lib/runtime/inference.js +251 -0
  110. package/dist/lib/runtime/lint-dispatch.d.ts +40 -0
  111. package/dist/lib/runtime/lint-dispatch.js +285 -0
  112. package/dist/lib/runtime/logger.d.ts +66 -0
  113. package/dist/lib/runtime/logger.js +201 -0
  114. package/dist/lib/runtime/models.d.ts +20 -0
  115. package/dist/lib/runtime/models.js +20 -0
  116. package/dist/lib/runtime/platform-adapter.d.ts +7 -0
  117. package/dist/lib/runtime/platform-adapter.js +21 -0
  118. package/dist/lib/runtime/preflight.d.ts +24 -0
  119. package/dist/lib/runtime/preflight.js +65 -0
  120. package/dist/lib/runtime/sentinel-ipc.d.ts +14 -0
  121. package/dist/lib/runtime/sentinel-ipc.js +67 -0
  122. package/dist/lib/runtime/state-io.d.ts +31 -0
  123. package/dist/lib/runtime/state-io.js +179 -0
  124. package/dist/lib/runtime/stop-words.d.ts +20 -0
  125. package/dist/lib/runtime/stop-words.js +150 -0
  126. package/dist/lib/runtime/subprocess-utils.d.ts +29 -0
  127. package/dist/lib/runtime/subprocess-utils.js +96 -0
  128. package/dist/lib/runtime/tmux-preflight.d.ts +13 -0
  129. package/dist/lib/runtime/tmux-preflight.js +78 -0
  130. package/dist/lib/runtime/utils.d.ts +62 -0
  131. package/dist/lib/runtime/utils.js +192 -0
  132. package/dist/lib/schemas.d.ts +250 -0
  133. package/dist/lib/schemas.js +216 -0
  134. package/dist/lib/sentinel-manager.d.ts +32 -0
  135. package/dist/lib/sentinel-manager.js +62 -0
  136. package/dist/lib/sentinel-wrapper.d.ts +10 -0
  137. package/dist/lib/sentinel-wrapper.js +29 -0
  138. package/dist/lib/settings-hierarchy.js +3 -20
  139. package/dist/lib/shell-adapters/bash-adapter.d.ts +18 -0
  140. package/dist/lib/shell-adapters/bash-adapter.js +69 -0
  141. package/dist/lib/shell-adapters/index.d.ts +5 -0
  142. package/dist/lib/shell-adapters/index.js +7 -0
  143. package/dist/lib/shell-adapters/powershell-adapter.d.ts +18 -0
  144. package/dist/lib/shell-adapters/powershell-adapter.js +62 -0
  145. package/dist/lib/shell-adapters/shell-adapter.d.ts +45 -0
  146. package/dist/lib/shell-adapters/shell-adapter.js +5 -0
  147. package/dist/lib/shell-quoting.d.ts +5 -0
  148. package/dist/lib/shell-quoting.js +17 -0
  149. package/dist/lib/spawn-errors.d.ts +9 -0
  150. package/dist/lib/spawn-errors.js +29 -0
  151. package/dist/lib/spawn.js +5 -11
  152. package/dist/lib/spinner.d.ts +0 -5
  153. package/dist/lib/spinner.js +0 -16
  154. package/dist/lib/template-installer.d.ts +14 -5
  155. package/dist/lib/template-installer.js +40 -38
  156. package/dist/lib/template-resolver.d.ts +6 -7
  157. package/dist/lib/template-resolver.js +26 -21
  158. package/dist/lib/template-settings-reconstructor.d.ts +7 -2
  159. package/dist/lib/template-settings-reconstructor.js +76 -45
  160. package/dist/lib/terminal-strategy.d.ts +12 -0
  161. package/dist/lib/terminal-strategy.js +55 -0
  162. package/dist/lib/terminal.d.ts +34 -4
  163. package/dist/lib/terminal.js +192 -119
  164. package/dist/lib/tmux-pane-placement.d.ts +17 -0
  165. package/dist/lib/tmux-pane-placement.js +58 -0
  166. package/dist/lib/tmux-primitives.d.ts +3 -0
  167. package/dist/lib/tmux-primitives.js +11 -0
  168. package/dist/lib/tmux-session.d.ts +32 -0
  169. package/dist/lib/tmux-session.js +87 -0
  170. package/dist/lib/tty-detection.js +1 -1
  171. package/dist/lib/types.d.ts +168 -0
  172. package/dist/lib/types.js +6 -0
  173. package/dist/lib/version.d.ts +1 -1
  174. package/dist/lib/version.js +1 -1
  175. package/dist/lib/windsurf-hooks-hierarchy.js +6 -23
  176. package/dist/platform/launch.d.ts +11 -0
  177. package/dist/platform/launch.js +11 -0
  178. package/dist/templates/CLAUDE.md +30 -40
  179. package/dist/templates/cc-native/.claude/settings.json +26 -36
  180. package/dist/templates/cc-native/CC-NATIVE-README.md +1 -1
  181. package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +20 -12
  182. package/dist/templates/cc-native/_cc-native/cc-native.config.json +2 -6
  183. package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +39 -59
  184. package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +9 -11
  185. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +2 -2
  186. package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +4 -5
  187. package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +4 -4
  188. package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +2 -27
  189. package/dist/templates/cc-native/_cc-native/hooks/validate_task_prompt.ts +7 -7
  190. package/dist/templates/cc-native/_cc-native/lib-ts/.mocharc.json +9 -0
  191. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/aggregate-agents.test.ts +118 -0
  192. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/artifacts.test.ts +234 -0
  193. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cc-native-state.test.ts +170 -0
  194. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/cli-output-parser.test.ts +73 -0
  195. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/config.test.ts +64 -0
  196. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/constants.test.ts +40 -0
  197. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/debug.test.ts +42 -0
  198. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/exports.test.ts +58 -0
  199. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/helpers.ts +107 -0
  200. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/add-plan-context.hook.test.ts +97 -0
  201. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-questions.hook.test.ts +81 -0
  202. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/hooks/plan-review.hook.test.ts +71 -0
  203. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/json-parser.test.ts +99 -0
  204. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator-agent.test.ts +288 -0
  205. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/orchestrator.test.ts +48 -0
  206. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/reviewers.test.ts +32 -0
  207. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/state.test.ts +124 -0
  208. package/dist/templates/cc-native/_cc-native/lib-ts/__tests__/verdict.test.ts +93 -0
  209. package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -0
  210. package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +6 -14
  211. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/format.ts +597 -599
  212. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/index.ts +26 -26
  213. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/tracker.ts +106 -107
  214. package/dist/templates/cc-native/_cc-native/{artifacts/lib → lib-ts/artifacts}/write.ts +118 -119
  215. package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -0
  216. package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +17 -16
  217. package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +132 -10
  218. package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +1 -1
  219. package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +6 -6
  220. package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +119 -0
  221. package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +2 -3
  222. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/graduation.ts +132 -132
  223. package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +88 -86
  224. package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +5 -6
  225. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/orchestrator.ts +70 -70
  226. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/output-builder.ts +130 -121
  227. package/dist/templates/cc-native/_cc-native/lib-ts/package-lock.json +1679 -0
  228. package/dist/templates/cc-native/_cc-native/lib-ts/package.json +24 -0
  229. package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +5 -5
  230. package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +1 -6
  231. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/plan-questions.ts +101 -101
  232. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/review-pipeline.ts +511 -543
  233. package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/__tests__/agent-providers.test.ts +262 -0
  234. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/agent.ts +71 -85
  235. package/dist/templates/{_shared/lib-ts/agent-exec → cc-native/_cc-native/lib-ts/reviewers/base}/base-agent.ts +138 -150
  236. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/index.ts +12 -12
  237. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/claude-agent.ts +66 -57
  238. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/codex-agent.ts +185 -200
  239. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/gemini-agent.ts +39 -40
  240. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/providers/orchestrator-claude-agent.ts +196 -225
  241. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/schemas.ts +201 -201
  242. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/reviewers/types.ts +21 -23
  243. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/hyde.test.ts +365 -0
  244. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/__tests__/ollama-client.test.ts +223 -0
  245. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +12 -16
  246. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +3 -2
  247. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +31 -31
  248. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +7 -8
  249. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +7 -9
  250. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +16 -19
  251. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +37 -41
  252. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +33 -43
  253. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +20 -20
  254. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +9 -10
  255. package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +3 -4
  256. package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +50 -126
  257. package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +20 -22
  258. package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +2 -2
  259. package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +14 -89
  260. package/dist/templates/cc-native/_cc-native/{plan-review/lib → lib-ts}/verdict.ts +72 -72
  261. package/dist/templates/cc-native/_cc-native/plan-review/CLAUDE.md +38 -1
  262. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/agent-selection.test.ts +345 -0
  263. package/dist/templates/cc-native/_cc-native/plan-review/lib/__tests__/preflight.test.ts +344 -0
  264. package/dist/templates/cc-native/_cc-native/plan-review/lib/agent-selection.ts +38 -16
  265. package/dist/templates/cc-native/_cc-native/plan-review/lib/preflight.ts +56 -26
  266. package/dist/templates/cc-native/_cc-native/scripts/council_debate.ts +242 -0
  267. package/dist/templates/cc-native/_cc-native/scripts/council_debate_simple.ts +294 -0
  268. package/dist/templates/cc-native/_cc-native/{plan-review/workflows → workflows}/specdev.md +9 -9
  269. package/dist/templates/core/.claude/skills/codex/SKILL.md +25 -0
  270. package/dist/templates/core/.claude/skills/devin/SKILL.md +25 -0
  271. package/dist/templates/core/.claude/skills/handoff/SKILL.md +11 -0
  272. package/dist/templates/core/.claude/skills/handoff-resume/SKILL.md +11 -0
  273. package/dist/templates/core/.claude/skills/meta-plan/SKILL.md +13 -0
  274. package/dist/templates/core/.codex/skills/codex/SKILL.md +13 -0
  275. package/dist/templates/core/.codex/skills/devin/SKILL.md +19 -0
  276. package/dist/templates/core/.codex/skills/handoff/SKILL.md +11 -0
  277. package/dist/templates/core/.codex/skills/handoff-resume/SKILL.md +11 -0
  278. package/dist/templates/core/.codex/skills/meta-plan/SKILL.md +13 -0
  279. package/dist/templates/core/.devin/AGENTS.md +5 -0
  280. package/dist/templates/core/.devin/config.json +12 -0
  281. package/dist/templates/core/.devin/skills/codex/SKILL.md +19 -0
  282. package/dist/templates/core/.devin/skills/devin/SKILL.md +13 -0
  283. package/dist/templates/core/.devin/skills/handoff/SKILL.md +11 -0
  284. package/dist/templates/core/.devin/skills/handoff-resume/SKILL.md +11 -0
  285. package/dist/templates/core/.devin/skills/meta-plan/SKILL.md +13 -0
  286. package/dist/templates/core/.windsurf/workflows/handoff-resume.md +9 -0
  287. package/dist/templates/{_shared → core}/.windsurf/workflows/handoff.md +1 -1
  288. package/dist/templates/{_shared → core}/.windsurf/workflows/meta-plan.md +1 -1
  289. package/dist/templates/core/hooks-ts/_utils/git-state.ts +2 -0
  290. package/dist/templates/{_shared → core}/hooks-ts/archive_plan.ts +15 -44
  291. package/dist/templates/core/hooks-ts/codex_explorer.ts +160 -0
  292. package/dist/templates/{_shared → core}/hooks-ts/context_monitor.ts +23 -55
  293. package/dist/templates/{_shared → core}/hooks-ts/file-suggestion.ts +5 -22
  294. package/dist/templates/{_shared → core}/hooks-ts/lint_after_edit.ts +7 -9
  295. package/dist/templates/core/hooks-ts/pre_compact.ts +36 -0
  296. package/dist/templates/{_shared → core}/hooks-ts/session_end.ts +38 -78
  297. package/dist/templates/{_shared → core}/hooks-ts/session_start.ts +5 -5
  298. package/dist/templates/core/hooks-ts/task_create_capture.ts +32 -0
  299. package/dist/templates/{_shared → core}/hooks-ts/task_update_capture.ts +9 -24
  300. package/dist/templates/core/hooks-ts/user_prompt_submit.ts +46 -0
  301. package/dist/templates/{_shared → core}/lib-ts/CLAUDE.md +27 -16
  302. package/dist/templates/{_shared → core}/lib-ts/context/CLAUDE.md +9 -6
  303. package/dist/templates/{_shared → core}/lib-ts/context/context-formatter.ts +16 -21
  304. package/dist/templates/{_shared → core}/lib-ts/context/context-selector.ts +8 -6
  305. package/dist/templates/{_shared → core}/lib-ts/context/context-store.ts +59 -20
  306. package/dist/templates/{_shared → core}/lib-ts/context/plan-manager.ts +19 -15
  307. package/dist/templates/{_shared → core}/lib-ts/context/task-tracker.ts +3 -3
  308. package/dist/templates/core/lib-ts/hooks/context-monitor-logic.ts +32 -0
  309. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/hooks}/hook-utils.ts +179 -41
  310. package/dist/templates/core/lib-ts/hooks/prompt-binding-logic.ts +80 -0
  311. package/dist/templates/core/lib-ts/hooks/session-end-logic.ts +82 -0
  312. package/dist/templates/core/lib-ts/package.json +19 -0
  313. package/dist/templates/core/lib-ts/runtime/agent-launcher.ts +369 -0
  314. package/dist/templates/core/lib-ts/runtime/aiw-cli.ts +108 -0
  315. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/atomic-write.ts +12 -7
  316. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/cli-args.ts +24 -8
  317. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/constants.ts +326 -324
  318. package/dist/templates/core/lib-ts/runtime/executable-policy.ts +89 -0
  319. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/git-state.ts +6 -4
  320. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/inference.ts +60 -23
  321. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/lint-dispatch.ts +25 -23
  322. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/logger.ts +32 -29
  323. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/models.ts +9 -2
  324. package/dist/templates/core/lib-ts/runtime/platform-adapter.ts +33 -0
  325. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/preflight.ts +4 -3
  326. package/dist/templates/core/lib-ts/runtime/sentinel-ipc.ts +91 -0
  327. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/state-io.ts +20 -11
  328. package/dist/templates/core/lib-ts/runtime/stop-words.ts +185 -0
  329. package/dist/templates/core/lib-ts/runtime/subprocess-utils.ts +147 -0
  330. package/dist/templates/core/lib-ts/runtime/tmux-preflight.ts +93 -0
  331. package/dist/templates/{_shared/lib-ts/base → core/lib-ts/runtime}/utils.ts +34 -4
  332. package/dist/templates/core/lib-ts/schemas.ts +233 -0
  333. package/dist/templates/{_shared → core}/lib-ts/templates/formatters.ts +7 -5
  334. package/dist/templates/{_shared → core}/lib-ts/templates/plan-context.ts +2 -1
  335. package/dist/templates/{_shared → core}/lib-ts/tsconfig.json +3 -1
  336. package/dist/templates/{_shared → core}/lib-ts/types.ts +78 -77
  337. package/dist/templates/core/scripts/resolve-run.ts +93 -0
  338. package/dist/templates/{_shared → core}/scripts/resolve_context.ts +3 -3
  339. package/dist/templates/{_shared → core}/scripts/status_line.ts +26 -21
  340. package/dist/templates/core/skills/codex/CLAUDE.md +83 -0
  341. package/dist/templates/{_shared → core}/skills/codex/SKILL.md +27 -18
  342. package/dist/templates/{_shared → core}/skills/codex/lib/codex-watcher.ts +79 -113
  343. package/dist/templates/{_shared → core}/skills/codex/scripts/launch-codex.ts +134 -148
  344. package/dist/templates/{_shared → core}/skills/codex/scripts/watch-codex.ts +6 -4
  345. package/dist/templates/core/skills/devin/CLAUDE.md +122 -0
  346. package/dist/templates/core/skills/devin/SKILL.md +73 -0
  347. package/dist/templates/core/skills/devin/lib/devin-watcher.ts +300 -0
  348. package/dist/templates/core/skills/devin/scripts/launch-devin.ts +258 -0
  349. package/dist/templates/{_shared → core}/skills/handoff-system/CLAUDE.md +436 -433
  350. package/dist/templates/{_shared → core}/skills/handoff-system/lib/document-generator.ts +9 -7
  351. package/dist/templates/{_shared → core}/skills/handoff-system/lib/handoff-reader.ts +6 -4
  352. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/resume_handoff.ts +10 -8
  353. package/dist/templates/{_shared → core}/skills/handoff-system/scripts/save_handoff.ts +12 -10
  354. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff-resume.md +2 -2
  355. package/dist/templates/{_shared → core}/skills/handoff-system/workflows/handoff.md +6 -5
  356. package/dist/templates/{_shared → core}/skills/meta-plan/CLAUDE.md +2 -1
  357. package/dist/templates/{_shared → core}/skills/meta-plan/workflows/meta-plan.md +8 -7
  358. package/oclif.manifest.json +89 -13
  359. package/package.json +13 -12
  360. package/dist/lib/base-command.d.ts +0 -114
  361. package/dist/lib/base-command.js +0 -153
  362. package/dist/lib/env-compat.d.ts +0 -18
  363. package/dist/lib/env-compat.js +0 -23
  364. package/dist/lib/stdin.d.ts +0 -48
  365. package/dist/lib/stdin.js +0 -60
  366. package/dist/templates/_shared/.claude/settings.json +0 -120
  367. package/dist/templates/_shared/.claude/skills/codex/SKILL.md +0 -35
  368. package/dist/templates/_shared/.claude/skills/handoff/SKILL.md +0 -13
  369. package/dist/templates/_shared/.claude/skills/handoff-resume/SKILL.md +0 -13
  370. package/dist/templates/_shared/.claude/skills/meta-plan/SKILL.md +0 -43
  371. package/dist/templates/_shared/.codex/workflows/codex.md +0 -11
  372. package/dist/templates/_shared/.codex/workflows/handoff.md +0 -226
  373. package/dist/templates/_shared/.codex/workflows/meta-plan.md +0 -347
  374. package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +0 -2
  375. package/dist/templates/_shared/hooks-ts/pre_compact.ts +0 -49
  376. package/dist/templates/_shared/hooks-ts/task_create_capture.ts +0 -48
  377. package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +0 -93
  378. package/dist/templates/_shared/lib-ts/agent-exec/backends/headless.ts +0 -33
  379. package/dist/templates/_shared/lib-ts/agent-exec/backends/index.ts +0 -6
  380. package/dist/templates/_shared/lib-ts/agent-exec/backends/tmux.ts +0 -119
  381. package/dist/templates/_shared/lib-ts/agent-exec/execution-backend.ts +0 -50
  382. package/dist/templates/_shared/lib-ts/agent-exec/index.ts +0 -6
  383. package/dist/templates/_shared/lib-ts/agent-exec/structured-output.ts +0 -166
  384. package/dist/templates/_shared/lib-ts/base/launchers/tmux-launcher.ts +0 -173
  385. package/dist/templates/_shared/lib-ts/base/launchers/window-launcher.ts +0 -93
  386. package/dist/templates/_shared/lib-ts/base/launchers/wt-launcher.ts +0 -64
  387. package/dist/templates/_shared/lib-ts/base/pane-launcher.ts +0 -55
  388. package/dist/templates/_shared/lib-ts/base/sentinel-ipc.ts +0 -87
  389. package/dist/templates/_shared/lib-ts/base/stop-words.ts +0 -184
  390. package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +0 -249
  391. package/dist/templates/_shared/lib-ts/base/tmux-driver.ts +0 -341
  392. package/dist/templates/_shared/lib-ts/base/tmux-pane-placement.ts +0 -78
  393. package/dist/templates/_shared/lib-ts/package.json +0 -20
  394. package/dist/templates/_shared/scripts/resolve-run.ts +0 -62
  395. package/dist/templates/_shared/skills/codex/CLAUDE.md +0 -70
  396. package/dist/templates/cc-native/_cc-native/CLAUDE.md +0 -73
  397. package/dist/templates/cc-native/_cc-native/artifacts/CLAUDE.md +0 -64
  398. package/dist/templates/cc-native/_cc-native/lib-ts/CLAUDE.md +0 -70
  399. package/dist/templates/cc-native/_cc-native/plan-review/CODING-STANDARDS-CHECKLIST.md +0 -75
  400. package/dist/templates/cc-native/_cc-native/plan-review/agents/CLAUDE.md +0 -143
  401. package/dist/templates/cc-native/_cc-native/plan-review/agents/PLAN-ORCHESTRATOR.md +0 -213
  402. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-questions/PLAN-QUESTIONER.md +0 -70
  403. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-EVOLUTION.md +0 -62
  404. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-PATTERNS.md +0 -61
  405. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ARCH-STRUCTURE.md +0 -62
  406. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/ASSUMPTION-TRACER.md +0 -56
  407. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CLARITY-AUDITOR.md +0 -53
  408. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-FEASIBILITY.md +0 -66
  409. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-GAPS.md +0 -70
  410. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/COMPLETENESS-ORDERING.md +0 -62
  411. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/CONSTRAINT-VALIDATOR.md +0 -72
  412. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-ADR-VALIDATOR.md +0 -61
  413. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DESIGN-SCALE-MATCHER.md +0 -64
  414. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DEVILS-ADVOCATE.md +0 -56
  415. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/DOCUMENTATION-PHILOSOPHY.md +0 -86
  416. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HANDOFF-READINESS.md +0 -59
  417. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/HIDDEN-COMPLEXITY.md +0 -58
  418. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/INCREMENTAL-DELIVERY.md +0 -66
  419. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-DEPENDENCY.md +0 -62
  420. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-FMEA.md +0 -66
  421. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-PREMORTEM.md +0 -71
  422. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/RISK-REVERSIBILITY.md +0 -74
  423. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SCOPE-BOUNDARY.md +0 -77
  424. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SIMPLICITY-GUARDIAN.md +0 -62
  425. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/SKEPTIC.md +0 -68
  426. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-BEHAVIOR-AUDITOR.md +0 -61
  427. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-CHARACTERIZATION.md +0 -71
  428. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-FIRST-VALIDATOR.md +0 -61
  429. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TESTDRIVEN-PYRAMID-ANALYZER.md +0 -61
  430. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-COSTS.md +0 -67
  431. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/TRADEOFF-STAKEHOLDERS.md +0 -65
  432. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-COVERAGE.md +0 -74
  433. package/dist/templates/cc-native/_cc-native/plan-review/agents/plan-review/VERIFY-STRENGTH.md +0 -69
  434. package/dist/templates/cc-native/_cc-native/plan-review/lib/corroboration.ts +0 -172
  435. package/dist/templates/cc-native/_cc-native/plan-review/lib/reviewers/base/base-agent.ts +0 -7
@@ -0,0 +1,365 @@
1
+ import { expect } from "chai";
2
+
3
+ // Inline versions of HyDE functions for testing (avoids module loading issues with types.ts)
4
+
5
+ const HYDE_SYSTEM_PROMPT = `You are a knowledge base assistant. Given a user query about past coding sessions, generate a hypothetical answer that MIGHT exist in session transcripts.
6
+
7
+ Rules:
8
+ - Write 2-3 sentences maximum (under 200 tokens)
9
+ - Use specific technical language: file names, function names, error messages, tool names
10
+ - Describe actions taken, decisions made, or problems solved
11
+ - Do NOT say "I don't know" or ask clarifying questions
12
+ - Be concrete and specific, even if speculative
13
+
14
+ Example:
15
+
16
+ Query: "How did we fix the authentication redirect loop?"
17
+
18
+ Hypothetical Answer: "The redirect loop was caused by middleware checking session.user before the session was populated. We moved the auth check to a route-level guard in src/middleware/auth.ts and updated the session initialization order in app.ts to populate user data before routing."`;
19
+
20
+ function averageEmbeddings(embeddings: Float32Array[]): Float32Array {
21
+ if (embeddings.length === 0) {
22
+ throw new Error("No embeddings to average");
23
+ }
24
+
25
+ const dim = embeddings[0].length;
26
+ const avg = new Float32Array(dim);
27
+
28
+ for (const emb of embeddings) {
29
+ for (let i = 0; i < dim; i++) {
30
+ avg[i] += emb[i];
31
+ }
32
+ }
33
+
34
+ const n = embeddings.length;
35
+ for (let i = 0; i < dim; i++) {
36
+ avg[i] /= n;
37
+ }
38
+
39
+ return avg;
40
+ }
41
+
42
+ async function hydeQueryEmbedding(
43
+ query: string,
44
+ config: {
45
+ numResponses: number;
46
+ maxTokens: number;
47
+ timeout: number;
48
+ fallbackToQuery: boolean;
49
+ },
50
+ generateTextFn: any,
51
+ embedFn: any,
52
+ embedOneFn: any,
53
+ ): Promise<Float32Array> {
54
+ const promises = Array.from({ length: config.numResponses }, (_, i) =>
55
+ generateTextFn(query, {
56
+ systemPrompt: HYDE_SYSTEM_PROMPT,
57
+ maxTokens: config.maxTokens,
58
+ timeout: config.timeout,
59
+ temperature: 0.7,
60
+ }),
61
+ );
62
+
63
+ const results = await Promise.all(promises);
64
+ const responses = results
65
+ .filter((r: any) => r.success && r.text.trim().length > 20)
66
+ .map((r: any) => r.text.trim());
67
+
68
+ if (responses.length < 3) {
69
+ if (config.fallbackToQuery) {
70
+ return embedOneFn(query);
71
+ }
72
+ throw new Error("HyDE generation failed: insufficient responses");
73
+ }
74
+
75
+ const embeddings = await embedFn(responses);
76
+ const avg = averageEmbeddings(embeddings);
77
+
78
+ return avg;
79
+ }
80
+
81
+ describe("hyde (HyDE logic)", () => {
82
+ describe("averageEmbeddings", () => {
83
+ it("averages embeddings correctly", () => {
84
+ const emb1 = new Float32Array([1.0, 2.0, 3.0]);
85
+ const emb2 = new Float32Array([2.0, 4.0, 6.0]);
86
+ const emb3 = new Float32Array([3.0, 6.0, 9.0]);
87
+
88
+ const result = averageEmbeddings([emb1, emb2, emb3]);
89
+
90
+ expect(Array.from(result)).to.deep.equal([2.0, 4.0, 6.0]);
91
+ });
92
+
93
+ it("preserves dimensionality", () => {
94
+ const emb1 = new Float32Array([1.0, 2.0, 3.0, 4.0, 5.0]);
95
+ const emb2 = new Float32Array([5.0, 4.0, 3.0, 2.0, 1.0]);
96
+
97
+ const result = averageEmbeddings([emb1, emb2]);
98
+
99
+ expect(result.length).to.equal(5);
100
+ expect(Array.from(result)).to.deep.equal([3.0, 3.0, 3.0, 3.0, 3.0]);
101
+ });
102
+
103
+ it("handles single embedding", () => {
104
+ const emb = new Float32Array([10.0, 20.0, 30.0]);
105
+
106
+ const result = averageEmbeddings([emb]);
107
+
108
+ expect(Array.from(result)).to.deep.equal([10.0, 20.0, 30.0]);
109
+ });
110
+
111
+ it("throws error for empty array", () => {
112
+ expect(() => averageEmbeddings([])).to.throw("No embeddings to average");
113
+ });
114
+ });
115
+
116
+ describe("hydeQueryEmbedding", () => {
117
+ it("generates hypothetical responses and returns averaged embedding", async () => {
118
+ const mockGenerateText = async () => ({
119
+ success: true,
120
+ text: "This is a hypothetical response about fixing authentication bugs in the login module.",
121
+ latency_ms: 500,
122
+ });
123
+
124
+ const mockEmbed = async (texts: string[]) => {
125
+ return texts.map(() => new Float32Array([1.0, 2.0, 3.0, 4.0]));
126
+ };
127
+
128
+ const mockEmbedOne = async () => new Float32Array([0, 0, 0, 0]);
129
+
130
+ const result = await hydeQueryEmbedding(
131
+ "How did we fix auth bugs?",
132
+ {
133
+ numResponses: 5,
134
+ maxTokens: 200,
135
+ timeout: 10000,
136
+ fallbackToQuery: true,
137
+ },
138
+ mockGenerateText,
139
+ mockEmbed,
140
+ mockEmbedOne,
141
+ );
142
+
143
+ expect(result).to.be.instanceOf(Float32Array);
144
+ expect(result.length).to.equal(4);
145
+ expect(Array.from(result)).to.deep.equal([1.0, 2.0, 3.0, 4.0]);
146
+ });
147
+
148
+ it("averages different embeddings correctly", async () => {
149
+ const mockGenerateText = async () => ({
150
+ success: true,
151
+ text: "Hypothetical response text that is long enough to pass the filter.",
152
+ latency_ms: 500,
153
+ });
154
+
155
+ let callCount = 0;
156
+ const mockEmbed = async (texts: string[]) => {
157
+ return texts.map(() => {
158
+ callCount++;
159
+ if (callCount === 1) return new Float32Array([1.0, 2.0, 3.0]);
160
+ if (callCount === 2) return new Float32Array([2.0, 4.0, 6.0]);
161
+ return new Float32Array([3.0, 6.0, 9.0]);
162
+ });
163
+ };
164
+
165
+ const mockEmbedOne = async () => new Float32Array([0, 0, 0]);
166
+
167
+ const result = await hydeQueryEmbedding(
168
+ "test query",
169
+ {
170
+ numResponses: 3,
171
+ maxTokens: 200,
172
+ timeout: 10000,
173
+ fallbackToQuery: true,
174
+ },
175
+ mockGenerateText,
176
+ mockEmbed,
177
+ mockEmbedOne,
178
+ );
179
+
180
+ expect(Array.from(result)).to.deep.equal([2.0, 4.0, 6.0]);
181
+ });
182
+
183
+ it("falls back to direct query embedding when < 3 responses", async () => {
184
+ let callCount = 0;
185
+ const mockGenerateText = async () => {
186
+ callCount++;
187
+ if (callCount <= 2) {
188
+ return {
189
+ success: true,
190
+ text: "This is a valid response with sufficient length to pass filter.",
191
+ latency_ms: 500,
192
+ };
193
+ }
194
+ return {
195
+ success: false,
196
+ text: "",
197
+ error: "Generation failed",
198
+ latency_ms: 100,
199
+ };
200
+ };
201
+
202
+ const mockEmbed = async () => [];
203
+ const mockEmbedOne = async (query: string) => {
204
+ return new Float32Array([10.0, 20.0, 30.0]);
205
+ };
206
+
207
+ const result = await hydeQueryEmbedding(
208
+ "test query",
209
+ {
210
+ numResponses: 5,
211
+ maxTokens: 200,
212
+ timeout: 10000,
213
+ fallbackToQuery: true,
214
+ },
215
+ mockGenerateText,
216
+ mockEmbed,
217
+ mockEmbedOne,
218
+ );
219
+
220
+ expect(Array.from(result)).to.deep.equal([10.0, 20.0, 30.0]);
221
+ });
222
+
223
+ it("throws error when < 3 responses and fallbackToQuery is false", async () => {
224
+ const mockGenerateText = async () => ({
225
+ success: false,
226
+ text: "",
227
+ error: "All generations failed",
228
+ latency_ms: 100,
229
+ });
230
+
231
+ const mockEmbed = async () => [];
232
+ const mockEmbedOne = async () => new Float32Array([0]);
233
+
234
+ try {
235
+ await hydeQueryEmbedding(
236
+ "test query",
237
+ {
238
+ numResponses: 5,
239
+ maxTokens: 200,
240
+ timeout: 10000,
241
+ fallbackToQuery: false,
242
+ },
243
+ mockGenerateText,
244
+ mockEmbed,
245
+ mockEmbedOne,
246
+ );
247
+ expect.fail("Should have thrown error");
248
+ } catch (e: any) {
249
+ expect(e.message).to.include("HyDE generation failed");
250
+ expect(e.message).to.include("insufficient responses");
251
+ }
252
+ });
253
+
254
+ it("filters out responses shorter than 20 characters", async () => {
255
+ let callCount = 0;
256
+ const mockGenerateText = async () => {
257
+ callCount++;
258
+ if (callCount <= 2) {
259
+ return {
260
+ success: true,
261
+ text: "Too short",
262
+ latency_ms: 500,
263
+ };
264
+ }
265
+ return {
266
+ success: true,
267
+ text: "This is a sufficiently long response that passes the filter.",
268
+ latency_ms: 500,
269
+ };
270
+ };
271
+
272
+ const mockEmbed = async (texts: string[]) => {
273
+ return texts.map(() => new Float32Array([5.0, 10.0]));
274
+ };
275
+
276
+ const mockEmbedOne = async () => new Float32Array([0, 0]);
277
+
278
+ const result = await hydeQueryEmbedding(
279
+ "test",
280
+ {
281
+ numResponses: 5,
282
+ maxTokens: 200,
283
+ timeout: 10000,
284
+ fallbackToQuery: true,
285
+ },
286
+ mockGenerateText,
287
+ mockEmbed,
288
+ mockEmbedOne,
289
+ );
290
+
291
+ // Only 3 long responses should pass, meeting threshold
292
+ expect(Array.from(result)).to.deep.equal([5.0, 10.0]);
293
+ });
294
+
295
+ it("handles all failed generations by falling back", async () => {
296
+ const mockGenerateText = async () => ({
297
+ success: false,
298
+ text: "",
299
+ error: "Ollama connection refused",
300
+ latency_ms: 50,
301
+ });
302
+
303
+ const mockEmbed = async () => [];
304
+ const mockEmbedOne = async (query: string) => {
305
+ return new Float32Array([100.0, 200.0]);
306
+ };
307
+
308
+ const result = await hydeQueryEmbedding(
309
+ "test query",
310
+ {
311
+ numResponses: 5,
312
+ maxTokens: 200,
313
+ timeout: 10000,
314
+ fallbackToQuery: true,
315
+ },
316
+ mockGenerateText,
317
+ mockEmbed,
318
+ mockEmbedOne,
319
+ );
320
+
321
+ expect(Array.from(result)).to.deep.equal([100.0, 200.0]);
322
+ });
323
+
324
+ it("works with exactly 3 successful responses", async () => {
325
+ let callCount = 0;
326
+ const mockGenerateText = async () => {
327
+ callCount++;
328
+ if (callCount <= 3) {
329
+ return {
330
+ success: true,
331
+ text: "Valid hypothetical response with enough characters to pass.",
332
+ latency_ms: 500,
333
+ };
334
+ }
335
+ return {
336
+ success: false,
337
+ text: "",
338
+ error: "Failed",
339
+ latency_ms: 100,
340
+ };
341
+ };
342
+
343
+ const mockEmbed = async (texts: string[]) => {
344
+ return texts.map(() => new Float32Array([5.0, 10.0]));
345
+ };
346
+
347
+ const mockEmbedOne = async () => new Float32Array([0, 0]);
348
+
349
+ const result = await hydeQueryEmbedding(
350
+ "test",
351
+ {
352
+ numResponses: 5,
353
+ maxTokens: 200,
354
+ timeout: 10000,
355
+ fallbackToQuery: true,
356
+ },
357
+ mockGenerateText,
358
+ mockEmbed,
359
+ mockEmbedOne,
360
+ );
361
+
362
+ expect(Array.from(result)).to.deep.equal([5.0, 10.0]);
363
+ });
364
+ });
365
+ });
@@ -0,0 +1,223 @@
1
+ import { expect } from "chai";
2
+
3
+ // Simplified test approach: test the logic without importing the full module
4
+ // to avoid module-level config loading issues in types.ts
5
+
6
+ let originalFetch: typeof global.fetch;
7
+
8
+ // Inline version of generateText for testing (avoids module loading issues)
9
+ async function generateText(
10
+ prompt: string,
11
+ options?: {
12
+ systemPrompt?: string;
13
+ temperature?: number;
14
+ maxTokens?: number;
15
+ timeout?: number;
16
+ model?: string;
17
+ },
18
+ ): Promise<{ success: boolean; text: string; error?: string; latency_ms: number }> {
19
+ const startTime = Date.now();
20
+ const model = options?.model ?? "qwen2.5:1.5b";
21
+ const baseUrl = "http://localhost:11434";
22
+
23
+ try {
24
+ const response = await fetch(`${baseUrl}/api/generate`, {
25
+ method: "POST",
26
+ headers: { "Content-Type": "application/json" },
27
+ body: JSON.stringify({
28
+ model,
29
+ prompt: options?.systemPrompt
30
+ ? `${options.systemPrompt}\n\n${prompt}`
31
+ : prompt,
32
+ stream: false,
33
+ options: {
34
+ temperature: options?.temperature ?? 0.7,
35
+ num_predict: options?.maxTokens ?? 200,
36
+ },
37
+ }),
38
+ signal: AbortSignal.timeout(options?.timeout ?? 10_000),
39
+ });
40
+
41
+ if (!response.ok) {
42
+ return {
43
+ success: false,
44
+ text: "",
45
+ error: `HTTP ${response.status}: ${response.statusText}`,
46
+ latency_ms: Date.now() - startTime,
47
+ };
48
+ }
49
+
50
+ const data = await response.json();
51
+ return {
52
+ success: true,
53
+ text: data.response || "",
54
+ latency_ms: Date.now() - startTime,
55
+ };
56
+ } catch (e) {
57
+ return {
58
+ success: false,
59
+ text: "",
60
+ error: String(e),
61
+ latency_ms: Date.now() - startTime,
62
+ };
63
+ }
64
+ }
65
+
66
+ describe("ollama-client (generateText logic)", () => {
67
+ beforeEach(() => {
68
+ originalFetch = global.fetch;
69
+ });
70
+
71
+ afterEach(() => {
72
+ global.fetch = originalFetch;
73
+ });
74
+
75
+ describe("generateText", () => {
76
+ it("returns successful response with generated text", async () => {
77
+ global.fetch = async () =>
78
+ ({
79
+ ok: true,
80
+ json: async () => ({ response: "This is a generated response about coding sessions." }),
81
+ }) as Response;
82
+
83
+ const result = await generateText("How did we fix the bug?", {
84
+ systemPrompt: "You are a helpful assistant.",
85
+ maxTokens: 200,
86
+ timeout: 5000,
87
+ });
88
+
89
+ expect(result.success).to.be.true;
90
+ expect(result.text).to.equal("This is a generated response about coding sessions.");
91
+ expect(result.latency_ms).to.be.at.least(0);
92
+ expect(result.error).to.be.undefined;
93
+ });
94
+
95
+ it("handles HTTP errors gracefully", async () => {
96
+ global.fetch = async () =>
97
+ ({
98
+ ok: false,
99
+ status: 500,
100
+ statusText: "Internal Server Error",
101
+ }) as Response;
102
+
103
+ const result = await generateText("test query");
104
+
105
+ expect(result.success).to.be.false;
106
+ expect(result.text).to.equal("");
107
+ expect(result.error).to.equal("HTTP 500: Internal Server Error");
108
+ expect(result.latency_ms).to.be.at.least(0);
109
+ });
110
+
111
+ it("handles network errors gracefully", async () => {
112
+ global.fetch = async () => {
113
+ throw new Error("Network connection failed");
114
+ };
115
+
116
+ const result = await generateText("test query");
117
+
118
+ expect(result.success).to.be.false;
119
+ expect(result.text).to.equal("");
120
+ expect(result.error).to.include("Network connection failed");
121
+ expect(result.latency_ms).to.be.at.least(0);
122
+ });
123
+
124
+ it("handles timeout errors", async () => {
125
+ global.fetch = async () => {
126
+ throw new Error("TimeoutError: The operation was aborted");
127
+ };
128
+
129
+ const result = await generateText("test query", { timeout: 100 });
130
+
131
+ expect(result.success).to.be.false;
132
+ expect(result.text).to.equal("");
133
+ expect(result.error).to.include("aborted");
134
+ });
135
+
136
+ it("uses default temperature and maxTokens when not provided", async () => {
137
+ let capturedRequest: any;
138
+ global.fetch = async (url, init) => {
139
+ capturedRequest = JSON.parse(init?.body as string);
140
+ return {
141
+ ok: true,
142
+ json: async () => ({ response: "test response" }),
143
+ } as Response;
144
+ };
145
+
146
+ await generateText("test query");
147
+
148
+ expect(capturedRequest.options.temperature).to.equal(0.7);
149
+ expect(capturedRequest.options.num_predict).to.equal(200);
150
+ });
151
+
152
+ it("combines system prompt with user prompt", async () => {
153
+ let capturedRequest: any;
154
+ global.fetch = async (url, init) => {
155
+ capturedRequest = JSON.parse(init?.body as string);
156
+ return {
157
+ ok: true,
158
+ json: async () => ({ response: "test response" }),
159
+ } as Response;
160
+ };
161
+
162
+ await generateText("user query", { systemPrompt: "system instructions" });
163
+
164
+ expect(capturedRequest.prompt).to.equal("system instructions\n\nuser query");
165
+ });
166
+
167
+ it("uses custom model when provided", async () => {
168
+ let capturedRequest: any;
169
+ global.fetch = async (url, init) => {
170
+ capturedRequest = JSON.parse(init?.body as string);
171
+ return {
172
+ ok: true,
173
+ json: async () => ({ response: "test response" }),
174
+ } as Response;
175
+ };
176
+
177
+ await generateText("test", { model: "custom-model:7b" });
178
+
179
+ expect(capturedRequest.model).to.equal("custom-model:7b");
180
+ });
181
+
182
+ it("sets stream to false for non-streaming mode", async () => {
183
+ let capturedRequest: any;
184
+ global.fetch = async (url, init) => {
185
+ capturedRequest = JSON.parse(init?.body as string);
186
+ return {
187
+ ok: true,
188
+ json: async () => ({ response: "test response" }),
189
+ } as Response;
190
+ };
191
+
192
+ await generateText("test");
193
+
194
+ expect(capturedRequest.stream).to.be.false;
195
+ });
196
+
197
+ it("handles empty response text", async () => {
198
+ global.fetch = async () =>
199
+ ({
200
+ ok: true,
201
+ json: async () => ({ response: "" }),
202
+ }) as Response;
203
+
204
+ const result = await generateText("test");
205
+
206
+ expect(result.success).to.be.true;
207
+ expect(result.text).to.equal("");
208
+ });
209
+
210
+ it("handles missing response field in JSON", async () => {
211
+ global.fetch = async () =>
212
+ ({
213
+ ok: true,
214
+ json: async () => ({}),
215
+ }) as Response;
216
+
217
+ const result = await generateText("test");
218
+
219
+ expect(result.success).to.be.true;
220
+ expect(result.text).to.equal("");
221
+ });
222
+ });
223
+ });
@@ -13,17 +13,14 @@
13
13
  * bun embedding-indexer.ts --stats # Show index statistics
14
14
  */
15
15
 
16
- import { readFileSync, existsSync, readdirSync } from "node:fs";
17
- import { readdir } from "node:fs/promises";
18
- import { homedir } from "node:os";
19
- import { join } from "node:path";
20
-
16
+ import { readdir } from "fs/promises";
17
+ import { readFileSync, existsSync, readdirSync } from "fs";
18
+ import { join } from "path";
19
+ import { homedir } from "os";
21
20
  import { z } from "zod";
22
-
23
- import { logInfo, logWarn, logError } from "./logger.js";
21
+ import { RLM_INDEX_DIR, type SessionIndex } from "./types.js";
22
+ import { logInfo, logWarn, logError, logDebug } from "./logger.js";
24
23
  import { checkOllamaHealth, embed } from "./ollama-client.js";
25
- import { loadTranscript } from "./transcript-loader.js";
26
- import { RLM_INDEX_DIR } from "./types.js";
27
24
  import {
28
25
  openVectorDb,
29
26
  insertChunks,
@@ -33,6 +30,7 @@ import {
33
30
  getStats,
34
31
  type ChunkRow,
35
32
  } from "./vector-store.js";
33
+ import { loadTranscript } from "./transcript-loader.js";
36
34
 
37
35
  const HOOK_NAME = "rlm_embed_idx";
38
36
  const MAX_EMBED_CHARS = 8000;
@@ -66,12 +64,10 @@ const projectFilter = projectArg ? projectArg.split("=")[1] : null;
66
64
  if (isStats) {
67
65
  showStats();
68
66
  } else if (isBatch) {
69
- try {
70
- await runBatch();
71
- } catch (error) {
72
- logError(HOOK_NAME, `Fatal: ${error}`, { stderr: true });
67
+ runBatch().catch((e) => {
68
+ logError(HOOK_NAME, `Fatal: ${e}`, { stderr: true });
73
69
  process.exitCode = 1;
74
- }
70
+ });
75
71
  } else {
76
72
  process.stderr.write(
77
73
  "Usage: bun embedding-indexer.ts --batch [--limit=N] [--project=name]\n" +
@@ -236,9 +232,9 @@ async function runBatch(): Promise<void> {
236
232
  if (embedded % 50 === 0) {
237
233
  logInfo(HOOK_NAME, `Progress: ${embedded} sessions embedded`, { stderr: true });
238
234
  }
239
- } catch (error) {
235
+ } catch (e) {
240
236
  errors++;
241
- logWarn(HOOK_NAME, `Error embedding ${indexFile}: ${error}`);
237
+ logWarn(HOOK_NAME, `Error embedding ${indexFile}: ${e}`);
242
238
  }
243
239
  }
244
240
 
@@ -11,8 +11,9 @@
11
11
  * See: Gao et al., "Precise Zero-Shot Dense Retrieval without Relevance Labels" (ACL 2023)
12
12
  */
13
13
 
14
+ import { generateText } from "./ollama-client.js";
15
+ import { embed, embedOne } from "./ollama-client.js";
14
16
  import { logDebug, logInfo, logWarn } from "./logger.js";
15
- import { generateText , embed, embedOne } from "./ollama-client.js";
16
17
 
17
18
  const HOOK_NAME = "rlm_hyde";
18
19
 
@@ -104,7 +105,7 @@ export async function hydeQueryEmbedding(
104
105
  logInfo(HOOK_NAME, `Generating ${config.numResponses} hypothetical responses via Ollama`);
105
106
 
106
107
  // Step 1: Generate N hypothetical responses in parallel
107
- const promises = Array.from({ length: config.numResponses }, (_) =>
108
+ const promises = Array.from({ length: config.numResponses }, (_, i) =>
108
109
  generateText(query, {
109
110
  systemPrompt: HYDE_SYSTEM_PROMPT,
110
111
  maxTokens: config.maxTokens,