tarsk 0.4.4 → 0.4.6

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 (366) hide show
  1. package/dist/index.js +447375 -37
  2. package/package.json +2 -2
  3. package/dist/agent/agent.error-utils.d.ts +0 -14
  4. package/dist/agent/agent.error-utils.js +0 -52
  5. package/dist/agent/agent.event-transformer.d.ts +0 -55
  6. package/dist/agent/agent.event-transformer.js +0 -175
  7. package/dist/agent/agent.executor.d.ts +0 -26
  8. package/dist/agent/agent.executor.js +0 -286
  9. package/dist/agent/agent.model-resolver.d.ts +0 -22
  10. package/dist/agent/agent.model-resolver.js +0 -67
  11. package/dist/agent/agent.process-manager.d.ts +0 -57
  12. package/dist/agent/agent.process-manager.js +0 -262
  13. package/dist/agent/agent.processing-state-manager.d.ts +0 -74
  14. package/dist/agent/agent.processing-state-manager.js +0 -87
  15. package/dist/agent/agent.prompt-loader.d.ts +0 -16
  16. package/dist/agent/agent.prompt-loader.js +0 -227
  17. package/dist/agent/agent.subagent-executor.d.ts +0 -35
  18. package/dist/agent/agent.subagent-executor.js +0 -135
  19. package/dist/bun/index.d.ts +0 -2
  20. package/dist/bun/index.js +0 -165
  21. package/dist/cli.d.ts +0 -3
  22. package/dist/cli.js +0 -22
  23. package/dist/core/crypto.d.ts +0 -29
  24. package/dist/core/crypto.js +0 -166
  25. package/dist/core/dev-server-cache.d.ts +0 -46
  26. package/dist/core/dev-server-cache.js +0 -59
  27. package/dist/core/env-manager.d.ts +0 -3
  28. package/dist/core/env-manager.js +0 -60
  29. package/dist/core/error-responses.d.ts +0 -61
  30. package/dist/core/error-responses.js +0 -64
  31. package/dist/core/logger.d.ts +0 -10
  32. package/dist/core/logger.js +0 -47
  33. package/dist/core/paths.d.ts +0 -22
  34. package/dist/core/paths.js +0 -26
  35. package/dist/core/random-words.d.ts +0 -18
  36. package/dist/core/random-words.js +0 -135
  37. package/dist/core/response-builder.d.ts +0 -50
  38. package/dist/core/response-builder.js +0 -56
  39. package/dist/core/route-helpers.d.ts +0 -47
  40. package/dist/core/route-helpers.js +0 -54
  41. package/dist/core/run-command-detector.d.ts +0 -26
  42. package/dist/core/run-command-detector.js +0 -98
  43. package/dist/core/stream-helper.d.ts +0 -44
  44. package/dist/core/stream-helper.js +0 -50
  45. package/dist/core/utils.d.ts +0 -43
  46. package/dist/core/utils.js +0 -113
  47. package/dist/core/validation.d.ts +0 -10
  48. package/dist/core/validation.js +0 -20
  49. package/dist/database/database.d.ts +0 -40
  50. package/dist/database/database.encryption.d.ts +0 -33
  51. package/dist/database/database.encryption.js +0 -62
  52. package/dist/database/database.js +0 -480
  53. package/dist/database/database.state.d.ts +0 -52
  54. package/dist/database/database.state.js +0 -119
  55. package/dist/database/database.test-utils.d.ts +0 -22
  56. package/dist/database/database.test-utils.js +0 -39
  57. package/dist/database/database.types.d.ts +0 -3
  58. package/dist/database/database.types.js +0 -2
  59. package/dist/features/agents/agents.manager.d.ts +0 -24
  60. package/dist/features/agents/agents.manager.js +0 -200
  61. package/dist/features/ask-user/ask-user.routes.d.ts +0 -9
  62. package/dist/features/ask-user/ask-user.routes.js +0 -35
  63. package/dist/features/chat/chat-delete.route.d.ts +0 -15
  64. package/dist/features/chat/chat-delete.route.js +0 -36
  65. package/dist/features/chat/chat-post.route.d.ts +0 -11
  66. package/dist/features/chat/chat-post.route.js +0 -270
  67. package/dist/features/chat/chat-stop.route.d.ts +0 -21
  68. package/dist/features/chat/chat-stop.route.js +0 -22
  69. package/dist/features/chat/chat-subscribe.route.d.ts +0 -9
  70. package/dist/features/chat/chat-subscribe.route.js +0 -71
  71. package/dist/features/chat/chat.routes.d.ts +0 -22
  72. package/dist/features/chat/chat.routes.js +0 -29
  73. package/dist/features/conversations/conversations-delete.route.d.ts +0 -16
  74. package/dist/features/conversations/conversations-delete.route.js +0 -34
  75. package/dist/features/conversations/conversations-get-all.route.d.ts +0 -16
  76. package/dist/features/conversations/conversations-get-all.route.js +0 -39
  77. package/dist/features/conversations/conversations-get-by-id.route.d.ts +0 -16
  78. package/dist/features/conversations/conversations-get-by-id.route.js +0 -38
  79. package/dist/features/conversations/conversations-get-deleted.route.d.ts +0 -15
  80. package/dist/features/conversations/conversations-get-deleted.route.js +0 -34
  81. package/dist/features/conversations/conversations-get-messages.route.d.ts +0 -16
  82. package/dist/features/conversations/conversations-get-messages.route.js +0 -49
  83. package/dist/features/conversations/conversations.content.d.ts +0 -28
  84. package/dist/features/conversations/conversations.content.js +0 -142
  85. package/dist/features/conversations/conversations.database.d.ts +0 -108
  86. package/dist/features/conversations/conversations.database.js +0 -373
  87. package/dist/features/conversations/conversations.manager.d.ts +0 -130
  88. package/dist/features/conversations/conversations.manager.js +0 -162
  89. package/dist/features/conversations/conversations.routes.d.ts +0 -21
  90. package/dist/features/conversations/conversations.routes.js +0 -38
  91. package/dist/features/conversations/token-usage.route.d.ts +0 -41
  92. package/dist/features/conversations/token-usage.route.js +0 -419
  93. package/dist/features/git/git-commit.route.d.ts +0 -12
  94. package/dist/features/git/git-commit.route.js +0 -39
  95. package/dist/features/git/git-create-branch.route.d.ts +0 -28
  96. package/dist/features/git/git-create-branch.route.js +0 -119
  97. package/dist/features/git/git-create-pr.route.d.ts +0 -13
  98. package/dist/features/git/git-create-pr.route.js +0 -50
  99. package/dist/features/git/git-create-repo.route.d.ts +0 -14
  100. package/dist/features/git/git-create-repo.route.js +0 -108
  101. package/dist/features/git/git-diff.route.d.ts +0 -30
  102. package/dist/features/git/git-diff.route.js +0 -189
  103. package/dist/features/git/git-fetch.route.d.ts +0 -12
  104. package/dist/features/git/git-fetch.route.js +0 -31
  105. package/dist/features/git/git-generate-commit-message.route.d.ts +0 -12
  106. package/dist/features/git/git-generate-commit-message.route.js +0 -76
  107. package/dist/features/git/git-generate-pr-info.route.d.ts +0 -13
  108. package/dist/features/git/git-generate-pr-info.route.js +0 -147
  109. package/dist/features/git/git-github-status.route.d.ts +0 -16
  110. package/dist/features/git/git-github-status.route.js +0 -68
  111. package/dist/features/git/git-log.route.d.ts +0 -17
  112. package/dist/features/git/git-log.route.js +0 -33
  113. package/dist/features/git/git-pr-status.route.d.ts +0 -15
  114. package/dist/features/git/git-pr-status.route.js +0 -33
  115. package/dist/features/git/git-pull.route.d.ts +0 -12
  116. package/dist/features/git/git-pull.route.js +0 -35
  117. package/dist/features/git/git-push.route.d.ts +0 -12
  118. package/dist/features/git/git-push.route.js +0 -46
  119. package/dist/features/git/git-status-cache.database.d.ts +0 -7
  120. package/dist/features/git/git-status-cache.database.js +0 -53
  121. package/dist/features/git/git-status.route.d.ts +0 -15
  122. package/dist/features/git/git-status.route.js +0 -62
  123. package/dist/features/git/git-sync-branch.route.d.ts +0 -4
  124. package/dist/features/git/git-sync-branch.route.js +0 -208
  125. package/dist/features/git/git-unified-status.route.d.ts +0 -30
  126. package/dist/features/git/git-unified-status.route.js +0 -165
  127. package/dist/features/git/git-username.route.d.ts +0 -3
  128. package/dist/features/git/git-username.route.js +0 -24
  129. package/dist/features/git/git.manager.d.ts +0 -139
  130. package/dist/features/git/git.manager.js +0 -352
  131. package/dist/features/git/git.routes.d.ts +0 -4
  132. package/dist/features/git/git.routes.js +0 -116
  133. package/dist/features/git/git.utils.d.ts +0 -82
  134. package/dist/features/git/git.utils.js +0 -1040
  135. package/dist/features/mcp/mcp.config.d.ts +0 -27
  136. package/dist/features/mcp/mcp.config.js +0 -148
  137. package/dist/features/mcp/mcp.manager.d.ts +0 -61
  138. package/dist/features/mcp/mcp.manager.js +0 -254
  139. package/dist/features/mcp/mcp.popular.json +0 -103
  140. package/dist/features/mcp/mcp.routes.d.ts +0 -13
  141. package/dist/features/mcp/mcp.routes.js +0 -159
  142. package/dist/features/mcp/mcp.types.d.ts +0 -80
  143. package/dist/features/mcp/mcp.types.js +0 -8
  144. package/dist/features/metadata/metadata.manager.d.ts +0 -126
  145. package/dist/features/metadata/metadata.manager.js +0 -423
  146. package/dist/features/models/model-info-aihubmix.d.ts +0 -25
  147. package/dist/features/models/model-info-aihubmix.js +0 -117
  148. package/dist/features/models/model-info-openrouter.d.ts +0 -25
  149. package/dist/features/models/model-info-openrouter.js +0 -104
  150. package/dist/features/models/model-info.d.ts +0 -37
  151. package/dist/features/models/model-info.js +0 -39
  152. package/dist/features/models/models-catalog.d.ts +0 -49
  153. package/dist/features/models/models-catalog.js +0 -80
  154. package/dist/features/models/models-catalog.route.d.ts +0 -43
  155. package/dist/features/models/models-catalog.route.js +0 -15
  156. package/dist/features/models/models-get-available.route.d.ts +0 -36
  157. package/dist/features/models/models-get-available.route.js +0 -66
  158. package/dist/features/models/models-get-enabled.route.d.ts +0 -33
  159. package/dist/features/models/models-get-enabled.route.js +0 -45
  160. package/dist/features/models/models-get-model-info.route.d.ts +0 -31
  161. package/dist/features/models/models-get-model-info.route.js +0 -84
  162. package/dist/features/models/models-model-disable.route.d.ts +0 -15
  163. package/dist/features/models/models-model-disable.route.js +0 -20
  164. package/dist/features/models/models-model-enable.route.d.ts +0 -13
  165. package/dist/features/models/models-model-enable.route.js +0 -20
  166. package/dist/features/models/models-provider-refresh.route.d.ts +0 -17
  167. package/dist/features/models/models-provider-refresh.route.js +0 -20
  168. package/dist/features/models/models.manager.d.ts +0 -58
  169. package/dist/features/models/models.manager.js +0 -138
  170. package/dist/features/models/models.routes.d.ts +0 -18
  171. package/dist/features/models/models.routes.js +0 -83
  172. package/dist/features/models/open-router-models.d.ts +0 -38
  173. package/dist/features/models/open-router-models.js +0 -73
  174. package/dist/features/models/openai-models.d.ts +0 -63
  175. package/dist/features/models/openai-models.js +0 -150
  176. package/dist/features/onboarding/onboarding-get-git-check.route.d.ts +0 -11
  177. package/dist/features/onboarding/onboarding-get-git-check.route.js +0 -28
  178. package/dist/features/onboarding/onboarding-get-status.route.d.ts +0 -12
  179. package/dist/features/onboarding/onboarding-get-status.route.js +0 -15
  180. package/dist/features/onboarding/onboarding-post-complete.route.d.ts +0 -12
  181. package/dist/features/onboarding/onboarding-post-complete.route.js +0 -15
  182. package/dist/features/onboarding/onboarding-post-reset.route.d.ts +0 -12
  183. package/dist/features/onboarding/onboarding-post-reset.route.js +0 -15
  184. package/dist/features/onboarding/onboarding.routes.d.ts +0 -18
  185. package/dist/features/onboarding/onboarding.routes.js +0 -28
  186. package/dist/features/project-todos/project-todos.database.d.ts +0 -38
  187. package/dist/features/project-todos/project-todos.database.js +0 -91
  188. package/dist/features/project-todos/project-todos.routes.d.ts +0 -4
  189. package/dist/features/project-todos/project-todos.routes.js +0 -94
  190. package/dist/features/projects/projects-ai-files.route.d.ts +0 -148
  191. package/dist/features/projects/projects-ai-files.route.js +0 -425
  192. package/dist/features/projects/projects-commands.route.d.ts +0 -27
  193. package/dist/features/projects/projects-commands.route.js +0 -39
  194. package/dist/features/projects/projects-create.route.d.ts +0 -19
  195. package/dist/features/projects/projects-create.route.js +0 -37
  196. package/dist/features/projects/projects-delete.route.d.ts +0 -24
  197. package/dist/features/projects/projects-delete.route.js +0 -34
  198. package/dist/features/projects/projects-get.route.d.ts +0 -47
  199. package/dist/features/projects/projects-get.route.js +0 -36
  200. package/dist/features/projects/projects-list.route.d.ts +0 -58
  201. package/dist/features/projects/projects-list.route.js +0 -59
  202. package/dist/features/projects/projects-open-folder.route.d.ts +0 -10
  203. package/dist/features/projects/projects-open-folder.route.js +0 -11
  204. package/dist/features/projects/projects-open.route.d.ts +0 -26
  205. package/dist/features/projects/projects-open.route.js +0 -49
  206. package/dist/features/projects/projects-package-scripts.route.d.ts +0 -15
  207. package/dist/features/projects/projects-package-scripts.route.js +0 -96
  208. package/dist/features/projects/projects-run-command.route.d.ts +0 -8
  209. package/dist/features/projects/projects-run-command.route.js +0 -21
  210. package/dist/features/projects/projects-run.route.d.ts +0 -51
  211. package/dist/features/projects/projects-run.route.js +0 -74
  212. package/dist/features/projects/projects-update.route.d.ts +0 -24
  213. package/dist/features/projects/projects-update.route.js +0 -81
  214. package/dist/features/projects/projects.creator.d.ts +0 -33
  215. package/dist/features/projects/projects.creator.js +0 -555
  216. package/dist/features/projects/projects.database.d.ts +0 -61
  217. package/dist/features/projects/projects.database.js +0 -212
  218. package/dist/features/projects/projects.manager.d.ts +0 -291
  219. package/dist/features/projects/projects.manager.js +0 -426
  220. package/dist/features/projects/projects.open-with.d.ts +0 -27
  221. package/dist/features/projects/projects.open-with.js +0 -156
  222. package/dist/features/projects/projects.routes.d.ts +0 -20
  223. package/dist/features/projects/projects.routes.js +0 -255
  224. package/dist/features/projects/terminal-session-manager.d.ts +0 -55
  225. package/dist/features/projects/terminal-session-manager.js +0 -90
  226. package/dist/features/providers/provider-resolver.d.ts +0 -13
  227. package/dist/features/providers/provider-resolver.js +0 -22
  228. package/dist/features/providers/providers-get-credits.route.d.ts +0 -15
  229. package/dist/features/providers/providers-get-credits.route.js +0 -51
  230. package/dist/features/providers/providers-get.route.d.ts +0 -16
  231. package/dist/features/providers/providers-get.route.js +0 -32
  232. package/dist/features/providers/providers-open-external.route.d.ts +0 -15
  233. package/dist/features/providers/providers-open-external.route.js +0 -49
  234. package/dist/features/providers/providers-post-bulk-keys.route.d.ts +0 -14
  235. package/dist/features/providers/providers-post-bulk-keys.route.js +0 -31
  236. package/dist/features/providers/providers-post-keys.route.d.ts +0 -14
  237. package/dist/features/providers/providers-post-keys.route.js +0 -25
  238. package/dist/features/providers/providers.routes.d.ts +0 -19
  239. package/dist/features/providers/providers.routes.js +0 -31
  240. package/dist/features/rules/rules-post.route.d.ts +0 -43
  241. package/dist/features/rules/rules-post.route.js +0 -89
  242. package/dist/features/rules/rules.manager.d.ts +0 -36
  243. package/dist/features/rules/rules.manager.js +0 -203
  244. package/dist/features/rules/rules.routes.d.ts +0 -12
  245. package/dist/features/rules/rules.routes.js +0 -13
  246. package/dist/features/run/run-get-running.route.d.ts +0 -15
  247. package/dist/features/run/run-get-running.route.js +0 -21
  248. package/dist/features/run/run-post-start.route.d.ts +0 -8
  249. package/dist/features/run/run-post-start.route.js +0 -21
  250. package/dist/features/run/run-post-stop.route.d.ts +0 -15
  251. package/dist/features/run/run-post-stop.route.js +0 -24
  252. package/dist/features/run/run-post-suggest.route.d.ts +0 -15
  253. package/dist/features/run/run-post-suggest.route.js +0 -21
  254. package/dist/features/run/run-put-command.route.d.ts +0 -15
  255. package/dist/features/run/run-put-command.route.js +0 -24
  256. package/dist/features/run/run.routes.d.ts +0 -19
  257. package/dist/features/run/run.routes.js +0 -31
  258. package/dist/features/scaffold/index.d.ts +0 -7
  259. package/dist/features/scaffold/index.js +0 -5
  260. package/dist/features/scaffold/scaffold-get-templates.route.d.ts +0 -27
  261. package/dist/features/scaffold/scaffold-get-templates.route.js +0 -17
  262. package/dist/features/scaffold/scaffold-post.route.d.ts +0 -8
  263. package/dist/features/scaffold/scaffold-post.route.js +0 -30
  264. package/dist/features/scaffold/scaffold.routes.d.ts +0 -10
  265. package/dist/features/scaffold/scaffold.routes.js +0 -16
  266. package/dist/features/scaffold/scaffold.runner.d.ts +0 -48
  267. package/dist/features/scaffold/scaffold.runner.js +0 -475
  268. package/dist/features/scaffold/scaffold.types.d.ts +0 -26
  269. package/dist/features/scaffold/scaffold.types.js +0 -5
  270. package/dist/features/skills/skills.activation.d.ts +0 -31
  271. package/dist/features/skills/skills.activation.js +0 -155
  272. package/dist/features/skills/skills.manager.d.ts +0 -35
  273. package/dist/features/skills/skills.manager.js +0 -251
  274. package/dist/features/slash-commands/slash-commands-delete.route.d.ts +0 -23
  275. package/dist/features/slash-commands/slash-commands-delete.route.js +0 -36
  276. package/dist/features/slash-commands/slash-commands-get.route.d.ts +0 -53
  277. package/dist/features/slash-commands/slash-commands-get.route.js +0 -54
  278. package/dist/features/slash-commands/slash-commands-post.route.d.ts +0 -39
  279. package/dist/features/slash-commands/slash-commands-post.route.js +0 -70
  280. package/dist/features/slash-commands/slash-commands-put.route.d.ts +0 -23
  281. package/dist/features/slash-commands/slash-commands-put.route.js +0 -36
  282. package/dist/features/slash-commands/slash-commands.manager.d.ts +0 -46
  283. package/dist/features/slash-commands/slash-commands.manager.js +0 -265
  284. package/dist/features/slash-commands/slash-commands.routes.d.ts +0 -13
  285. package/dist/features/slash-commands/slash-commands.routes.js +0 -20
  286. package/dist/features/threads/threads-ai-files.route.d.ts +0 -153
  287. package/dist/features/threads/threads-ai-files.route.js +0 -287
  288. package/dist/features/threads/threads-conversation-folder-path.route.d.ts +0 -14
  289. package/dist/features/threads/threads-conversation-folder-path.route.js +0 -23
  290. package/dist/features/threads/threads-create.route.d.ts +0 -22
  291. package/dist/features/threads/threads-create.route.js +0 -60
  292. package/dist/features/threads/threads-delete.route.d.ts +0 -25
  293. package/dist/features/threads/threads-delete.route.js +0 -35
  294. package/dist/features/threads/threads-files.route.d.ts +0 -15
  295. package/dist/features/threads/threads-files.route.js +0 -20
  296. package/dist/features/threads/threads-fix-comments.route.d.ts +0 -26
  297. package/dist/features/threads/threads-fix-comments.route.js +0 -45
  298. package/dist/features/threads/threads-get.route.d.ts +0 -30
  299. package/dist/features/threads/threads-get.route.js +0 -38
  300. package/dist/features/threads/threads-list.route.d.ts +0 -56
  301. package/dist/features/threads/threads-list.route.js +0 -58
  302. package/dist/features/threads/threads-messages.route.d.ts +0 -28
  303. package/dist/features/threads/threads-messages.route.js +0 -110
  304. package/dist/features/threads/threads-open.route.d.ts +0 -26
  305. package/dist/features/threads/threads-open.route.js +0 -62
  306. package/dist/features/threads/threads-select.route.d.ts +0 -25
  307. package/dist/features/threads/threads-select.route.js +0 -35
  308. package/dist/features/threads/threads-update.route.d.ts +0 -15
  309. package/dist/features/threads/threads-update.route.js +0 -30
  310. package/dist/features/threads/threads.database.d.ts +0 -68
  311. package/dist/features/threads/threads.database.js +0 -215
  312. package/dist/features/threads/threads.manager.d.ts +0 -204
  313. package/dist/features/threads/threads.manager.js +0 -505
  314. package/dist/features/threads/threads.routes.d.ts +0 -20
  315. package/dist/features/threads/threads.routes.js +0 -230
  316. package/dist/features/todos/todos.database.d.ts +0 -14
  317. package/dist/features/todos/todos.database.js +0 -31
  318. package/dist/features/updates/updates.routes.d.ts +0 -13
  319. package/dist/features/updates/updates.routes.js +0 -40
  320. package/dist/index.d.ts +0 -3
  321. package/dist/project-analyzer.d.ts +0 -26
  322. package/dist/project-analyzer.js +0 -307
  323. package/dist/server.d.ts +0 -12
  324. package/dist/server.js +0 -142
  325. package/dist/tools/agent-tool.d.ts +0 -49
  326. package/dist/tools/agent-tool.js +0 -131
  327. package/dist/tools/ask-user.d.ts +0 -25
  328. package/dist/tools/ask-user.js +0 -74
  329. package/dist/tools/ast-grep.d.ts +0 -28
  330. package/dist/tools/ast-grep.js +0 -273
  331. package/dist/tools/bash.d.ts +0 -33
  332. package/dist/tools/bash.js +0 -186
  333. package/dist/tools/edit-diff.d.ts +0 -24
  334. package/dist/tools/edit-diff.js +0 -136
  335. package/dist/tools/edit.d.ts +0 -28
  336. package/dist/tools/edit.js +0 -78
  337. package/dist/tools/find.d.ts +0 -31
  338. package/dist/tools/find.js +0 -117
  339. package/dist/tools/grep.d.ts +0 -37
  340. package/dist/tools/grep.js +0 -231
  341. package/dist/tools/index.d.ts +0 -93
  342. package/dist/tools/index.js +0 -110
  343. package/dist/tools/ls.d.ts +0 -31
  344. package/dist/tools/ls.js +0 -108
  345. package/dist/tools/mcp-tools.d.ts +0 -31
  346. package/dist/tools/mcp-tools.js +0 -59
  347. package/dist/tools/path-utils.d.ts +0 -14
  348. package/dist/tools/path-utils.js +0 -87
  349. package/dist/tools/read.d.ts +0 -27
  350. package/dist/tools/read.js +0 -86
  351. package/dist/tools/resolve-bin.d.ts +0 -5
  352. package/dist/tools/resolve-bin.js +0 -28
  353. package/dist/tools/shell.d.ts +0 -7
  354. package/dist/tools/shell.js +0 -143
  355. package/dist/tools/skill-reference-tool.d.ts +0 -30
  356. package/dist/tools/skill-reference-tool.js +0 -171
  357. package/dist/tools/skill-tool.d.ts +0 -33
  358. package/dist/tools/skill-tool.js +0 -213
  359. package/dist/tools/todo.d.ts +0 -20
  360. package/dist/tools/todo.js +0 -168
  361. package/dist/tools/tool-helpers.d.ts +0 -78
  362. package/dist/tools/tool-helpers.js +0 -109
  363. package/dist/tools/truncate.d.ts +0 -31
  364. package/dist/tools/truncate.js +0 -164
  365. package/dist/tools/write.d.ts +0 -21
  366. package/dist/tools/write.js +0 -65
