@roackb2/heddle 0.0.2

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 (370) hide show
  1. package/README.md +273 -0
  2. package/dist/examples/conversation.d.ts +2 -0
  3. package/dist/examples/conversation.d.ts.map +1 -0
  4. package/dist/examples/conversation.js +3 -0
  5. package/dist/examples/conversation.js.map +1 -0
  6. package/dist/examples/repo-investigator.d.ts +2 -0
  7. package/dist/examples/repo-investigator.d.ts.map +1 -0
  8. package/dist/examples/repo-investigator.js +57 -0
  9. package/dist/examples/repo-investigator.js.map +1 -0
  10. package/dist/src/__tests__/chat-activity-format.test.d.ts +2 -0
  11. package/dist/src/__tests__/chat-activity-format.test.d.ts.map +1 -0
  12. package/dist/src/__tests__/chat-activity-format.test.js +41 -0
  13. package/dist/src/__tests__/chat-activity-format.test.js.map +1 -0
  14. package/dist/src/__tests__/chat-compaction.test.d.ts +2 -0
  15. package/dist/src/__tests__/chat-compaction.test.d.ts.map +1 -0
  16. package/dist/src/__tests__/chat-compaction.test.js +24 -0
  17. package/dist/src/__tests__/chat-compaction.test.js.map +1 -0
  18. package/dist/src/__tests__/chat-format.test.d.ts +2 -0
  19. package/dist/src/__tests__/chat-format.test.d.ts.map +1 -0
  20. package/dist/src/__tests__/chat-format.test.js +124 -0
  21. package/dist/src/__tests__/chat-format.test.js.map +1 -0
  22. package/dist/src/__tests__/chat-runtime.test.d.ts +2 -0
  23. package/dist/src/__tests__/chat-runtime.test.d.ts.map +1 -0
  24. package/dist/src/__tests__/chat-runtime.test.js +39 -0
  25. package/dist/src/__tests__/chat-runtime.test.js.map +1 -0
  26. package/dist/src/__tests__/core-utils.test.d.ts +2 -0
  27. package/dist/src/__tests__/core-utils.test.d.ts.map +1 -0
  28. package/dist/src/__tests__/core-utils.test.js +87 -0
  29. package/dist/src/__tests__/core-utils.test.js.map +1 -0
  30. package/dist/src/__tests__/llm-factory.test.d.ts +2 -0
  31. package/dist/src/__tests__/llm-factory.test.d.ts.map +1 -0
  32. package/dist/src/__tests__/llm-factory.test.js +45 -0
  33. package/dist/src/__tests__/llm-factory.test.js.map +1 -0
  34. package/dist/src/__tests__/local-commands.test.d.ts +2 -0
  35. package/dist/src/__tests__/local-commands.test.d.ts.map +1 -0
  36. package/dist/src/__tests__/local-commands.test.js +163 -0
  37. package/dist/src/__tests__/local-commands.test.js.map +1 -0
  38. package/dist/src/__tests__/project-approval-rules.test.d.ts +2 -0
  39. package/dist/src/__tests__/project-approval-rules.test.d.ts.map +1 -0
  40. package/dist/src/__tests__/project-approval-rules.test.js +135 -0
  41. package/dist/src/__tests__/project-approval-rules.test.js.map +1 -0
  42. package/dist/src/__tests__/prompts.test.d.ts +2 -0
  43. package/dist/src/__tests__/prompts.test.d.ts.map +1 -0
  44. package/dist/src/__tests__/prompts.test.js +43 -0
  45. package/dist/src/__tests__/prompts.test.js.map +1 -0
  46. package/dist/src/__tests__/run-agent.test.d.ts +2 -0
  47. package/dist/src/__tests__/run-agent.test.d.ts.map +1 -0
  48. package/dist/src/__tests__/run-agent.test.js +1276 -0
  49. package/dist/src/__tests__/run-agent.test.js.map +1 -0
  50. package/dist/src/__tests__/run-shell.command.test.d.ts +2 -0
  51. package/dist/src/__tests__/run-shell.command.test.d.ts.map +1 -0
  52. package/dist/src/__tests__/run-shell.command.test.js +188 -0
  53. package/dist/src/__tests__/run-shell.command.test.js.map +1 -0
  54. package/dist/src/__tests__/smoke.test.d.ts +2 -0
  55. package/dist/src/__tests__/smoke.test.d.ts.map +1 -0
  56. package/dist/src/__tests__/smoke.test.js +314 -0
  57. package/dist/src/__tests__/smoke.test.js.map +1 -0
  58. package/dist/src/__tests__/tools.test.d.ts +2 -0
  59. package/dist/src/__tests__/tools.test.d.ts.map +1 -0
  60. package/dist/src/__tests__/tools.test.js +557 -0
  61. package/dist/src/__tests__/tools.test.js.map +1 -0
  62. package/dist/src/__tests__/trace-format.test.d.ts +2 -0
  63. package/dist/src/__tests__/trace-format.test.d.ts.map +1 -0
  64. package/dist/src/__tests__/trace-format.test.js +148 -0
  65. package/dist/src/__tests__/trace-format.test.js.map +1 -0
  66. package/dist/src/cli/ask.d.ts +11 -0
  67. package/dist/src/cli/ask.d.ts.map +1 -0
  68. package/dist/src/cli/ask.js +59 -0
  69. package/dist/src/cli/ask.js.map +1 -0
  70. package/dist/src/cli/chat/App.d.ts +5 -0
  71. package/dist/src/cli/chat/App.d.ts.map +1 -0
  72. package/dist/src/cli/chat/App.js +348 -0
  73. package/dist/src/cli/chat/App.js.map +1 -0
  74. package/dist/src/cli/chat/actions.d.ts +47 -0
  75. package/dist/src/cli/chat/actions.d.ts.map +1 -0
  76. package/dist/src/cli/chat/actions.js +215 -0
  77. package/dist/src/cli/chat/actions.js.map +1 -0
  78. package/dist/src/cli/chat/components/ActivityPanel.d.ts +11 -0
  79. package/dist/src/cli/chat/components/ActivityPanel.d.ts.map +1 -0
  80. package/dist/src/cli/chat/components/ActivityPanel.js +20 -0
  81. package/dist/src/cli/chat/components/ActivityPanel.js.map +1 -0
  82. package/dist/src/cli/chat/components/ApprovalComposer.d.ts +6 -0
  83. package/dist/src/cli/chat/components/ApprovalComposer.d.ts.map +1 -0
  84. package/dist/src/cli/chat/components/ApprovalComposer.js +30 -0
  85. package/dist/src/cli/chat/components/ApprovalComposer.js.map +1 -0
  86. package/dist/src/cli/chat/components/CommandHintPanel.d.ts +5 -0
  87. package/dist/src/cli/chat/components/CommandHintPanel.d.ts.map +1 -0
  88. package/dist/src/cli/chat/components/CommandHintPanel.js +13 -0
  89. package/dist/src/cli/chat/components/CommandHintPanel.js.map +1 -0
  90. package/dist/src/cli/chat/components/ConversationPanel.d.ts +16 -0
  91. package/dist/src/cli/chat/components/ConversationPanel.d.ts.map +1 -0
  92. package/dist/src/cli/chat/components/ConversationPanel.js +218 -0
  93. package/dist/src/cli/chat/components/ConversationPanel.js.map +1 -0
  94. package/dist/src/cli/chat/components/ModelPickerPanel.d.ts +7 -0
  95. package/dist/src/cli/chat/components/ModelPickerPanel.d.ts.map +1 -0
  96. package/dist/src/cli/chat/components/ModelPickerPanel.js +32 -0
  97. package/dist/src/cli/chat/components/ModelPickerPanel.js.map +1 -0
  98. package/dist/src/cli/chat/components/PromptInput.d.ts +29 -0
  99. package/dist/src/cli/chat/components/PromptInput.d.ts.map +1 -0
  100. package/dist/src/cli/chat/components/PromptInput.js +132 -0
  101. package/dist/src/cli/chat/components/PromptInput.js.map +1 -0
  102. package/dist/src/cli/chat/components/RecentTurnsPanel.d.ts +5 -0
  103. package/dist/src/cli/chat/components/RecentTurnsPanel.d.ts.map +1 -0
  104. package/dist/src/cli/chat/components/RecentTurnsPanel.js +10 -0
  105. package/dist/src/cli/chat/components/RecentTurnsPanel.js.map +1 -0
  106. package/dist/src/cli/chat/components/SessionPickerPanel.d.ts +12 -0
  107. package/dist/src/cli/chat/components/SessionPickerPanel.d.ts.map +1 -0
  108. package/dist/src/cli/chat/components/SessionPickerPanel.js +32 -0
  109. package/dist/src/cli/chat/components/SessionPickerPanel.js.map +1 -0
  110. package/dist/src/cli/chat/components/SlashHintPanel.d.ts +8 -0
  111. package/dist/src/cli/chat/components/SlashHintPanel.d.ts.map +1 -0
  112. package/dist/src/cli/chat/components/SlashHintPanel.js +38 -0
  113. package/dist/src/cli/chat/components/SlashHintPanel.js.map +1 -0
  114. package/dist/src/cli/chat/components/index.d.ts +10 -0
  115. package/dist/src/cli/chat/components/index.d.ts.map +1 -0
  116. package/dist/src/cli/chat/components/index.js +10 -0
  117. package/dist/src/cli/chat/components/index.js.map +1 -0
  118. package/dist/src/cli/chat/format.d.ts +23 -0
  119. package/dist/src/cli/chat/format.d.ts.map +1 -0
  120. package/dist/src/cli/chat/format.js +243 -0
  121. package/dist/src/cli/chat/format.js.map +1 -0
  122. package/dist/src/cli/chat/hooks/useAgentRun.d.ts +61 -0
  123. package/dist/src/cli/chat/hooks/useAgentRun.d.ts.map +1 -0
  124. package/dist/src/cli/chat/hooks/useAgentRun.js +463 -0
  125. package/dist/src/cli/chat/hooks/useAgentRun.js.map +1 -0
  126. package/dist/src/cli/chat/hooks/useApprovalFlow.d.ts +31 -0
  127. package/dist/src/cli/chat/hooks/useApprovalFlow.d.ts.map +1 -0
  128. package/dist/src/cli/chat/hooks/useApprovalFlow.js +145 -0
  129. package/dist/src/cli/chat/hooks/useApprovalFlow.js.map +1 -0
  130. package/dist/src/cli/chat/hooks/useChatSessions.d.ts +23 -0
  131. package/dist/src/cli/chat/hooks/useChatSessions.d.ts.map +1 -0
  132. package/dist/src/cli/chat/hooks/useChatSessions.js +124 -0
  133. package/dist/src/cli/chat/hooks/useChatSessions.js.map +1 -0
  134. package/dist/src/cli/chat/hooks/useProjectApprovals.d.ts +8 -0
  135. package/dist/src/cli/chat/hooks/useProjectApprovals.d.ts.map +1 -0
  136. package/dist/src/cli/chat/hooks/useProjectApprovals.js +33 -0
  137. package/dist/src/cli/chat/hooks/useProjectApprovals.js.map +1 -0
  138. package/dist/src/cli/chat/index.d.ts +4 -0
  139. package/dist/src/cli/chat/index.d.ts.map +1 -0
  140. package/dist/src/cli/chat/index.js +9 -0
  141. package/dist/src/cli/chat/index.js.map +1 -0
  142. package/dist/src/cli/chat/local-commands.d.ts +17 -0
  143. package/dist/src/cli/chat/local-commands.d.ts.map +1 -0
  144. package/dist/src/cli/chat/local-commands.js +180 -0
  145. package/dist/src/cli/chat/local-commands.js.map +1 -0
  146. package/dist/src/cli/chat/panels.d.ts +37 -0
  147. package/dist/src/cli/chat/panels.d.ts.map +1 -0
  148. package/dist/src/cli/chat/panels.js +142 -0
  149. package/dist/src/cli/chat/panels.js.map +1 -0
  150. package/dist/src/cli/chat/runtime.d.ts +26 -0
  151. package/dist/src/cli/chat/runtime.d.ts.map +1 -0
  152. package/dist/src/cli/chat/runtime.js +28 -0
  153. package/dist/src/cli/chat/runtime.js.map +1 -0
  154. package/dist/src/cli/chat/state/approval-rules.d.ts +21 -0
  155. package/dist/src/cli/chat/state/approval-rules.d.ts.map +1 -0
  156. package/dist/src/cli/chat/state/approval-rules.js +196 -0
  157. package/dist/src/cli/chat/state/approval-rules.js.map +1 -0
  158. package/dist/src/cli/chat/state/compaction.d.ts +13 -0
  159. package/dist/src/cli/chat/state/compaction.d.ts.map +1 -0
  160. package/dist/src/cli/chat/state/compaction.js +143 -0
  161. package/dist/src/cli/chat/state/compaction.js.map +1 -0
  162. package/dist/src/cli/chat/state/local-commands.d.ts +17 -0
  163. package/dist/src/cli/chat/state/local-commands.d.ts.map +1 -0
  164. package/dist/src/cli/chat/state/local-commands.js +169 -0
  165. package/dist/src/cli/chat/state/local-commands.js.map +1 -0
  166. package/dist/src/cli/chat/state/storage.d.ts +14 -0
  167. package/dist/src/cli/chat/state/storage.d.ts.map +1 -0
  168. package/dist/src/cli/chat/state/storage.js +144 -0
  169. package/dist/src/cli/chat/state/storage.js.map +1 -0
  170. package/dist/src/cli/chat/state/types.d.ts +69 -0
  171. package/dist/src/cli/chat/state/types.d.ts.map +1 -0
  172. package/dist/src/cli/chat/state/types.js +2 -0
  173. package/dist/src/cli/chat/state/types.js.map +1 -0
  174. package/dist/src/cli/chat/storage.d.ts +13 -0
  175. package/dist/src/cli/chat/storage.d.ts.map +1 -0
  176. package/dist/src/cli/chat/storage.js +126 -0
  177. package/dist/src/cli/chat/storage.js.map +1 -0
  178. package/dist/src/cli/chat/submit.d.ts +28 -0
  179. package/dist/src/cli/chat/submit.d.ts.map +1 -0
  180. package/dist/src/cli/chat/submit.js +90 -0
  181. package/dist/src/cli/chat/submit.js.map +1 -0
  182. package/dist/src/cli/chat/types.d.ts +51 -0
  183. package/dist/src/cli/chat/types.d.ts.map +1 -0
  184. package/dist/src/cli/chat/types.js +2 -0
  185. package/dist/src/cli/chat/types.js.map +1 -0
  186. package/dist/src/cli/chat/use-run-state.d.ts +23 -0
  187. package/dist/src/cli/chat/use-run-state.d.ts.map +1 -0
  188. package/dist/src/cli/chat/use-run-state.js +118 -0
  189. package/dist/src/cli/chat/use-run-state.js.map +1 -0
  190. package/dist/src/cli/chat/use-sessions.d.ts +21 -0
  191. package/dist/src/cli/chat/use-sessions.d.ts.map +1 -0
  192. package/dist/src/cli/chat/use-sessions.js +111 -0
  193. package/dist/src/cli/chat/use-sessions.js.map +1 -0
  194. package/dist/src/cli/chat/utils/format.d.ts +41 -0
  195. package/dist/src/cli/chat/utils/format.d.ts.map +1 -0
  196. package/dist/src/cli/chat/utils/format.js +578 -0
  197. package/dist/src/cli/chat/utils/format.js.map +1 -0
  198. package/dist/src/cli/chat/utils/runtime.d.ts +31 -0
  199. package/dist/src/cli/chat/utils/runtime.d.ts.map +1 -0
  200. package/dist/src/cli/chat/utils/runtime.js +56 -0
  201. package/dist/src/cli/chat/utils/runtime.js.map +1 -0
  202. package/dist/src/cli/chat-actions.d.ts +47 -0
  203. package/dist/src/cli/chat-actions.d.ts.map +1 -0
  204. package/dist/src/cli/chat-actions.js +215 -0
  205. package/dist/src/cli/chat-actions.js.map +1 -0
  206. package/dist/src/cli/chat-format.d.ts +23 -0
  207. package/dist/src/cli/chat-format.d.ts.map +1 -0
  208. package/dist/src/cli/chat-format.js +243 -0
  209. package/dist/src/cli/chat-format.js.map +1 -0
  210. package/dist/src/cli/chat-local-commands.d.ts +17 -0
  211. package/dist/src/cli/chat-local-commands.d.ts.map +1 -0
  212. package/dist/src/cli/chat-local-commands.js +180 -0
  213. package/dist/src/cli/chat-local-commands.js.map +1 -0
  214. package/dist/src/cli/chat-panels.d.ts +37 -0
  215. package/dist/src/cli/chat-panels.d.ts.map +1 -0
  216. package/dist/src/cli/chat-panels.js +142 -0
  217. package/dist/src/cli/chat-panels.js.map +1 -0
  218. package/dist/src/cli/chat-runtime.d.ts +26 -0
  219. package/dist/src/cli/chat-runtime.d.ts.map +1 -0
  220. package/dist/src/cli/chat-runtime.js +28 -0
  221. package/dist/src/cli/chat-runtime.js.map +1 -0
  222. package/dist/src/cli/chat-storage.d.ts +13 -0
  223. package/dist/src/cli/chat-storage.d.ts.map +1 -0
  224. package/dist/src/cli/chat-storage.js +126 -0
  225. package/dist/src/cli/chat-storage.js.map +1 -0
  226. package/dist/src/cli/chat-submit.d.ts +28 -0
  227. package/dist/src/cli/chat-submit.d.ts.map +1 -0
  228. package/dist/src/cli/chat-submit.js +90 -0
  229. package/dist/src/cli/chat-submit.js.map +1 -0
  230. package/dist/src/cli/chat-types.d.ts +51 -0
  231. package/dist/src/cli/chat-types.d.ts.map +1 -0
  232. package/dist/src/cli/chat-types.js +2 -0
  233. package/dist/src/cli/chat-types.js.map +1 -0
  234. package/dist/src/cli/chat.d.ts +4 -0
  235. package/dist/src/cli/chat.d.ts.map +1 -0
  236. package/dist/src/cli/chat.js +153 -0
  237. package/dist/src/cli/chat.js.map +1 -0
  238. package/dist/src/cli/main.d.ts +3 -0
  239. package/dist/src/cli/main.d.ts.map +1 -0
  240. package/dist/src/cli/main.js +190 -0
  241. package/dist/src/cli/main.js.map +1 -0
  242. package/dist/src/cli/useChatRunState.d.ts +23 -0
  243. package/dist/src/cli/useChatRunState.d.ts.map +1 -0
  244. package/dist/src/cli/useChatRunState.js +118 -0
  245. package/dist/src/cli/useChatRunState.js.map +1 -0
  246. package/dist/src/cli/useChatSessions.d.ts +21 -0
  247. package/dist/src/cli/useChatSessions.d.ts.map +1 -0
  248. package/dist/src/cli/useChatSessions.js +111 -0
  249. package/dist/src/cli/useChatSessions.js.map +1 -0
  250. package/dist/src/config.d.ts +4 -0
  251. package/dist/src/config.d.ts.map +1 -0
  252. package/dist/src/config.js +7 -0
  253. package/dist/src/config.js.map +1 -0
  254. package/dist/src/index.d.ts +36 -0
  255. package/dist/src/index.d.ts.map +1 -0
  256. package/dist/src/index.js +31 -0
  257. package/dist/src/index.js.map +1 -0
  258. package/dist/src/llm/anthropic.d.ts +7 -0
  259. package/dist/src/llm/anthropic.d.ts.map +1 -0
  260. package/dist/src/llm/anthropic.js +115 -0
  261. package/dist/src/llm/anthropic.js.map +1 -0
  262. package/dist/src/llm/factory.d.ts +10 -0
  263. package/dist/src/llm/factory.d.ts.map +1 -0
  264. package/dist/src/llm/factory.js +53 -0
  265. package/dist/src/llm/factory.js.map +1 -0
  266. package/dist/src/llm/openai-models.d.ts +15 -0
  267. package/dist/src/llm/openai-models.d.ts.map +1 -0
  268. package/dist/src/llm/openai-models.js +97 -0
  269. package/dist/src/llm/openai-models.js.map +1 -0
  270. package/dist/src/llm/openai.d.ts +10 -0
  271. package/dist/src/llm/openai.d.ts.map +1 -0
  272. package/dist/src/llm/openai.js +170 -0
  273. package/dist/src/llm/openai.js.map +1 -0
  274. package/dist/src/llm/types.d.ts +64 -0
  275. package/dist/src/llm/types.d.ts.map +1 -0
  276. package/dist/src/llm/types.js +5 -0
  277. package/dist/src/llm/types.js.map +1 -0
  278. package/dist/src/prompts/system-prompt.d.ts +6 -0
  279. package/dist/src/prompts/system-prompt.d.ts.map +1 -0
  280. package/dist/src/prompts/system-prompt.js +117 -0
  281. package/dist/src/prompts/system-prompt.js.map +1 -0
  282. package/dist/src/run-agent/history.d.ts +3 -0
  283. package/dist/src/run-agent/history.d.ts.map +1 -0
  284. package/dist/src/run-agent/history.js +36 -0
  285. package/dist/src/run-agent/history.js.map +1 -0
  286. package/dist/src/run-agent/mutation-tracking.d.ts +22 -0
  287. package/dist/src/run-agent/mutation-tracking.d.ts.map +1 -0
  288. package/dist/src/run-agent/mutation-tracking.js +116 -0
  289. package/dist/src/run-agent/mutation-tracking.js.map +1 -0
  290. package/dist/src/run-agent/post-mutation.d.ts +23 -0
  291. package/dist/src/run-agent/post-mutation.d.ts.map +1 -0
  292. package/dist/src/run-agent/post-mutation.js +106 -0
  293. package/dist/src/run-agent/post-mutation.js.map +1 -0
  294. package/dist/src/run-agent/progress-reminders.d.ts +13 -0
  295. package/dist/src/run-agent/progress-reminders.d.ts.map +1 -0
  296. package/dist/src/run-agent/progress-reminders.js +65 -0
  297. package/dist/src/run-agent/progress-reminders.js.map +1 -0
  298. package/dist/src/run-agent/tool-dispatch.d.ts +31 -0
  299. package/dist/src/run-agent/tool-dispatch.d.ts.map +1 -0
  300. package/dist/src/run-agent/tool-dispatch.js +114 -0
  301. package/dist/src/run-agent/tool-dispatch.js.map +1 -0
  302. package/dist/src/run-agent/util.d.ts +10 -0
  303. package/dist/src/run-agent/util.d.ts.map +1 -0
  304. package/dist/src/run-agent/util.js +64 -0
  305. package/dist/src/run-agent/util.js.map +1 -0
  306. package/dist/src/run-agent.d.ts +36 -0
  307. package/dist/src/run-agent.d.ts.map +1 -0
  308. package/dist/src/run-agent.js +477 -0
  309. package/dist/src/run-agent.js.map +1 -0
  310. package/dist/src/tools/edit-file.d.ts +10 -0
  311. package/dist/src/tools/edit-file.d.ts.map +1 -0
  312. package/dist/src/tools/edit-file.js +268 -0
  313. package/dist/src/tools/edit-file.js.map +1 -0
  314. package/dist/src/tools/execute-tool.d.ts +8 -0
  315. package/dist/src/tools/execute-tool.d.ts.map +1 -0
  316. package/dist/src/tools/execute-tool.js +31 -0
  317. package/dist/src/tools/execute-tool.js.map +1 -0
  318. package/dist/src/tools/list-files.d.ts +3 -0
  319. package/dist/src/tools/list-files.d.ts.map +1 -0
  320. package/dist/src/tools/list-files.js +49 -0
  321. package/dist/src/tools/list-files.js.map +1 -0
  322. package/dist/src/tools/read-file.d.ts +3 -0
  323. package/dist/src/tools/read-file.d.ts.map +1 -0
  324. package/dist/src/tools/read-file.js +73 -0
  325. package/dist/src/tools/read-file.js.map +1 -0
  326. package/dist/src/tools/registry.d.ts +11 -0
  327. package/dist/src/tools/registry.d.ts.map +1 -0
  328. package/dist/src/tools/registry.js +27 -0
  329. package/dist/src/tools/registry.js.map +1 -0
  330. package/dist/src/tools/report-state.d.ts +3 -0
  331. package/dist/src/tools/report-state.d.ts.map +1 -0
  332. package/dist/src/tools/report-state.js +63 -0
  333. package/dist/src/tools/report-state.js.map +1 -0
  334. package/dist/src/tools/run-shell.d.ts +41 -0
  335. package/dist/src/tools/run-shell.d.ts.map +1 -0
  336. package/dist/src/tools/run-shell.js +407 -0
  337. package/dist/src/tools/run-shell.js.map +1 -0
  338. package/dist/src/tools/search-files.d.ts +8 -0
  339. package/dist/src/tools/search-files.d.ts.map +1 -0
  340. package/dist/src/tools/search-files.js +86 -0
  341. package/dist/src/tools/search-files.js.map +1 -0
  342. package/dist/src/tools/update-plan.d.ts +8 -0
  343. package/dist/src/tools/update-plan.d.ts.map +1 -0
  344. package/dist/src/tools/update-plan.js +85 -0
  345. package/dist/src/tools/update-plan.js.map +1 -0
  346. package/dist/src/trace/format.d.ts +6 -0
  347. package/dist/src/trace/format.d.ts.map +1 -0
  348. package/dist/src/trace/format.js +94 -0
  349. package/dist/src/trace/format.js.map +1 -0
  350. package/dist/src/trace/recorder.d.ts +11 -0
  351. package/dist/src/trace/recorder.d.ts.map +1 -0
  352. package/dist/src/trace/recorder.js +21 -0
  353. package/dist/src/trace/recorder.js.map +1 -0
  354. package/dist/src/types.d.ts +110 -0
  355. package/dist/src/types.d.ts.map +1 -0
  356. package/dist/src/types.js +6 -0
  357. package/dist/src/types.js.map +1 -0
  358. package/dist/src/utils/budget.d.ts +13 -0
  359. package/dist/src/utils/budget.d.ts.map +1 -0
  360. package/dist/src/utils/budget.js +22 -0
  361. package/dist/src/utils/budget.js.map +1 -0
  362. package/dist/src/utils/errors.d.ts +14 -0
  363. package/dist/src/utils/errors.d.ts.map +1 -0
  364. package/dist/src/utils/errors.js +31 -0
  365. package/dist/src/utils/errors.js.map +1 -0
  366. package/dist/src/utils/logger.d.ts +17 -0
  367. package/dist/src/utils/logger.d.ts.map +1 -0
  368. package/dist/src/utils/logger.js +50 -0
  369. package/dist/src/utils/logger.js.map +1 -0
  370. package/package.json +57 -0
package/README.md ADDED
@@ -0,0 +1,273 @@
1
+ # Heddle
2
+
3
+ Heddle is a terminal coding agent runtime and CLI built mainly for interactive chat inside a real project directory, with tool calls, command approval, traces, and persistent chat state.
4
+
5
+ It is built for repository work such as:
6
+
7
+ - understanding an unfamiliar codebase
8
+ - searching, reading, and editing files
9
+ - running shell commands with explicit approval for risky actions
10
+ - keeping a trace of what the agent did in `.heddle/`
11
+
12
+ ## Install
13
+
14
+ Global install:
15
+
16
+ ```bash
17
+ npm install -g @roackb2/heddle
18
+ ```
19
+
20
+ Run without a global install:
21
+
22
+ ```bash
23
+ npx @roackb2/heddle
24
+ ```
25
+
26
+ The installed CLI command remains `heddle`.
27
+
28
+ ## Quick Start
29
+
30
+ 1. Set an API key for a supported provider.
31
+
32
+ ```bash
33
+ export OPENAI_API_KEY=your_key_here
34
+ # or
35
+ export ANTHROPIC_API_KEY=your_key_here
36
+ ```
37
+
38
+ 2. Move into the project you want Heddle to work on.
39
+
40
+ ```bash
41
+ cd /path/to/project
42
+ ```
43
+
44
+ 3. Start chat mode.
45
+
46
+ ```bash
47
+ heddle
48
+ ```
49
+
50
+ Heddle uses the current directory as the workspace root unless you pass `--cwd`.
51
+
52
+ The default workflow is interactive chat, not one-shot prompts. You keep a session open, inspect the repo, switch models, run direct shell commands when needed, and continue earlier sessions later.
53
+
54
+ ## What Heddle Does
55
+
56
+ Heddle runs an agent loop against your workspace:
57
+
58
+ ```text
59
+ goal
60
+ -> send transcript + tool definitions to the model
61
+ -> model answers or requests tool calls
62
+ -> execute tools in the workspace
63
+ -> append results to the transcript
64
+ -> continue until done / max steps / error
65
+ ```
66
+
67
+ Current focus:
68
+
69
+ - chat-first coding and repository workflows from the terminal
70
+ - minimal runtime behavior instead of a large framework surface
71
+ - traceability and operator control over hidden orchestration
72
+
73
+ ## Chat Workflow
74
+
75
+ Start chat in the current repo:
76
+
77
+ ```bash
78
+ heddle
79
+ heddle chat
80
+ heddle --cwd /path/to/project
81
+ heddle chat --model gpt-5.4-mini --max-steps 20
82
+ ```
83
+
84
+ Typical chat use cases:
85
+
86
+ - ask Heddle to explain architecture, code paths, tests, or build setup
87
+ - iterate on a fix over multiple prompts instead of fitting everything into one request
88
+ - inspect files, search the repo, and edit code inside one persistent session
89
+ - run direct shell commands from chat with `!<command>`
90
+ - pause and later resume earlier sessions
91
+
92
+ Useful chat commands:
93
+
94
+ - `/help`: show local chat commands
95
+ - `/continue`: resume the current session from its last interrupted or prior run
96
+ - `/model`: show the active model
97
+ - `/model list`: show the built-in shortlist
98
+ - `/model set <query>`: open the interactive model picker
99
+ - `/model <name>`: switch models directly
100
+ - `/session list`: list recent saved sessions
101
+ - `/session choose <query>`: choose a recent session interactively
102
+ - `/session new [name]`: create a new session
103
+ - `/session switch <id>`: switch to another session
104
+ - `/session continue <id>`: switch and immediately continue that session
105
+ - `/session rename <name>`: rename the current session
106
+ - `/session close <id>`: remove a saved session
107
+ - `/clear`: clear the current transcript
108
+ - `!<command>`: run a shell command directly in chat
109
+
110
+ Direct shell in chat:
111
+
112
+ ```bash
113
+ !pwd
114
+ !git status
115
+ !yarn test
116
+ ```
117
+
118
+ Read-oriented commands stay in inspect mode when possible. Workspace-changing or unclassified commands fall back to approval-gated execution.
119
+
120
+ ## CLI Usage
121
+
122
+ Supported commands:
123
+
124
+ - `heddle` or `heddle chat`: start interactive chat mode
125
+ - `heddle ask "<goal>"`: run a single prompt and exit
126
+ - `heddle init`: create a `heddle.config.json` template in the current project
127
+
128
+ Common flags:
129
+
130
+ - `--cwd <path>`: run against another workspace root
131
+ - `--model <name>`: choose the active model
132
+ - `--max-steps <n>`: limit the agent loop length
133
+
134
+ ## Supported Providers And Models
135
+
136
+ Heddle currently has working adapters for:
137
+
138
+ - OpenAI
139
+ - Anthropic
140
+
141
+ Environment variables:
142
+
143
+ - `OPENAI_API_KEY` for OpenAI models
144
+ - `ANTHROPIC_API_KEY` for Anthropic models
145
+ - dev fallback env vars are also accepted: `PERSONAL_OPENAI_API_KEY` and `PERSONAL_ANTHROPIC_API_KEY`
146
+
147
+ Default models:
148
+
149
+ - OpenAI: `gpt-5.1-codex`
150
+ - Anthropic: `claude-sonnet-4-6`
151
+
152
+ Built-in model shortlist exposed by the CLI UI:
153
+
154
+ - OpenAI: `gpt-5.4`, `gpt-5.4-pro`, `gpt-5.4-mini`, `gpt-5.4-nano`
155
+ - OpenAI: `gpt-5`, `gpt-5-pro`, `gpt-5-mini`, `gpt-5-nano`
156
+ - OpenAI: `gpt-5.2`, `gpt-5.2-pro`, `gpt-5.1`
157
+ - OpenAI: `gpt-4.1`, `gpt-4.1-mini`, `gpt-4.1-nano`
158
+ - OpenAI: `o3-pro`, `o3`, `o3-mini`, `o4-mini`
159
+ - OpenAI coding models: `gpt-5.1-codex`, `gpt-5.1-codex-max`, `gpt-5.1-codex-mini`
160
+ - Anthropic: `claude-opus-4-6`, `claude-sonnet-4-6`, `claude-haiku-4-5`
161
+ - Anthropic: `claude-opus-4-1`, `claude-opus-4-0`, `claude-sonnet-4-0`
162
+ - Anthropic: `claude-3-7-sonnet-latest`
163
+ - Anthropic: `claude-3-5-sonnet-latest`, `claude-3-5-haiku-latest`
164
+
165
+ Notes:
166
+
167
+ - model selection is inferred from the model name prefix
168
+ - Gemini model names are recognized by provider inference, but a Google adapter is not wired yet
169
+ - you can pass another model name with `--model`, but it only works if the corresponding provider adapter supports it
170
+
171
+ ## Current Functionality
172
+
173
+ The current runtime exposes a small set of repo-oriented capabilities:
174
+
175
+ - list files
176
+ - read files
177
+ - search files
178
+ - edit files
179
+ - run shell commands in inspect or approval-gated mutate mode
180
+ - report state
181
+ - update a plan during a run
182
+
183
+ Operator-facing behavior includes:
184
+
185
+ - explicit approval flow for risky tool calls and mutate commands
186
+ - project-level remembered command approvals
187
+ - per-project state under `.heddle/`
188
+ - saved chat sessions and resumable chat workflow
189
+ - trace logs for runs and tool activity
190
+ - project instruction injection from `AGENTS.md` by default
191
+
192
+ Chat usage notes:
193
+
194
+ - use `/continue` for built-in resume behavior
195
+ - use `/model`, `/model list`, or `/model set` to inspect or switch models in chat
196
+ - use `/session` commands to create, switch, continue, rename, and close saved sessions
197
+ - use `!<command>` to run shell commands directly from the composer
198
+ - during approval, `A` remembers the current mutate command for the project, while `Y` approves once and `N` denies
199
+ - if a long-running turn appears stuck, `Esc` requests an interrupt
200
+
201
+ ## Project Config
202
+
203
+ You can store project defaults in `heddle.config.json`:
204
+
205
+ ```json
206
+ {
207
+ "model": "gpt-5.1-codex",
208
+ "maxSteps": 40,
209
+ "stateDir": ".heddle",
210
+ "directShellApproval": "never",
211
+ "searchIgnoreDirs": [".git", "dist", "node_modules", ".heddle"],
212
+ "agentContextPaths": ["AGENTS.md"]
213
+ }
214
+ ```
215
+
216
+ Precedence order:
217
+
218
+ - CLI flags override `heddle.config.json`
219
+ - `heddle.config.json` overrides environment-driven defaults
220
+
221
+ Field notes:
222
+
223
+ - `stateDir`: where traces, logs, approvals, and chat state are stored
224
+ - `directShellApproval`: whether explicit `!command` input in chat still asks for approval
225
+ - `searchIgnoreDirs`: directories excluded from `search_files`
226
+ - `agentContextPaths`: project instruction files injected into the system prompt
227
+
228
+ ## Who It Is For
229
+
230
+ Heddle is for people who want a coding agent that runs in a real repository with visible traces and explicit host-side control.
231
+
232
+ It is a good fit if you want:
233
+
234
+ - a CLI-first coding assistant
235
+ - a minimal runtime you can inspect and extend
236
+ - direct workspace execution instead of a hosted IDE product
237
+
238
+ It is not trying to be:
239
+
240
+ - a no-code agent builder
241
+ - a multi-agent orchestration framework
242
+ - a general prompt workflow library
243
+
244
+ ## Runtime And Library
245
+
246
+ The npm package also exports the core runtime pieces for programmatic use, including:
247
+
248
+ - `runAgent`
249
+ - LLM adapter helpers
250
+ - built-in tools
251
+ - trace utilities
252
+
253
+ Install as a dependency with:
254
+
255
+ ```bash
256
+ npm install @roackb2/heddle
257
+ ```
258
+
259
+ The public API lives in [src/index.ts](/Users/roackb2/Studio/projects/ProjectHeddle/heddle/src/index.ts).
260
+
261
+ ## Design Direction
262
+
263
+ Heddle's long-term goal is broader than the current CLI: a credible general runtime for tool-using agents. The current implementation stays deliberately narrow and behavior-first so abstractions only get added after real runtime traces justify them.
264
+
265
+ More project context:
266
+
267
+ - [Framework Vision](/Users/roackb2/Studio/projects/ProjectHeddle/heddle/docs/framework-vision.md)
268
+ - [Project Purpose](/Users/roackb2/Studio/projects/ProjectHeddle/heddle/docs/project-purpose.md)
269
+ - [Coding Agent Roadmap](/Users/roackb2/Studio/projects/ProjectHeddle/heddle/docs/coding-agent-roadmap.md)
270
+
271
+ ## License
272
+
273
+ MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=conversation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../../examples/conversation.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { startChatCli } from '../src/cli/chat/index.js';
2
+ startChatCli();
3
+ //# sourceMappingURL=conversation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation.js","sourceRoot":"","sources":["../../examples/conversation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,YAAY,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=repo-investigator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-investigator.d.ts","sourceRoot":"","sources":["../../examples/repo-investigator.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Example: Repo Investigator
3
+ //
4
+ // Usage:
5
+ // OPENAI_API_KEY=sk-... npx tsx examples/repo-investigator.ts "What does this project do?"
6
+ // ---------------------------------------------------------------------------
7
+ import { writeFileSync, mkdirSync } from 'node:fs';
8
+ import { join } from 'node:path';
9
+ import { DEFAULT_OPENAI_MODEL, runAgent, createOpenAiAdapter, listFilesTool, readFileTool, editFileTool, searchFilesTool, reportStateTool, createRunShellInspectTool, createRunShellMutateTool, formatTraceForConsole, createLogger, } from '../src/index.js';
10
+ async function main() {
11
+ const goal = process.argv[2];
12
+ if (!goal) {
13
+ console.error('Usage: npx tsx examples/repo-investigator.ts "<goal>"');
14
+ process.exit(1);
15
+ }
16
+ const model = process.env.OPENAI_MODEL ?? DEFAULT_OPENAI_MODEL;
17
+ const maxSteps = parsePositiveInt(process.env.HEDDLE_MAX_STEPS) ?? 40;
18
+ const logger = createLogger({ pretty: true, level: 'debug' });
19
+ logger.info({ goal, model, maxSteps }, '🧵 Heddle — Repo Investigator');
20
+ const llm = createOpenAiAdapter({
21
+ model,
22
+ apiKey: process.env.OPENAI_API_KEY ?? process.env.PERSONAL_OPENAI_API_KEY,
23
+ });
24
+ const tools = [
25
+ listFilesTool,
26
+ readFileTool,
27
+ editFileTool,
28
+ searchFilesTool,
29
+ reportStateTool,
30
+ createRunShellInspectTool(),
31
+ createRunShellMutateTool(),
32
+ ];
33
+ const result = await runAgent({ goal, llm, tools, maxSteps, logger });
34
+ // Print formatted trace
35
+ console.log(formatTraceForConsole(result.trace));
36
+ // Save JSON trace
37
+ const traceDir = join(process.cwd(), 'local', 'traces');
38
+ mkdirSync(traceDir, { recursive: true });
39
+ const traceFile = join(traceDir, `trace-${Date.now()}.json`);
40
+ writeFileSync(traceFile, JSON.stringify(result.trace, null, 2));
41
+ logger.info({ traceFile }, 'Trace saved');
42
+ }
43
+ main().catch((err) => {
44
+ console.error('Fatal error:', err);
45
+ process.exit(1);
46
+ });
47
+ function parsePositiveInt(raw) {
48
+ if (!raw) {
49
+ return undefined;
50
+ }
51
+ const value = Number.parseInt(raw, 10);
52
+ if (!Number.isFinite(value) || value <= 0) {
53
+ return undefined;
54
+ }
55
+ return value;
56
+ }
57
+ //# sourceMappingURL=repo-investigator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-investigator.js","sourceRoot":"","sources":["../../examples/repo-investigator.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,6BAA6B;AAC7B,EAAE;AACF,SAAS;AACT,6FAA6F;AAC7F,8EAA8E;AAE9E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,oBAAoB,EACpB,QAAQ,EACR,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,eAAe,EACf,yBAAyB,EACzB,wBAAwB,EACxB,qBAAqB,EACrB,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,oBAAoB,CAAC;IAC/D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;IAEtE,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAE9D,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,+BAA+B,CAAC,CAAC;IAExE,MAAM,GAAG,GAAG,mBAAmB,CAAC;QAC9B,KAAK;QACL,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB;KAC1E,CAAC,CAAC;IACH,MAAM,KAAK,GAAG;QACZ,aAAa;QACb,YAAY;QACZ,YAAY;QACZ,eAAe;QACf,eAAe;QACf,yBAAyB,EAAE;QAC3B,wBAAwB,EAAE;KAC3B,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAEtE,wBAAwB;IACxB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAEjD,kBAAkB;IAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IACxD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC7D,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAChE,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,aAAa,CAAC,CAAC;AAC5C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,SAAS,gBAAgB,CAAC,GAAuB;IAC/C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chat-activity-format.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-activity-format.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/chat-activity-format.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { summarizeToolCall, toLiveEvent } from '../cli/chat/utils/format.js';
3
+ describe('chat activity formatting', () => {
4
+ it('includes read_file paths in tool call summaries', () => {
5
+ expect(summarizeToolCall('read_file', { path: 'docs/framework-vision.md' })).toBe('read_file (docs/framework-vision.md)');
6
+ });
7
+ it('includes list_files paths in tool call summaries', () => {
8
+ expect(summarizeToolCall('list_files', { path: 'src/cli/chat' })).toBe('list_files (src/cli/chat)');
9
+ });
10
+ it('includes search_files query and path in tool call summaries', () => {
11
+ expect(summarizeToolCall('search_files', { query: 'trace-1775195542429', path: '.heddle/traces' })).toBe('search_files ("trace-1775195542429" in .heddle/traces)');
12
+ });
13
+ it('includes read paths in live activity events', () => {
14
+ const event = {
15
+ type: 'tool.call',
16
+ call: { id: 'call-1', tool: 'read_file', input: { path: 'README.md' } },
17
+ step: 1,
18
+ timestamp: '2024-01-01T00:00:00Z',
19
+ };
20
+ expect(toLiveEvent(event)).toBe('running read_file (README.md)');
21
+ });
22
+ it('includes list paths in approval activity events', () => {
23
+ const event = {
24
+ type: 'tool.approval_requested',
25
+ call: { id: 'call-2', tool: 'list_files', input: { path: 'src' } },
26
+ step: 2,
27
+ timestamp: '2024-01-01T00:00:01Z',
28
+ };
29
+ expect(toLiveEvent(event)).toBe('approval needed for list_files (src)');
30
+ });
31
+ it('includes search query details in live activity events', () => {
32
+ const event = {
33
+ type: 'tool.call',
34
+ call: { id: 'call-3', tool: 'search_files', input: { query: 'trace', path: '.heddle/traces' } },
35
+ step: 3,
36
+ timestamp: '2024-01-01T00:00:02Z',
37
+ };
38
+ expect(toLiveEvent(event)).toBe('running search_files ("trace" in .heddle/traces)');
39
+ });
40
+ });
41
+ //# sourceMappingURL=chat-activity-format.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-activity-format.test.js","sourceRoot":"","sources":["../../../src/__tests__/chat-activity-format.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG7E,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,iBAAiB,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC,CAAC,CAAC,IAAI,CAC/E,sCAAsC,CACvC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,iBAAiB,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CACpE,2BAA2B,CAC5B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,CAAC,iBAAiB,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,IAAI,CACtG,wDAAwD,CACzD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,KAAK,GAAe;YACxB,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE;YACvE,IAAI,EAAE,CAAC;YACP,SAAS,EAAE,sBAAsB;SAClC,CAAC;QAEF,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,KAAK,GAAe;YACxB,IAAI,EAAE,yBAAyB;YAC/B,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YAClE,IAAI,EAAE,CAAC;YACP,SAAS,EAAE,sBAAsB;SAClC,CAAC;QAEF,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,KAAK,GAAe;YACxB,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE;YAC/F,IAAI,EAAE,CAAC;YACP,SAAS,EAAE,sBAAsB;SAClC,CAAC;QAEF,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chat-compaction.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-compaction.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/chat-compaction.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { compactChatHistory, isCompactedHistorySummary } from '../cli/chat/state/compaction.js';
3
+ import { buildConversationMessages } from '../cli/chat/utils/format.js';
4
+ describe('chat history compaction', () => {
5
+ it('compacts older transcript messages into a summary and keeps recent messages', () => {
6
+ const history = Array.from({ length: 50 }).flatMap((_, index) => [
7
+ { role: 'user', content: `User prompt ${index}: ${'u'.repeat(4000)}` },
8
+ { role: 'assistant', content: `Assistant reply ${index}: ${'a'.repeat(4000)}` },
9
+ ]);
10
+ const compacted = compactChatHistory({
11
+ history,
12
+ model: 'gpt-4.1',
13
+ });
14
+ expect(isCompactedHistorySummary(compacted.history[0])).toBe(true);
15
+ expect(compacted.history.length).toBeLessThan(history.length);
16
+ expect(compacted.history.at(-1)).toEqual(history.at(-1));
17
+ expect(compacted.history.at(-2)).toEqual(history.at(-2));
18
+ expect(compacted.context.estimatedHistoryTokens).toBeLessThan(80_000);
19
+ expect(compacted.context.compactedMessages).toBeGreaterThan(0);
20
+ const visibleMessages = buildConversationMessages(compacted.history);
21
+ expect(visibleMessages[0]?.text).toContain('Earlier conversation history was compacted');
22
+ });
23
+ });
24
+ //# sourceMappingURL=chat-compaction.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-compaction.test.js","sourceRoot":"","sources":["../../../src/__tests__/chat-compaction.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAChG,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,MAAM,OAAO,GAAkB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YAC9E,EAAE,IAAI,EAAE,MAAe,EAAE,OAAO,EAAE,eAAe,KAAK,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE;YAC/E,EAAE,IAAI,EAAE,WAAoB,EAAE,OAAO,EAAE,mBAAmB,KAAK,KAAK,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE;SACzF,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,kBAAkB,CAAC;YACnC,OAAO;YACP,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,MAAM,CAAC,yBAAyB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9D,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACtE,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QAE/D,MAAM,eAAe,GAAG,yBAAyB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,4CAA4C,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chat-format.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-format.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/chat-format.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,124 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { buildConversationMessages, formatEditPreviewHistoryMessage, formatPlanHistoryMessage } from '../cli/chat/utils/format.js';
3
+ describe('buildConversationMessages', () => {
4
+ it('renders successful edit_file tool results into visible conversation history', () => {
5
+ const history = [
6
+ { role: 'user', content: 'Update the file.' },
7
+ {
8
+ role: 'assistant',
9
+ content: 'I will update the file.',
10
+ toolCalls: [{ id: 'call-1', tool: 'edit_file', input: { path: 'src/example.ts', oldText: 'old', newText: 'new' } }],
11
+ },
12
+ {
13
+ role: 'tool',
14
+ toolCallId: 'call-1',
15
+ content: JSON.stringify({
16
+ ok: true,
17
+ output: {
18
+ path: 'src/example.ts',
19
+ action: 'replaced',
20
+ matchCount: 1,
21
+ bytesWritten: 42,
22
+ diff: {
23
+ path: 'src/example.ts',
24
+ action: 'replaced',
25
+ diff: ['--- a/src/example.ts', '+++ b/src/example.ts', '@@ -1 +1 @@', '-const value = "old";', '+const value = "new";'].join('\n'),
26
+ truncated: false,
27
+ },
28
+ },
29
+ }),
30
+ },
31
+ { role: 'assistant', content: 'Done.' },
32
+ ];
33
+ const messages = buildConversationMessages(history);
34
+ expect(messages).toHaveLength(4);
35
+ expect(messages[2]).toMatchObject({
36
+ role: 'assistant',
37
+ text: expect.stringContaining('## Edited `src/example.ts`'),
38
+ });
39
+ expect(messages[2]?.text).toContain('Action: replaced');
40
+ expect(messages[2]?.text).toContain('Matches changed: 1');
41
+ expect(messages[2]?.text).toContain('```diff');
42
+ expect(messages[2]?.text).toContain('+const value = "new";');
43
+ });
44
+ it('does not render non-edit tool results into conversation history', () => {
45
+ const history = [
46
+ { role: 'user', content: 'Inspect the repo.' },
47
+ {
48
+ role: 'assistant',
49
+ content: 'I will inspect.',
50
+ toolCalls: [{ id: 'call-1', tool: 'list_files', input: { path: '.' } }],
51
+ },
52
+ {
53
+ role: 'tool',
54
+ toolCallId: 'call-1',
55
+ content: JSON.stringify({ ok: true, output: 'README.md\nsrc/' }),
56
+ },
57
+ ];
58
+ const messages = buildConversationMessages(history);
59
+ expect(messages).toEqual([
60
+ { id: 'user-0-Inspect the repo.', role: 'user', text: 'Inspect the repo.' },
61
+ { id: 'assistant-1-I will inspect.', role: 'assistant', text: 'I will inspect.' },
62
+ ]);
63
+ });
64
+ it('renders update_plan tool results into visible checklist history', () => {
65
+ const history = [
66
+ { role: 'user', content: 'Move the project forward.' },
67
+ {
68
+ role: 'assistant',
69
+ content: 'I will plan the work first.',
70
+ toolCalls: [{ id: 'call-1', tool: 'update_plan', input: { plan: [{ step: 'Inspect roadmap', status: 'completed' }] } }],
71
+ },
72
+ {
73
+ role: 'tool',
74
+ toolCallId: 'call-1',
75
+ content: JSON.stringify({
76
+ ok: true,
77
+ output: {
78
+ explanation: 'Tracking the next implementation slice.',
79
+ plan: [
80
+ { step: 'Inspect roadmap and runtime state', status: 'completed' },
81
+ { step: 'Implement the next bounded capability', status: 'in_progress' },
82
+ { step: 'Verify with tests and build', status: 'pending' },
83
+ ],
84
+ },
85
+ }),
86
+ },
87
+ ];
88
+ const messages = buildConversationMessages(history);
89
+ expect(messages).toHaveLength(3);
90
+ expect(messages[2]?.text).toContain('## Plan');
91
+ expect(messages[2]?.text).toContain('Tracking the next implementation slice.');
92
+ expect(messages[2]?.text).toContain('- [x] Inspect roadmap and runtime state');
93
+ expect(messages[2]?.text).toContain('- [-] Implement the next bounded capability');
94
+ expect(messages[2]?.text).toContain('- [ ] Verify with tests and build');
95
+ });
96
+ it('formats a live edit preview into the same visible diff block shape', () => {
97
+ const rendered = formatEditPreviewHistoryMessage({
98
+ path: 'src/example.ts',
99
+ action: 'replaced',
100
+ diff: ['--- a/src/example.ts', '+++ b/src/example.ts', '@@ -1 +1 @@', '-old', '+new'].join('\n'),
101
+ truncated: false,
102
+ });
103
+ expect(rendered).toContain('## Edited `src/example.ts`');
104
+ expect(rendered).toContain('Action: replaced');
105
+ expect(rendered).toContain('```diff');
106
+ expect(rendered).toContain('+new');
107
+ });
108
+ it('formats a live plan update into the same visible checklist block shape', () => {
109
+ const rendered = formatPlanHistoryMessage({
110
+ explanation: 'Tracking the current implementation slice.',
111
+ plan: [
112
+ { step: 'Inspect runtime behavior', status: 'completed' },
113
+ { step: 'Implement the fix', status: 'in_progress' },
114
+ { step: 'Verify with tests', status: 'pending' },
115
+ ],
116
+ });
117
+ expect(rendered).toContain('## Plan');
118
+ expect(rendered).toContain('Tracking the current implementation slice.');
119
+ expect(rendered).toContain('- [x] Inspect runtime behavior');
120
+ expect(rendered).toContain('- [-] Implement the fix');
121
+ expect(rendered).toContain('- [ ] Verify with tests');
122
+ });
123
+ });
124
+ //# sourceMappingURL=chat-format.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-format.test.js","sourceRoot":"","sources":["../../../src/__tests__/chat-format.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=chat-runtime.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-runtime.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/chat-runtime.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,39 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
+ import { resolveApiKeyForModel, resolveChatRuntimeConfig } from '../cli/chat/utils/runtime.js';
3
+ describe('resolveChatRuntimeConfig', () => {
4
+ afterEach(() => {
5
+ vi.unstubAllEnvs();
6
+ });
7
+ it('does not fall back to OpenAI keys for Anthropic models', () => {
8
+ vi.stubEnv('OPENAI_API_KEY', 'openai-key');
9
+ vi.stubEnv('PERSONAL_OPENAI_API_KEY', '');
10
+ vi.stubEnv('ANTHROPIC_API_KEY', '');
11
+ vi.stubEnv('PERSONAL_ANTHROPIC_API_KEY', '');
12
+ const runtime = resolveChatRuntimeConfig({
13
+ workspaceRoot: '/tmp/heddle-test',
14
+ model: 'claude-sonnet-4-6',
15
+ });
16
+ expect(runtime.apiKey).toBeUndefined();
17
+ });
18
+ it('uses Anthropic keys for Anthropic models', () => {
19
+ vi.stubEnv('OPENAI_API_KEY', 'openai-key');
20
+ vi.stubEnv('ANTHROPIC_API_KEY', 'anthropic-key');
21
+ const runtime = resolveChatRuntimeConfig({
22
+ workspaceRoot: '/tmp/heddle-test',
23
+ model: 'claude-sonnet-4-6',
24
+ });
25
+ expect(runtime.apiKey).toBe('anthropic-key');
26
+ });
27
+ it('resolves the correct provider key for a session model even if startup used another provider', () => {
28
+ vi.stubEnv('OPENAI_API_KEY', 'openai-key');
29
+ vi.stubEnv('ANTHROPIC_API_KEY', 'anthropic-key');
30
+ const runtime = resolveChatRuntimeConfig({
31
+ workspaceRoot: '/tmp/heddle-test',
32
+ model: 'gpt-5.4',
33
+ });
34
+ expect(runtime.apiKey).toBe('openai-key');
35
+ expect(runtime.apiKeyProvider).toBe('openai');
36
+ expect(resolveApiKeyForModel('claude-sonnet-4-6', runtime)).toBe('anthropic-key');
37
+ });
38
+ });
39
+ //# sourceMappingURL=chat-runtime.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-runtime.test.js","sourceRoot":"","sources":["../../../src/__tests__/chat-runtime.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAE/F,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;QAC3C,EAAE,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;QAC1C,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QACpC,EAAE,CAAC,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC;QAE7C,MAAM,OAAO,GAAG,wBAAwB,CAAC;YACvC,aAAa,EAAE,kBAAkB;YACjC,KAAK,EAAE,mBAAmB;SAC3B,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;QAC3C,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;QAEjD,MAAM,OAAO,GAAG,wBAAwB,CAAC;YACvC,aAAa,EAAE,kBAAkB;YACjC,KAAK,EAAE,mBAAmB;SAC3B,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6FAA6F,EAAE,GAAG,EAAE;QACrG,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;QAC3C,EAAE,CAAC,OAAO,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;QAEjD,MAAM,OAAO,GAAG,wBAAwB,CAAC;YACvC,aAAa,EAAE,kBAAkB;YACjC,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9C,MAAM,CAAC,qBAAqB,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=core-utils.test.d.ts.map