@@ -1,1040 +0,0 @@
1
- import { spawnProcess } from "../../core/utils.js";
2
- import { existsSync, readFileSync, statSync } from "fs";
3
- import { isAbsolute, normalize, resolve, join } from "path";
4
- import { getDataDir } from "../../core/paths.js";
5
- import { getModelsCatalog } from "../models/models-catalog.js";
6
- import { completeSimple, getModel, } from "@mariozechner/pi-ai";
7
- const PROVIDER_NAME_TO_PI = {
8
- anthropic: "anthropic",
9
- openai: "openai",
10
- google: "google",
11
- groq: "groq",
12
- cerebras: "cerebras",
13
- xai: "xai",
14
- openrouter: "openrouter",
15
- "github copilot": "github-copilot",
16
- minimax: "minimax",
17
- "kimi coding plan": "kimi-coding",
18
- "hugging face": "huggingface",
19
- codex: "openai-codex",
20
- mistral: "mistral",
21
- };
22
- export const DEFAULT_MODEL_MAP = {
23
- Anthropic: "claude-3-5-sonnet-20241022",
24
- OpenAI: "gpt-4o-mini",
25
- OpenRouter: "anthropic/claude-3.5-sonnet",
26
- Groq: "llama-3.3-70b-versatile",
27
- DeepSeek: "deepseek-chat",
28
- };
29
- export function resolveModelForGit(providerName, modelId, apiUrl) {
30
- const piProvider = PROVIDER_NAME_TO_PI[providerName.toLowerCase()];
31
- if (piProvider) {
32
- try {
33
- return getModel(piProvider, modelId);
34
- }
35
- catch {
36
- // fall through to custom model
37
- }
38
- }
39
- if (!apiUrl)
40
- throw new Error(`No API URL configured for provider: ${providerName}`);
41
- const apiType = apiUrl.includes("/anthropic/") || apiUrl.includes("api.anthropic.com")
42
- ? "anthropic-messages"
43
- : "openai-completions";
44
- return {
45
- id: modelId,
46
- name: modelId,
47
- api: apiType,
48
- provider: providerName.toLowerCase(),
49
- baseUrl: apiUrl,
50
- reasoning: false,
51
- input: ["text"],
52
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
53
- contextWindow: 128000,
54
- maxTokens: 16384,
55
- };
56
- }
57
- async function getAllProviders() {
58
- const catalog = await getModelsCatalog();
59
- if (!catalog)
60
- return [];
61
- return Object.values(catalog);
62
- }
63
- async function findProviderByName(name) {
64
- const providers = await getAllProviders();
65
- return providers.find((p) => p.name.toLowerCase() === name.toLowerCase()) ?? null;
66
- }
67
- async function overlayCatalogApi(prov) {
68
- // The catalog already has the API info, so just return as-is
69
- return prov;
70
- }
71
- export async function resolveProviderAndKey(metadataProviderKeys, preferredProvider) {
72
- if (preferredProvider) {
73
- const prov = await findProviderByName(preferredProvider);
74
- if (prov) {
75
- const envKey = prov.env.length > 0 ? prov.env[0] : undefined;
76
- // Try both exact name match and case-insensitive match for metadata keys
77
- const key = envKey && process.env[envKey]
78
- ? process.env[envKey]
79
- : (metadataProviderKeys[prov.name] ??
80
- (() => {
81
- const foundKey = Object.keys(metadataProviderKeys).find((k) => k.toLowerCase() === prov.name.toLowerCase());
82
- return foundKey ? metadataProviderKeys[foundKey] : undefined;
83
- })());
84
- if (key)
85
- return { provider: await overlayCatalogApi(prov), apiKey: key };
86
- }
87
- }
88
- const providerPriority = ["Anthropic", "OpenAI", "OpenRouter", "Groq", "DeepSeek"];
89
- for (const name of providerPriority) {
90
- const prov = await findProviderByName(name);
91
- if (prov && prov.env.length > 0) {
92
- const envKey = process.env[prov.env[0]];
93
- if (envKey)
94
- return { provider: await overlayCatalogApi(prov), apiKey: envKey };
95
- }
96
- }
97
- for (const name of providerPriority) {
98
- const prov = await findProviderByName(name);
99
- if (prov && metadataProviderKeys[prov.name]) {
100
- return { provider: await overlayCatalogApi(prov), apiKey: metadataProviderKeys[prov.name] };
101
- }
102
- }
103
- const allProviders = await getAllProviders();
104
- for (const prov of allProviders) {
105
- if (prov.api && prov.env.length > 0) {
106
- const envKey = process.env[prov.env[0]];
107
- if (envKey)
108
- return { provider: await overlayCatalogApi(prov), apiKey: envKey };
109
- const metadataKey = Object.keys(metadataProviderKeys).find((k) => k.toLowerCase() === prov.name.toLowerCase());
110
- if (metadataKey)
111
- return {
112
- provider: await overlayCatalogApi(prov),
113
- apiKey: metadataProviderKeys[metadataKey],
114
- };
115
- }
116
- }
117
- return null;
118
- }
119
- export async function generatePRInfoWithAI(commitLog, detailedCommits, diff, currentBranch, baseBranch, metadataManager, model, provider) {
120
- // Build the prompt content - prefer commits for PR generation, fall back to diff
121
- let promptContent;
122
- if (commitLog.trim()) {
123
- // We have commits between branches - use those for PR info
124
- promptContent = `Based on the following commits in branch "${currentBranch}" compared to "${baseBranch}", generate a pull request title and description.
125
-
126
- Commit log:
127
- ${commitLog}
128
-
129
- Detailed commit messages:
130
- ${detailedCommits || "(no details available)"}
131
-
132
- ${diff.trim() ? `\nAdditionally, there are uncommitted changes:\n${diff.length > 1500 ? diff.substring(0, 1500) + "\n...(truncated)" : diff}` : ""}`;
133
- }
134
- else {
135
- // No commits between branches - use just the diff
136
- const truncatedDiff = diff.length > 3000 ? diff.substring(0, 3000) + "\n...(truncated)" : diff;
137
- promptContent = `Based on the following git diff, generate a pull request title and description.
138
-
139
- Git diff:
140
- ${truncatedDiff}`;
141
- }
142
- const prompt = `${promptContent}
143
-
144
- Follow these guidelines:
145
- - Title: Concise, descriptive, under 72 characters
146
- - Description: Clear explanation of changes, why they were made, and any relevant context
147
- - Use markdown formatting for the description (bullet points, headers, etc.)
148
- - Be professional and clear
149
- - If multiple changes, group them logically in the description
150
-
151
- Generate the response in this exact format:
152
- TITLE: <title here>
153
- DESCRIPTION: <description here>`;
154
- try {
155
- const providerKeys = await metadataManager.getProviderKeys();
156
- const resolved = await resolveProviderAndKey(providerKeys, provider);
157
- if (!resolved?.provider?.api) {
158
- const errorMsg = provider
159
- ? `AI provider "${provider}" is specified but no API key is configured. Please add the API key in settings.`
160
- : `No AI provider configured. Please configure a provider in settings.`;
161
- console.log(`[pr-generation] ${errorMsg}`);
162
- return { title: "Update", description: "" };
163
- }
164
- let selectedModel = model;
165
- if (selectedModel) {
166
- selectedModel = selectedModel.replace(`${resolved.provider.name.toLowerCase()}/`, "");
167
- }
168
- else {
169
- selectedModel = DEFAULT_MODEL_MAP[resolved.provider.name] || "default";
170
- }
171
- const resolvedModel = resolveModelForGit(resolved.provider.name, selectedModel, resolved.provider.api);
172
- console.log(`[pr-generation] Using model: ${resolvedModel.name} provider: ${resolved.provider.name}. key: ${resolved.apiKey ? "exists" : "undefined"} prompt length: ${prompt.length}`);
173
- const response = await completeSimple(resolvedModel, {
174
- messages: [{ role: "user", content: prompt, timestamp: Date.now() }],
175
- }, { apiKey: resolved.apiKey });
176
- const prInfo = response.content
177
- .filter((b) => b.type === "text")
178
- .map((b) => b.text)
179
- .join("")
180
- .trim();
181
- const titleMatch = prInfo.match(/TITLE:\s*(.+?)(?:\nDESCRIPTION:|$)/s);
182
- const descriptionMatch = prInfo.match(/DESCRIPTION:\s*(.+?)$/s);
183
- const title = titleMatch ? titleMatch[1].trim() : "Update";
184
- const description = descriptionMatch ? descriptionMatch[1].trim() : "";
185
- return { title, description };
186
- }
187
- catch (error) {
188
- console.log(`[pr-generation] Error in generatePRInfoWithAI: ${error instanceof Error ? error.message : String(error)}`);
189
- return { title: "Update", description: "" };
190
- }
191
- }
192
- export async function generateCommitMessageWithAI(diff, metadataManager, model, provider) {
193
- const truncatedDiff = diff.length > 3000 ? diff.substring(0, 3000) + "\n...(truncated)" : diff;
194
- const prompt = `Based on the following git diff, generate a concise, conventional commit message. Follow these guidelines:
195
- - Use conventional commit format: type(scope): description
196
- - Types: feat, fix, docs, style, refactor, test, chore
197
- - Keep it under 72 characters
198
- - Be specific and descriptive
199
- - Focus on what changed and why
200
-
201
- Git diff:
202
- ${truncatedDiff}
203
-
204
- Generate only the commit message, nothing else:`;
205
- try {
206
- const providerKeys = await metadataManager.getProviderKeys();
207
- const resolved = await resolveProviderAndKey(providerKeys, provider);
208
- if (!resolved?.provider?.api) {
209
- const errorMsg = provider
210
- ? `AI provider "${provider}" is specified but no API key is configured. Please add the API key in settings.`
211
- : `No AI provider configured. Please configure a provider in settings.`;
212
- process.stdout.write(`[generate-commit-message] ${errorMsg}\n`);
213
- return `AI Error: ${errorMsg}`;
214
- }
215
- let selectedModel = model;
216
- if (selectedModel) {
217
- selectedModel = selectedModel.replace(`${resolved.provider.name.toLowerCase()}/`, "");
218
- }
219
- else {
220
- selectedModel = DEFAULT_MODEL_MAP[resolved.provider.name] || "default";
221
- }
222
- const resolvedModel = resolveModelForGit(resolved.provider.name, selectedModel, resolved.provider.api);
223
- console.log(`[generate-commit-message] Using model: ${resolvedModel.name} provider: ${resolved.provider.name}. key: ${resolved.apiKey ? "exists" : "undefined"} prompt: ${prompt}`);
224
- const response = await completeSimple(resolvedModel, {
225
- messages: [{ role: "user", content: prompt, timestamp: Date.now() }],
226
- }, { apiKey: resolved.apiKey });
227
- let commitMessage = response.content
228
- .filter((b) => b.type === "text")
229
- .map((b) => b.text)
230
- .join("")
231
- .trim();
232
- commitMessage = commitMessage.replace(/^["']|["']$/g, "").trim();
233
- if (!commitMessage) {
234
- console.log(`[generate-commit-message] AI returned empty commit message, using fallback`, response);
235
- process.stdout.write("[generate-commit-message] AI returned empty commit message, using fallback\n");
236
- return "Update files";
237
- }
238
- return commitMessage;
239
- }
240
- catch (error) {
241
- const errorMsg = error instanceof Error ? error.message : String(error);
242
- process.stdout.write(`[generate-commit-message] AI generation failed: ${errorMsg}\n`);
243
- return `AI Error: Failed to generate commit message: ${errorMsg}`;
244
- }
245
- }
246
- /** Resolve thread path: if absolute use as-is (normalized), else resolve against data dir. */
247
- export function resolveThreadPath(repoPath) {
248
- const base = isAbsolute(repoPath) ? repoPath : resolve(getDataDir(), repoPath);
249
- return normalize(base);
250
- }
251
- /** Get git repo root for a path (directory or subdir of repo). Throws if not a git repo. */
252
- export function getGitRoot(cwd) {
253
- return new Promise((resolveRoot, reject) => {
254
- const proc = spawnProcess("git", ["rev-parse", "--show-toplevel"], { cwd });
255
- let out = "";
256
- let err = "";
257
- if (proc.stdout) {
258
- proc.stdout.on("data", (d) => {
259
- out += d.toString();
260
- });
261
- }
262
- if (proc.stderr) {
263
- proc.stderr.on("data", (d) => {
264
- err += d.toString();
265
- });
266
- }
267
- proc.on("close", (code) => {
268
- if (code === 0) {
269
- resolveRoot(out.trim());
270
- }
271
- else {
272
- reject(new Error(err.trim() || "Not a git repository"));
273
- }
274
- });
275
- proc.on("error", reject);
276
- });
277
- }
278
- /** Get current git branch */
279
- export function getCurrentBranch(gitRoot) {
280
- return new Promise((resolve) => {
281
- const proc = spawnProcess("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd: gitRoot });
282
- let out = "";
283
- if (proc.stdout) {
284
- proc.stdout.on("data", (d) => {
285
- out += d.toString();
286
- });
287
- }
288
- proc.on("close", () => {
289
- resolve(out.trim());
290
- });
291
- proc.on("error", () => resolve(""));
292
- });
293
- }
294
- /** Get git diff for staged and unstaged changes */
295
- export async function getGitDiff(gitRoot) {
296
- return new Promise((resolveDiff, reject) => {
297
- const runUnstagedDiff = () => {
298
- const proc2 = spawnProcess("git", ["diff"], { cwd: gitRoot });
299
- let out2 = "";
300
- if (proc2.stdout) {
301
- proc2.stdout.on("data", (d) => {
302
- out2 += d.toString();
303
- });
304
- }
305
- proc2.on("close", (code) => {
306
- resolveDiff(code === 0 ? out2 : "");
307
- });
308
- proc2.on("error", reject);
309
- };
310
- const proc = spawnProcess("git", ["diff", "--cached"], { cwd: gitRoot });
311
- let out = "";
312
- let err = "";
313
- if (proc.stdout) {
314
- proc.stdout.on("data", (d) => {
315
- out += d.toString();
316
- });
317
- }
318
- if (proc.stderr) {
319
- proc.stderr.on("data", (d) => {
320
- err += d.toString();
321
- });
322
- }
323
- proc.on("close", (code) => {
324
- if (code === 0) {
325
- if (!out.trim()) {
326
- runUnstagedDiff();
327
- }
328
- else {
329
- resolveDiff(out);
330
- }
331
- }
332
- else {
333
- // No commits yet (HEAD missing) or similar: use working tree diff
334
- const noHead = /HEAD|revision|unknown revision/i.test(err);
335
- if (noHead) {
336
- runUnstagedDiff();
337
- }
338
- else {
339
- reject(new Error(err || "Failed to get git diff"));
340
- }
341
- }
342
- });
343
- proc.on("error", reject);
344
- });
345
- }
346
- /** Get diff for untracked files */
347
- export async function getUntrackedFilesDiff(gitRoot) {
348
- const statusOut = await new Promise((resolveStatus) => {
349
- const proc = spawnProcess("git", ["status", "--porcelain", "--untracked-files=all"], {
350
- cwd: gitRoot,
351
- });
352
- let out = "";
353
- if (proc.stdout) {
354
- proc.stdout.on("data", (d) => {
355
- out += d.toString();
356
- });
357
- }
358
- proc.on("close", () => resolveStatus(out));
359
- proc.on("error", () => resolveStatus(""));
360
- });
361
- const lines = statusOut
362
- .trim()
363
- .split("\n")
364
- .filter((l) => l.length > 0);
365
- const untrackedPaths = [];
366
- for (const line of lines) {
367
- const code = line.slice(0, 2);
368
- const pathPart = line.slice(3).trim();
369
- if (code === "??") {
370
- untrackedPaths.push(pathPart);
371
- }
372
- }
373
- if (untrackedPaths.length === 0)
374
- return "";
375
- const parts = [];
376
- const maxFileSize = 100_000;
377
- for (const relPath of untrackedPaths) {
378
- const fullPath = join(gitRoot, relPath);
379
- if (!existsSync(fullPath))
380
- continue;
381
- try {
382
- if (statSync(fullPath).isDirectory())
383
- continue;
384
- const content = readFileSync(fullPath, "utf-8");
385
- const safeContent = content.length > maxFileSize ? content.slice(0, maxFileSize) + "\n...(truncated)" : content;
386
- const linesForDiff = safeContent
387
- .split(/\r?\n/)
388
- .map((l) => `+${l}`)
389
- .join("\n");
390
- parts.push(`diff --git a/${relPath} b/${relPath}\nnew file mode 100644\n--- /dev/null\n+++ b/${relPath}\n${linesForDiff}`);
391
- }
392
- catch {
393
- parts.push(`diff --git a/${relPath} b/${relPath}\nnew file mode 100644\n(Binary or unreadable file: ${relPath})`);
394
- }
395
- }
396
- return parts.join("\n");
397
- }
398
- /** Get git status output */
399
- export function getGitStatus(gitRoot) {
400
- return new Promise((resolve) => {
401
- const proc = spawnProcess("git", ["status", "--porcelain", "--untracked-files=all"], {
402
- cwd: gitRoot,
403
- });
404
- let out = "";
405
- if (proc.stdout) {
406
- proc.stdout.on("data", (d) => {
407
- out += d.toString();
408
- });
409
- }
410
- proc.on("close", () => resolve(out));
411
- proc.on("error", () => resolve(""));
412
- });
413
- }
414
- /** Check if there are unpushed commits */
415
- export function hasUnpushedCommits(gitRoot, currentBranch) {
416
- return new Promise((resolve) => {
417
- const proc = spawnProcess("git", ["log", `origin/${currentBranch}..HEAD`, "--oneline"], {
418
- cwd: gitRoot,
419
- });
420
- let out = "";
421
- if (proc.stdout) {
422
- proc.stdout.on("data", (d) => {
423
- out += d.toString();
424
- });
425
- }
426
- proc.on("close", () => {
427
- resolve(out.trim().length > 0);
428
- });
429
- proc.on("error", () => resolve(false));
430
- });
431
- }
432
- /** Check if current branch has commits not yet in the default branch (pushed or not) */
433
- export function hasCommitsAheadOfDefault(gitRoot, defaultBranch) {
434
- return new Promise((resolve) => {
435
- const proc = spawnProcess("git", ["rev-list", "--count", `origin/${defaultBranch}..HEAD`], {
436
- cwd: gitRoot,
437
- });
438
- let out = "";
439
- if (proc.stdout) {
440
- proc.stdout.on("data", (d) => {
441
- out += d.toString();
442
- });
443
- }
444
- proc.on("close", (code) => {
445
- if (code === 0) {
446
- resolve(parseInt(out.trim(), 10) > 0);
447
- }
448
- else {
449
- resolve(false);
450
- }
451
- });
452
- proc.on("error", () => resolve(false));
453
- });
454
- }
455
- /** Get remote origin URL */
456
- export function getRemoteOrigin(gitRoot) {
457
- return new Promise((resolve) => {
458
- const proc = spawnProcess("git", ["remote", "get-url", "origin"], { cwd: gitRoot });
459
- let out = "";
460
- if (proc.stdout) {
461
- proc.stdout.on("data", (d) => {
462
- out += d.toString();
463
- });
464
- }
465
- proc.on("close", (code) => {
466
- if (code === 0) {
467
- resolve(out.trim());
468
- }
469
- else {
470
- resolve(""); // No origin remote
471
- }
472
- });
473
- proc.on("error", () => resolve(""));
474
- });
475
- }
476
- /** Get the hash of the origin branch head */
477
- export function getOriginBranchHash(gitRoot, branch) {
478
- return new Promise((resolve) => {
479
- const proc = spawnProcess("git", ["show-ref", "--heads", "-s", `origin/${branch}`], {
480
- cwd: gitRoot,
481
- });
482
- let out = "";
483
- if (proc.stdout) {
484
- proc.stdout.on("data", (d) => {
485
- out += d.toString();
486
- });
487
- }
488
- if (proc.stderr) {
489
- proc.stderr.on("data", () => {
490
- // Ignore stderr
491
- });
492
- }
493
- proc.on("close", (code) => {
494
- if (code === 0 && out.trim()) {
495
- resolve(out.trim());
496
- }
497
- else {
498
- resolve(null);
499
- }
500
- });
501
- proc.on("error", () => resolve(null));
502
- });
503
- }
504
- /** Get the merge-base hash between origin branch and current branch */
505
- export function getMergeBaseHash(gitRoot, originBranch, currentBranch) {
506
- return new Promise((resolve) => {
507
- const proc = spawnProcess("git", ["merge-base", `origin/${originBranch}`, currentBranch], {
508
- cwd: gitRoot,
509
- });
510
- let out = "";
511
- if (proc.stdout) {
512
- proc.stdout.on("data", (d) => {
513
- out += d.toString();
514
- });
515
- }
516
- if (proc.stderr) {
517
- proc.stderr.on("data", () => {
518
- // Ignore stderr
519
- });
520
- }
521
- proc.on("close", (code) => {
522
- if (code === 0 && out.trim()) {
523
- resolve(out.trim());
524
- }
525
- else {
526
- resolve(null);
527
- }
528
- });
529
- proc.on("error", () => resolve(null));
530
- });
531
- }
532
- /** Check if current branch is behind origin branch */
533
- export async function isBranchBehind(gitRoot, branch) {
534
- const originHash = await getOriginBranchHash(gitRoot, branch);
535
- const mergeBaseHash = await getMergeBaseHash(gitRoot, branch, branch);
536
- // If either hash is null, we can't determine the status
537
- if (!originHash || !mergeBaseHash) {
538
- return false;
539
- }
540
- // If hashes are different, the branch is behind
541
- return originHash !== mergeBaseHash;
542
- }
543
- /** Get detailed git sync status (Behind, Ahead, Diverged, Up to date) */
544
- export async function getGitSyncStatus(gitRoot, branch) {
545
- console.log(`[git-status] Checking sync status for branch: ${branch}`);
546
- // Fetch to update remote tracking information
547
- console.log(`[git-status] Fetching from origin...`);
548
- await new Promise((resolve) => {
549
- const fetchProc = spawnProcess("git", ["fetch", "origin"], { cwd: gitRoot });
550
- fetchProc.on("close", () => {
551
- console.log(`[git-status] ✓ Fetch completed`);
552
- resolve();
553
- });
554
- fetchProc.on("error", () => {
555
- console.log(`[git-status] Fetch error (continuing anyway)`);
556
- resolve();
557
- });
558
- });
559
- // Check if branch is behind the default branch
560
- console.log(`[git-status] Finding default branch...`);
561
- const defaultBranch = await findDefaultBranch(gitRoot);
562
- console.log(`[git-status] Default branch: ${defaultBranch}`);
563
- if (defaultBranch && defaultBranch !== branch) {
564
- console.log(`[git-status] Checking if ${branch} is behind ${defaultBranch}...`);
565
- // Count commits in default branch that are not in current branch
566
- const isBehindDefault = await new Promise((resolve) => {
567
- const proc = spawnProcess("git", ["rev-list", "--count", `${branch}..origin/${defaultBranch}`], { cwd: gitRoot });
568
- let out = "";
569
- if (proc.stdout) {
570
- proc.stdout.on("data", (d) => {
571
- out += d.toString();
572
- });
573
- }
574
- proc.on("close", () => {
575
- const count = parseInt(out.trim(), 10);
576
- console.log(`[git-status] Commits in ${defaultBranch} but not in ${branch}: ${count}`);
577
- resolve(count > 0);
578
- });
579
- proc.on("error", () => {
580
- console.log(`[git-status] Error checking commits (assuming not behind)`);
581
- resolve(false);
582
- });
583
- });
584
- if (isBehindDefault) {
585
- console.log(`[git-status] ✓ Branch IS behind default branch`);
586
- return "Behind";
587
- }
588
- console.log(`[git-status] Branch is NOT behind default branch`);
589
- }
590
- else {
591
- console.log(`[git-status] Skipping default branch check (same branch or no default found)`);
592
- }
593
- // Check git status against remote tracking branch
594
- console.log(`[git-status] Checking status against remote tracking branch...`);
595
- return new Promise((resolve) => {
596
- const statusProc = spawnProcess("git", ["status", "-sb"], { cwd: gitRoot });
597
- let statusOut = "";
598
- let statusErr = "";
599
- if (statusProc.stdout) {
600
- statusProc.stdout.on("data", (d) => {
601
- statusOut += d.toString();
602
- });
603
- }
604
- if (statusProc.stderr) {
605
- statusProc.stderr.on("data", (d) => {
606
- statusErr += d.toString();
607
- });
608
- }
609
- statusProc.on("close", () => {
610
- const output = statusOut + statusErr;
611
- console.log(`[git-status] git status -sb output: ${output.trim()}`);
612
- // Validate that we're checking the right branch
613
- if (!output.includes(branch)) {
614
- console.log(`[git-status] Branch name not found in status output, returning 'Up to date'`);
615
- resolve("Up to date");
616
- return;
617
- }
618
- // Check for each status pattern based on git status output
619
- if (output.includes("ahead") && output.includes("behind")) {
620
- console.log(`[git-status] ✓ Status: Diverged`);
621
- resolve("Diverged");
622
- }
623
- else if (output.includes("behind")) {
624
- console.log(`[git-status] ✓ Status: Behind`);
625
- resolve("Behind");
626
- }
627
- else if (output.includes("ahead")) {
628
- console.log(`[git-status] ✓ Status: Ahead`);
629
- resolve("Ahead");
630
- }
631
- else if (output.includes("#") && !output.includes("ahead") && !output.includes("behind")) {
632
- console.log(`[git-status] ✓ Status: Up to date`);
633
- resolve("Up to date");
634
- }
635
- else {
636
- console.log(`[git-status] ✓ Status: Up to date (default)`);
637
- resolve("Up to date");
638
- }
639
- });
640
- statusProc.on("error", () => {
641
- console.log(`[git-status] Error getting status, defaulting to 'Up to date'`);
642
- resolve("Up to date");
643
- });
644
- });
645
- }
646
- /** Check if remote branch exists */
647
- export async function hasRemoteBranch(gitRoot, branch) {
648
- return new Promise((resolve) => {
649
- const proc = spawnProcess("git", ["rev-parse", "--verify", `origin/${branch}`], {
650
- cwd: gitRoot,
651
- });
652
- proc.on("close", (code) => {
653
- resolve(code === 0);
654
- });
655
- proc.on("error", () => {
656
- resolve(false);
657
- });
658
- });
659
- }
660
- /** Get default branch from origin/HEAD */
661
- export function getDefaultBranch(gitRoot) {
662
- return new Promise((resolve) => {
663
- const proc = spawnProcess("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], {
664
- cwd: gitRoot,
665
- });
666
- let out = "";
667
- if (proc.stdout) {
668
- proc.stdout.on("data", (d) => {
669
- out += d.toString();
670
- });
671
- }
672
- proc.on("close", (code) => {
673
- if (code === 0 && out.trim()) {
674
- // Output is like: refs/remotes/origin/main
675
- const match = out.trim().match(/refs\/remotes\/origin\/(.+)/);
676
- resolve(match ? match[1] : null);
677
- }
678
- else {
679
- resolve(null);
680
- }
681
- });
682
- proc.on("error", () => resolve(null));
683
- });
684
- }
685
- /** Find default branch by checking common candidates */
686
- export async function findDefaultBranch(gitRoot) {
687
- const candidates = ["main", "master", "develop", "staging"];
688
- for (const branch of candidates) {
689
- const exists = await new Promise((resolve) => {
690
- const proc = spawnProcess("git", ["rev-parse", "--verify", `origin/${branch}`], {
691
- cwd: gitRoot,
692
- });
693
- proc.on("close", (code) => resolve(code === 0));
694
- proc.on("error", () => resolve(false));
695
- });
696
- if (exists)
697
- return branch;
698
- }
699
- return null;
700
- }
701
- /** Get commit log between branches */
702
- export function getCommitLog(gitRoot, baseBranch, currentBranch) {
703
- return new Promise((resolve) => {
704
- const proc = spawnProcess("git", ["log", "--oneline", `${baseBranch}..${currentBranch}`], {
705
- cwd: gitRoot,
706
- });
707
- let out = "";
708
- if (proc.stdout) {
709
- proc.stdout.on("data", (d) => {
710
- out += d.toString();
711
- });
712
- }
713
- proc.on("close", () => resolve(out.trim()));
714
- proc.on("error", () => resolve(""));
715
- });
716
- }
717
- /** Get detailed commit information */
718
- export async function getDetailedCommits(gitRoot, baseBranch, currentBranch) {
719
- return new Promise((resolve) => {
720
- // Get commit messages with body (subject + body, limited)
721
- const proc = spawnProcess("git", ["log", `${baseBranch}..${currentBranch}`, "--format=%h %s%n%b%n---"], { cwd: gitRoot });
722
- let out = "";
723
- if (proc.stdout) {
724
- proc.stdout.on("data", (d) => {
725
- out += d.toString();
726
- });
727
- }
728
- proc.on("close", () => {
729
- // Truncate to avoid huge prompts
730
- resolve(out.length > 2000 ? out.substring(0, 2000) + "\n...(more commits)" : out);
731
- });
732
- proc.on("error", () => resolve(""));
733
- });
734
- }
735
- /** Get git log with limit */
736
- export function getGitLog(gitRoot, limit) {
737
- return new Promise((resolve, reject) => {
738
- const proc = spawnProcess("git", ["log", "--oneline", "-n", limit.toString(), "--format=%H|%s|%an|%ai"], { cwd: gitRoot });
739
- let out = "";
740
- let err = "";
741
- if (proc.stdout) {
742
- proc.stdout.on("data", (d) => {
743
- out += d.toString();
744
- });
745
- }
746
- if (proc.stderr) {
747
- proc.stderr.on("data", (d) => {
748
- err += d.toString();
749
- });
750
- }
751
- proc.on("close", (code) => {
752
- if (code === 0) {
753
- const lines = out
754
- .trim()
755
- .split("\n")
756
- .filter((line) => line.length > 0);
757
- const parsed = lines.map((line) => {
758
- const parts = line.split("|");
759
- return {
760
- hash: parts[0] || "",
761
- message: parts[1] || "",
762
- author: parts[2] || "",
763
- date: parts[3] || "",
764
- };
765
- });
766
- resolve(parsed);
767
- }
768
- else {
769
- reject(new Error(err || "Failed to get git log"));
770
- }
771
- });
772
- proc.on("error", reject);
773
- });
774
- }
775
- /** Stage all changes */
776
- export function stageAllChanges(gitRoot) {
777
- return new Promise((resolve, reject) => {
778
- const proc = spawnProcess("git", ["add", "-A"], { cwd: gitRoot });
779
- proc.on("close", (code) => {
780
- if (code === 0)
781
- resolve();
782
- else
783
- reject(new Error("Failed to stage changes"));
784
- });
785
- proc.on("error", reject);
786
- });
787
- }
788
- /** Commit changes */
789
- export function commitChanges(gitRoot, message) {
790
- return new Promise((resolve, reject) => {
791
- const proc = spawnProcess("git", ["commit", "-m", message], { cwd: gitRoot });
792
- proc.on("close", (code) => {
793
- if (code === 0)
794
- resolve();
795
- else
796
- reject(new Error("Failed to commit changes"));
797
- });
798
- proc.on("error", reject);
799
- });
800
- }
801
- /** Push changes to origin */
802
- export function pushToOrigin(gitRoot, currentBranch) {
803
- return new Promise((resolve, reject) => {
804
- console.log(`[git-push] Executing: git push -u origin ${currentBranch}`);
805
- const proc = spawnProcess("git", ["push", "-u", "origin", currentBranch], { cwd: gitRoot });
806
- let err = "";
807
- let _out = "";
808
- if (proc.stdout) {
809
- proc.stdout.on("data", (d) => {
810
- _out += d.toString();
811
- console.log(`[git-push] stdout: ${d.toString().trim()}`);
812
- });
813
- }
814
- if (proc.stderr) {
815
- proc.stderr.on("data", (d) => {
816
- err += d.toString();
817
- console.log(`[git-push] stderr: ${d.toString().trim()}`);
818
- });
819
- }
820
- proc.on("close", (code) => {
821
- console.log(`[git-push] git push exited with code: ${code}`);
822
- if (code === 0) {
823
- console.log(`[git-push] ✓ Push completed successfully`);
824
- resolve();
825
- }
826
- else {
827
- console.log(`[git-push] ✗ Push failed with error: ${err || "Unknown error"}`);
828
- reject(new Error(err || "Failed to push changes"));
829
- }
830
- });
831
- proc.on("error", (error) => {
832
- console.log(`[git-push] ✗ Process error: ${error instanceof Error ? error.message : String(error)}`);
833
- reject(error);
834
- });
835
- });
836
- }
837
- /** Fetch from origin */
838
- export function fetchFromOrigin(gitRoot) {
839
- return new Promise((resolve, reject) => {
840
- const proc = spawnProcess("git", ["fetch", "origin"], { cwd: gitRoot });
841
- let err = "";
842
- if (proc.stderr) {
843
- proc.stderr.on("data", (d) => {
844
- err += d.toString();
845
- });
846
- }
847
- proc.on("close", (code) => {
848
- if (code === 0)
849
- resolve();
850
- else
851
- reject(new Error(err || "Failed to fetch from origin"));
852
- });
853
- proc.on("error", reject);
854
- });
855
- }
856
- /** Pull from origin */
857
- export function pullFromOrigin(gitRoot) {
858
- return new Promise((resolve, reject) => {
859
- const proc = spawnProcess("git", ["pull"], { cwd: gitRoot });
860
- let err = "";
861
- if (proc.stderr) {
862
- proc.stderr.on("data", (d) => {
863
- err += d.toString();
864
- });
865
- }
866
- proc.on("close", (code) => {
867
- if (code === 0)
868
- resolve();
869
- else
870
- reject(new Error(err || "Failed to pull from origin"));
871
- });
872
- proc.on("error", reject);
873
- });
874
- }
875
- /** Stash changes */
876
- export function stashChanges(gitRoot) {
877
- return new Promise((resolve, reject) => {
878
- const proc = spawnProcess("git", ["stash"], { cwd: gitRoot });
879
- let err = "";
880
- if (proc.stderr) {
881
- proc.stderr.on("data", (d) => {
882
- err += d.toString();
883
- });
884
- }
885
- proc.on("close", (code) => {
886
- if (code === 0)
887
- resolve();
888
- else
889
- reject(new Error(err || "Failed to stash changes"));
890
- });
891
- proc.on("error", reject);
892
- });
893
- }
894
- /** Pop stashed changes */
895
- export function popStashedChanges(gitRoot) {
896
- return new Promise((resolve, reject) => {
897
- const proc = spawnProcess("git", ["stash", "pop"], { cwd: gitRoot });
898
- let err = "";
899
- if (proc.stderr) {
900
- proc.stderr.on("data", (d) => {
901
- err += d.toString();
902
- });
903
- }
904
- proc.on("close", (code) => {
905
- if (code === 0)
906
- resolve();
907
- else
908
- reject(new Error(err || "Failed to pop stashed changes"));
909
- });
910
- proc.on("error", reject);
911
- });
912
- }
913
- /** Create GitHub repository using gh CLI */
914
- export function createGitHubRepo(gitRoot, repoName, description, isPrivate) {
915
- return new Promise((resolve, reject) => {
916
- const args = ["repo", "create"];
917
- if (repoName) {
918
- args.push(repoName);
919
- }
920
- if (description) {
921
- args.push("--description", description);
922
- }
923
- if (isPrivate) {
924
- args.push("--private");
925
- }
926
- else {
927
- args.push("--public");
928
- }
929
- args.push("--source", ".", "--push");
930
- const proc = spawnProcess("gh", args, { cwd: gitRoot });
931
- let out = "";
932
- let err = "";
933
- if (proc.stdout) {
934
- proc.stdout.on("data", (d) => {
935
- out += d.toString();
936
- });
937
- }
938
- if (proc.stderr) {
939
- proc.stderr.on("data", (d) => {
940
- err += d.toString();
941
- });
942
- }
943
- proc.on("close", (code) => {
944
- if (code === 0) {
945
- // Extract URL from output
946
- const urlMatch = out.match(/https:\/\/[^\s]+/);
947
- resolve(urlMatch ? urlMatch[0] : out.trim());
948
- }
949
- else {
950
- reject(new Error(err || "Failed to create repository"));
951
- }
952
- });
953
- proc.on("error", () => reject(new Error("GitHub CLI (gh) not found. Please install it to create repositories.")));
954
- });
955
- }
956
- /** Create pull request using gh CLI */
957
- export function createPullRequest(gitRoot, title, description) {
958
- return new Promise((resolve, reject) => {
959
- const args = ["pr", "create", "--title", title ?? "", "--body", description ?? ""];
960
- console.log(`[git-create-pr] Executing: gh ${args.join(" ")}`);
961
- const proc = spawnProcess("gh", args, { cwd: gitRoot });
962
- let out = "";
963
- let err = "";
964
- if (proc.stdout) {
965
- proc.stdout.on("data", (d) => {
966
- out += d.toString();
967
- console.log(`[git-create-pr] stdout: ${d.toString().trim()}`);
968
- });
969
- }
970
- if (proc.stderr) {
971
- proc.stderr.on("data", (d) => {
972
- err += d.toString();
973
- console.log(`[git-create-pr] stderr: ${d.toString().trim()}`);
974
- });
975
- }
976
- proc.on("close", (code) => {
977
- console.log(`[git-create-pr] gh pr create exited with code: ${code}`);
978
- if (code === 0) {
979
- // Extract URL from output
980
- const urlMatch = out.match(/https:\/\/[^\s]+/);
981
- const prUrl = urlMatch ? urlMatch[0] : out.trim();
982
- console.log(`[git-create-pr] ✓ PR URL extracted: ${prUrl}`);
983
- resolve(prUrl);
984
- }
985
- else {
986
- console.log(`[git-create-pr] ✗ gh pr create failed with error: ${err || "Unknown error"}`);
987
- reject(new Error(err || "Failed to create PR"));
988
- }
989
- });
990
- proc.on("error", (error) => {
991
- console.log(`[git-create-pr] ✗ Process error: ${error instanceof Error ? error.message : String(error)}`);
992
- reject(new Error("GitHub CLI (gh) not found. Please install it to create PRs."));
993
- });
994
- });
995
- }
996
- /** Check if there's an existing PR for the current branch */
997
- export function getPullRequestStatus(gitRoot) {
998
- return new Promise((resolve, reject) => {
999
- const args = ["pr", "view", "--json", "url,state"];
1000
- const proc = spawnProcess("gh", args, { cwd: gitRoot });
1001
- let out = "";
1002
- let err = "";
1003
- if (proc.stdout) {
1004
- proc.stdout.on("data", (d) => {
1005
- out += d.toString();
1006
- });
1007
- }
1008
- if (proc.stderr) {
1009
- proc.stderr.on("data", (d) => {
1010
- err += d.toString();
1011
- });
1012
- }
1013
- proc.on("close", (code) => {
1014
- if (code === 0) {
1015
- try {
1016
- const prData = JSON.parse(out.trim());
1017
- resolve({
1018
- exists: true,
1019
- url: prData.url,
1020
- state: prData.state,
1021
- });
1022
- }
1023
- catch {
1024
- reject(new Error("Failed to parse PR data"));
1025
- }
1026
- }
1027
- else {
1028
- // Check if error indicates no PR exists
1029
- if (err.includes("no pull requests") || err.includes("not found")) {
1030
- resolve({ exists: false });
1031
- }
1032
- else {
1033
- reject(new Error(err || "Failed to check PR status"));
1034
- }
1035
- }
1036
- });
1037
- proc.on("error", () => reject(new Error("GitHub CLI (gh) not found. Please install it to check PR status.")));
1038
- });
1039
- }
1040
- //# sourceMappingURL=git.utils.js.map