@seawork/server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (682) hide show
  1. package/.env.example +23 -0
  2. package/README.md +107 -0
  3. package/dist/scripts/dev-runner.js +27 -0
  4. package/dist/scripts/dev-runner.js.map +1 -0
  5. package/dist/scripts/mcp-stdio-socket-bridge-cli.mjs +62 -0
  6. package/dist/scripts/supervisor-entrypoint.js +123 -0
  7. package/dist/scripts/supervisor-entrypoint.js.map +1 -0
  8. package/dist/scripts/supervisor.js +148 -0
  9. package/dist/scripts/supervisor.js.map +1 -0
  10. package/dist/server/client/daemon-client-relay-e2ee-transport.d.ts +8 -0
  11. package/dist/server/client/daemon-client-relay-e2ee-transport.d.ts.map +1 -0
  12. package/dist/server/client/daemon-client-relay-e2ee-transport.js +161 -0
  13. package/dist/server/client/daemon-client-relay-e2ee-transport.js.map +1 -0
  14. package/dist/server/client/daemon-client-transport-types.d.ts +34 -0
  15. package/dist/server/client/daemon-client-transport-types.d.ts.map +1 -0
  16. package/dist/server/client/daemon-client-transport-types.js +2 -0
  17. package/dist/server/client/daemon-client-transport-types.js.map +1 -0
  18. package/dist/server/client/daemon-client-transport-utils.d.ts +9 -0
  19. package/dist/server/client/daemon-client-transport-utils.d.ts.map +1 -0
  20. package/dist/server/client/daemon-client-transport-utils.js +121 -0
  21. package/dist/server/client/daemon-client-transport-utils.js.map +1 -0
  22. package/dist/server/client/daemon-client-transport.d.ts +5 -0
  23. package/dist/server/client/daemon-client-transport.d.ts.map +1 -0
  24. package/dist/server/client/daemon-client-transport.js +4 -0
  25. package/dist/server/client/daemon-client-transport.js.map +1 -0
  26. package/dist/server/client/daemon-client-websocket-transport.d.ts +7 -0
  27. package/dist/server/client/daemon-client-websocket-transport.d.ts.map +1 -0
  28. package/dist/server/client/daemon-client-websocket-transport.js +119 -0
  29. package/dist/server/client/daemon-client-websocket-transport.js.map +1 -0
  30. package/dist/server/client/daemon-client.d.ts +697 -0
  31. package/dist/server/client/daemon-client.d.ts.map +1 -0
  32. package/dist/server/client/daemon-client.js +2885 -0
  33. package/dist/server/client/daemon-client.js.map +1 -0
  34. package/dist/server/server/agent/activity-curator.d.ts +8 -0
  35. package/dist/server/server/agent/activity-curator.d.ts.map +1 -0
  36. package/dist/server/server/agent/activity-curator.js +243 -0
  37. package/dist/server/server/agent/activity-curator.js.map +1 -0
  38. package/dist/server/server/agent/agent-management-mcp.d.ts +41 -0
  39. package/dist/server/server/agent/agent-management-mcp.d.ts.map +1 -0
  40. package/dist/server/server/agent/agent-management-mcp.js +767 -0
  41. package/dist/server/server/agent/agent-management-mcp.js.map +1 -0
  42. package/dist/server/server/agent/agent-manager.d.ts +287 -0
  43. package/dist/server/server/agent/agent-manager.d.ts.map +1 -0
  44. package/dist/server/server/agent/agent-manager.js +1956 -0
  45. package/dist/server/server/agent/agent-manager.js.map +1 -0
  46. package/dist/server/server/agent/agent-metadata-generator.d.ts +29 -0
  47. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -0
  48. package/dist/server/server/agent/agent-metadata-generator.js +161 -0
  49. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -0
  50. package/dist/server/server/agent/agent-projections.d.ts +17 -0
  51. package/dist/server/server/agent/agent-projections.d.ts.map +1 -0
  52. package/dist/server/server/agent/agent-projections.js +280 -0
  53. package/dist/server/server/agent/agent-projections.js.map +1 -0
  54. package/dist/server/server/agent/agent-response-loop.d.ts +60 -0
  55. package/dist/server/server/agent/agent-response-loop.d.ts.map +1 -0
  56. package/dist/server/server/agent/agent-response-loop.js +304 -0
  57. package/dist/server/server/agent/agent-response-loop.js.map +1 -0
  58. package/dist/server/server/agent/agent-sdk-types.d.ts +470 -0
  59. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -0
  60. package/dist/server/server/agent/agent-sdk-types.js +12 -0
  61. package/dist/server/server/agent/agent-sdk-types.js.map +1 -0
  62. package/dist/server/server/agent/agent-storage.d.ts +336 -0
  63. package/dist/server/server/agent/agent-storage.d.ts.map +1 -0
  64. package/dist/server/server/agent/agent-storage.js +304 -0
  65. package/dist/server/server/agent/agent-storage.js.map +1 -0
  66. package/dist/server/server/agent/agent-title-limits.d.ts +3 -0
  67. package/dist/server/server/agent/agent-title-limits.d.ts.map +1 -0
  68. package/dist/server/server/agent/agent-title-limits.js +3 -0
  69. package/dist/server/server/agent/agent-title-limits.js.map +1 -0
  70. package/dist/server/server/agent/audio-utils.d.ts +3 -0
  71. package/dist/server/server/agent/audio-utils.d.ts.map +1 -0
  72. package/dist/server/server/agent/audio-utils.js +19 -0
  73. package/dist/server/server/agent/audio-utils.js.map +1 -0
  74. package/dist/server/server/agent/dictation-debug.d.ts +13 -0
  75. package/dist/server/server/agent/dictation-debug.d.ts.map +1 -0
  76. package/dist/server/server/agent/dictation-debug.js +50 -0
  77. package/dist/server/server/agent/dictation-debug.js.map +1 -0
  78. package/dist/server/server/agent/llm-openai.d.ts +7 -0
  79. package/dist/server/server/agent/llm-openai.d.ts.map +1 -0
  80. package/dist/server/server/agent/llm-openai.js +8 -0
  81. package/dist/server/server/agent/llm-openai.js.map +1 -0
  82. package/dist/server/server/agent/mcp-server.d.ts +33 -0
  83. package/dist/server/server/agent/mcp-server.d.ts.map +1 -0
  84. package/dist/server/server/agent/mcp-server.js +1279 -0
  85. package/dist/server/server/agent/mcp-server.js.map +1 -0
  86. package/dist/server/server/agent/mcp-shared.d.ts +251 -0
  87. package/dist/server/server/agent/mcp-shared.d.ts.map +1 -0
  88. package/dist/server/server/agent/mcp-shared.js +242 -0
  89. package/dist/server/server/agent/mcp-shared.js.map +1 -0
  90. package/dist/server/server/agent/model-resolver.d.ts +11 -0
  91. package/dist/server/server/agent/model-resolver.d.ts.map +1 -0
  92. package/dist/server/server/agent/model-resolver.js +21 -0
  93. package/dist/server/server/agent/model-resolver.js.map +1 -0
  94. package/dist/server/server/agent/orchestrator-instructions.d.ts +7 -0
  95. package/dist/server/server/agent/orchestrator-instructions.d.ts.map +1 -0
  96. package/dist/server/server/agent/orchestrator-instructions.js +51 -0
  97. package/dist/server/server/agent/orchestrator-instructions.js.map +1 -0
  98. package/dist/server/server/agent/orchestrator.d.ts +12 -0
  99. package/dist/server/server/agent/orchestrator.d.ts.map +1 -0
  100. package/dist/server/server/agent/orchestrator.js +12 -0
  101. package/dist/server/server/agent/orchestrator.js.map +1 -0
  102. package/dist/server/server/agent/pcm16-resampler.d.ts +14 -0
  103. package/dist/server/server/agent/pcm16-resampler.d.ts.map +1 -0
  104. package/dist/server/server/agent/pcm16-resampler.js +63 -0
  105. package/dist/server/server/agent/pcm16-resampler.js.map +1 -0
  106. package/dist/server/server/agent/provider-launch-config.d.ts +138 -0
  107. package/dist/server/server/agent/provider-launch-config.d.ts.map +1 -0
  108. package/dist/server/server/agent/provider-launch-config.js +80 -0
  109. package/dist/server/server/agent/provider-launch-config.js.map +1 -0
  110. package/dist/server/server/agent/provider-manifest.d.ts +29 -0
  111. package/dist/server/server/agent/provider-manifest.d.ts.map +1 -0
  112. package/dist/server/server/agent/provider-manifest.js +157 -0
  113. package/dist/server/server/agent/provider-manifest.js.map +1 -0
  114. package/dist/server/server/agent/provider-registry.d.ts +19 -0
  115. package/dist/server/server/agent/provider-registry.d.ts.map +1 -0
  116. package/dist/server/server/agent/provider-registry.js +58 -0
  117. package/dist/server/server/agent/provider-registry.js.map +1 -0
  118. package/dist/server/server/agent/provider-snapshot-manager.d.ts +27 -0
  119. package/dist/server/server/agent/provider-snapshot-manager.d.ts.map +1 -0
  120. package/dist/server/server/agent/provider-snapshot-manager.js +181 -0
  121. package/dist/server/server/agent/provider-snapshot-manager.js.map +1 -0
  122. package/dist/server/server/agent/providers/acp-agent.d.ts +202 -0
  123. package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -0
  124. package/dist/server/server/agent/providers/acp-agent.js +1650 -0
  125. package/dist/server/server/agent/providers/acp-agent.js.map +1 -0
  126. package/dist/server/server/agent/providers/claude/claude-models.d.ts +8 -0
  127. package/dist/server/server/agent/providers/claude/claude-models.d.ts.map +1 -0
  128. package/dist/server/server/agent/providers/claude/claude-models.js +63 -0
  129. package/dist/server/server/agent/providers/claude/claude-models.js.map +1 -0
  130. package/dist/server/server/agent/providers/claude/partial-json.d.ts +5 -0
  131. package/dist/server/server/agent/providers/claude/partial-json.d.ts.map +1 -0
  132. package/dist/server/server/agent/providers/claude/partial-json.js +306 -0
  133. package/dist/server/server/agent/providers/claude/partial-json.js.map +1 -0
  134. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts +20 -0
  135. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts.map +1 -0
  136. package/dist/server/server/agent/providers/claude/sidechain-tracker.js +230 -0
  137. package/dist/server/server/agent/providers/claude/sidechain-tracker.js.map +1 -0
  138. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +55 -0
  139. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts.map +1 -0
  140. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +267 -0
  141. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js.map +1 -0
  142. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts +3 -0
  143. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts.map +1 -0
  144. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +121 -0
  145. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -0
  146. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts +16 -0
  147. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -0
  148. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +252 -0
  149. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -0
  150. package/dist/server/server/agent/providers/claude-agent.d.ts +44 -0
  151. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -0
  152. package/dist/server/server/agent/providers/claude-agent.js +3452 -0
  153. package/dist/server/server/agent/providers/claude-agent.js.map +1 -0
  154. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts +12 -0
  155. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts.map +1 -0
  156. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.js +104 -0
  157. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.js.map +1 -0
  158. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts +15 -0
  159. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -0
  160. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +762 -0
  161. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -0
  162. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +200 -0
  163. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -0
  164. package/dist/server/server/agent/providers/codex-app-server-agent.js +3474 -0
  165. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -0
  166. package/dist/server/server/agent/providers/codex-feature-definitions.d.ts +11 -0
  167. package/dist/server/server/agent/providers/codex-feature-definitions.d.ts.map +1 -0
  168. package/dist/server/server/agent/providers/codex-feature-definitions.js +45 -0
  169. package/dist/server/server/agent/providers/codex-feature-definitions.js.map +1 -0
  170. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts +9 -0
  171. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts.map +1 -0
  172. package/dist/server/server/agent/providers/codex-rollout-timeline.js +544 -0
  173. package/dist/server/server/agent/providers/codex-rollout-timeline.js.map +1 -0
  174. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts +16 -0
  175. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts.map +1 -0
  176. package/dist/server/server/agent/providers/copilot-acp-agent.js +95 -0
  177. package/dist/server/server/agent/providers/copilot-acp-agent.js.map +1 -0
  178. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +17 -0
  179. package/dist/server/server/agent/providers/diagnostic-utils.d.ts.map +1 -0
  180. package/dist/server/server/agent/providers/diagnostic-utils.js +56 -0
  181. package/dist/server/server/agent/providers/diagnostic-utils.js.map +1 -0
  182. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts +3 -0
  183. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts.map +1 -0
  184. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js +39 -0
  185. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js.map +1 -0
  186. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts +13 -0
  187. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts.map +1 -0
  188. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js +144 -0
  189. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js.map +1 -0
  190. package/dist/server/server/agent/providers/opencode-agent.d.ts +121 -0
  191. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -0
  192. package/dist/server/server/agent/providers/opencode-agent.js +1649 -0
  193. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -0
  194. package/dist/server/server/agent/providers/pi-acp-agent.d.ts +28 -0
  195. package/dist/server/server/agent/providers/pi-acp-agent.d.ts.map +1 -0
  196. package/dist/server/server/agent/providers/pi-acp-agent.js +302 -0
  197. package/dist/server/server/agent/providers/pi-acp-agent.js.map +1 -0
  198. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.d.ts +3 -0
  199. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.d.ts.map +1 -0
  200. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js +57 -0
  201. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js.map +1 -0
  202. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +1745 -0
  203. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -0
  204. package/dist/server/server/agent/providers/tool-call-detail-primitives.js +686 -0
  205. package/dist/server/server/agent/providers/tool-call-detail-primitives.js.map +1 -0
  206. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts +18 -0
  207. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts.map +1 -0
  208. package/dist/server/server/agent/providers/tool-call-mapper-utils.js +115 -0
  209. package/dist/server/server/agent/providers/tool-call-mapper-utils.js.map +1 -0
  210. package/dist/server/server/agent/recordings-debug.d.ts +3 -0
  211. package/dist/server/server/agent/recordings-debug.d.ts.map +1 -0
  212. package/dist/server/server/agent/recordings-debug.js +19 -0
  213. package/dist/server/server/agent/recordings-debug.js.map +1 -0
  214. package/dist/server/server/agent/stt-debug.d.ts +10 -0
  215. package/dist/server/server/agent/stt-debug.d.ts.map +1 -0
  216. package/dist/server/server/agent/stt-debug.js +33 -0
  217. package/dist/server/server/agent/stt-debug.js.map +1 -0
  218. package/dist/server/server/agent/stt-manager.d.ts +33 -0
  219. package/dist/server/server/agent/stt-manager.d.ts.map +1 -0
  220. package/dist/server/server/agent/stt-manager.js +232 -0
  221. package/dist/server/server/agent/stt-manager.js.map +1 -0
  222. package/dist/server/server/agent/timeline-append.d.ts +10 -0
  223. package/dist/server/server/agent/timeline-append.d.ts.map +1 -0
  224. package/dist/server/server/agent/timeline-append.js +27 -0
  225. package/dist/server/server/agent/timeline-append.js.map +1 -0
  226. package/dist/server/server/agent/timeline-projection.d.ts +39 -0
  227. package/dist/server/server/agent/timeline-projection.d.ts.map +1 -0
  228. package/dist/server/server/agent/timeline-projection.js +215 -0
  229. package/dist/server/server/agent/timeline-projection.js.map +1 -0
  230. package/dist/server/server/agent/tool-name-normalization.d.ts +9 -0
  231. package/dist/server/server/agent/tool-name-normalization.d.ts.map +1 -0
  232. package/dist/server/server/agent/tool-name-normalization.js +82 -0
  233. package/dist/server/server/agent/tool-name-normalization.js.map +1 -0
  234. package/dist/server/server/agent/tts-debug.d.ts +8 -0
  235. package/dist/server/server/agent/tts-debug.d.ts.map +1 -0
  236. package/dist/server/server/agent/tts-debug.js +24 -0
  237. package/dist/server/server/agent/tts-debug.js.map +1 -0
  238. package/dist/server/server/agent/tts-manager.d.ts +41 -0
  239. package/dist/server/server/agent/tts-manager.d.ts.map +1 -0
  240. package/dist/server/server/agent/tts-manager.js +374 -0
  241. package/dist/server/server/agent/tts-manager.js.map +1 -0
  242. package/dist/server/server/agent/wait-for-agent-tracker.d.ts +15 -0
  243. package/dist/server/server/agent/wait-for-agent-tracker.d.ts.map +1 -0
  244. package/dist/server/server/agent/wait-for-agent-tracker.js +53 -0
  245. package/dist/server/server/agent/wait-for-agent-tracker.js.map +1 -0
  246. package/dist/server/server/agent-attention-policy.d.ts +20 -0
  247. package/dist/server/server/agent-attention-policy.d.ts.map +1 -0
  248. package/dist/server/server/agent-attention-policy.js +40 -0
  249. package/dist/server/server/agent-attention-policy.js.map +1 -0
  250. package/dist/server/server/allowed-hosts.d.ts +13 -0
  251. package/dist/server/server/allowed-hosts.d.ts.map +1 -0
  252. package/dist/server/server/allowed-hosts.js +94 -0
  253. package/dist/server/server/allowed-hosts.js.map +1 -0
  254. package/dist/server/server/bootstrap.d.ts +74 -0
  255. package/dist/server/server/bootstrap.d.ts.map +1 -0
  256. package/dist/server/server/bootstrap.js +537 -0
  257. package/dist/server/server/bootstrap.js.map +1 -0
  258. package/dist/server/server/chat/chat-mentions.d.ts +31 -0
  259. package/dist/server/server/chat/chat-mentions.d.ts.map +1 -0
  260. package/dist/server/server/chat/chat-mentions.js +71 -0
  261. package/dist/server/server/chat/chat-mentions.js.map +1 -0
  262. package/dist/server/server/chat/chat-rpc-schemas.d.ts +728 -0
  263. package/dist/server/server/chat/chat-rpc-schemas.d.ts.map +1 -0
  264. package/dist/server/server/chat/chat-rpc-schemas.js +103 -0
  265. package/dist/server/server/chat/chat-rpc-schemas.js.map +1 -0
  266. package/dist/server/server/chat/chat-service.d.ts +74 -0
  267. package/dist/server/server/chat/chat-service.d.ts.map +1 -0
  268. package/dist/server/server/chat/chat-service.js +330 -0
  269. package/dist/server/server/chat/chat-service.js.map +1 -0
  270. package/dist/server/server/chat/chat-types.d.ts +75 -0
  271. package/dist/server/server/chat/chat-types.d.ts.map +1 -0
  272. package/dist/server/server/chat/chat-types.js +22 -0
  273. package/dist/server/server/chat/chat-types.js.map +1 -0
  274. package/dist/server/server/checkout-diff-manager.d.ts +45 -0
  275. package/dist/server/server/checkout-diff-manager.d.ts.map +1 -0
  276. package/dist/server/server/checkout-diff-manager.js +374 -0
  277. package/dist/server/server/checkout-diff-manager.js.map +1 -0
  278. package/dist/server/server/checkout-git-utils.d.ts +9 -0
  279. package/dist/server/server/checkout-git-utils.d.ts.map +1 -0
  280. package/dist/server/server/checkout-git-utils.js +37 -0
  281. package/dist/server/server/checkout-git-utils.js.map +1 -0
  282. package/dist/server/server/client-message-id.d.ts +3 -0
  283. package/dist/server/server/client-message-id.d.ts.map +1 -0
  284. package/dist/server/server/client-message-id.js +12 -0
  285. package/dist/server/server/client-message-id.js.map +1 -0
  286. package/dist/server/server/config.d.ts +14 -0
  287. package/dist/server/server/config.d.ts.map +1 -0
  288. package/dist/server/server/config.js +96 -0
  289. package/dist/server/server/config.js.map +1 -0
  290. package/dist/server/server/connection-offer.d.ts +19 -0
  291. package/dist/server/server/connection-offer.d.ts.map +1 -0
  292. package/dist/server/server/connection-offer.js +59 -0
  293. package/dist/server/server/connection-offer.js.map +1 -0
  294. package/dist/server/server/daemon-config-store.d.ts +23 -0
  295. package/dist/server/server/daemon-config-store.d.ts.map +1 -0
  296. package/dist/server/server/daemon-config-store.js +114 -0
  297. package/dist/server/server/daemon-config-store.js.map +1 -0
  298. package/dist/server/server/daemon-keypair.d.ts +8 -0
  299. package/dist/server/server/daemon-keypair.d.ts.map +1 -0
  300. package/dist/server/server/daemon-keypair.js +40 -0
  301. package/dist/server/server/daemon-keypair.js.map +1 -0
  302. package/dist/server/server/daemon-version.d.ts +5 -0
  303. package/dist/server/server/daemon-version.d.ts.map +1 -0
  304. package/dist/server/server/daemon-version.js +22 -0
  305. package/dist/server/server/daemon-version.js.map +1 -0
  306. package/dist/server/server/dictation/dictation-stream-manager.d.ts +85 -0
  307. package/dist/server/server/dictation/dictation-stream-manager.d.ts.map +1 -0
  308. package/dist/server/server/dictation/dictation-stream-manager.js +571 -0
  309. package/dist/server/server/dictation/dictation-stream-manager.js.map +1 -0
  310. package/dist/server/server/editor-targets.d.ts +18 -0
  311. package/dist/server/server/editor-targets.d.ts.map +1 -0
  312. package/dist/server/server/editor-targets.js +113 -0
  313. package/dist/server/server/editor-targets.js.map +1 -0
  314. package/dist/server/server/exports.d.ts +19 -0
  315. package/dist/server/server/exports.d.ts.map +1 -0
  316. package/dist/server/server/exports.js +21 -0
  317. package/dist/server/server/exports.js.map +1 -0
  318. package/dist/server/server/file-download/token-store.d.ts +24 -0
  319. package/dist/server/server/file-download/token-store.d.ts.map +1 -0
  320. package/dist/server/server/file-download/token-store.js +40 -0
  321. package/dist/server/server/file-download/token-store.js.map +1 -0
  322. package/dist/server/server/file-explorer/service.d.ts +41 -0
  323. package/dist/server/server/file-explorer/service.d.ts.map +1 -0
  324. package/dist/server/server/file-explorer/service.js +194 -0
  325. package/dist/server/server/file-explorer/service.js.map +1 -0
  326. package/dist/server/server/index.d.ts +2 -0
  327. package/dist/server/server/index.d.ts.map +1 -0
  328. package/dist/server/server/index.js +176 -0
  329. package/dist/server/server/index.js.map +1 -0
  330. package/dist/server/server/json-utils.d.ts +11 -0
  331. package/dist/server/server/json-utils.d.ts.map +1 -0
  332. package/dist/server/server/json-utils.js +45 -0
  333. package/dist/server/server/json-utils.js.map +1 -0
  334. package/dist/server/server/logger.d.ts +33 -0
  335. package/dist/server/server/logger.d.ts.map +1 -0
  336. package/dist/server/server/logger.js +195 -0
  337. package/dist/server/server/logger.js.map +1 -0
  338. package/dist/server/server/loop/rpc-schemas.d.ts +2937 -0
  339. package/dist/server/server/loop/rpc-schemas.d.ts.map +1 -0
  340. package/dist/server/server/loop/rpc-schemas.js +159 -0
  341. package/dist/server/server/loop/rpc-schemas.js.map +1 -0
  342. package/dist/server/server/loop-service.d.ts +520 -0
  343. package/dist/server/server/loop-service.d.ts.map +1 -0
  344. package/dist/server/server/loop-service.js +739 -0
  345. package/dist/server/server/loop-service.js.map +1 -0
  346. package/dist/server/server/messages.d.ts +9 -0
  347. package/dist/server/server/messages.d.ts.map +1 -0
  348. package/dist/server/server/messages.js +29 -0
  349. package/dist/server/server/messages.js.map +1 -0
  350. package/dist/server/server/package-version.d.ts +13 -0
  351. package/dist/server/server/package-version.d.ts.map +1 -0
  352. package/dist/server/server/package-version.js +46 -0
  353. package/dist/server/server/package-version.js.map +1 -0
  354. package/dist/server/server/pairing-offer.d.ts +16 -0
  355. package/dist/server/server/pairing-offer.d.ts.map +1 -0
  356. package/dist/server/server/pairing-offer.js +45 -0
  357. package/dist/server/server/pairing-offer.js.map +1 -0
  358. package/dist/server/server/pairing-qr.d.ts +7 -0
  359. package/dist/server/server/pairing-qr.d.ts.map +1 -0
  360. package/dist/server/server/pairing-qr.js +45 -0
  361. package/dist/server/server/pairing-qr.js.map +1 -0
  362. package/dist/server/server/path-utils.d.ts +3 -0
  363. package/dist/server/server/path-utils.d.ts.map +1 -0
  364. package/dist/server/server/path-utils.js +20 -0
  365. package/dist/server/server/path-utils.js.map +1 -0
  366. package/dist/server/server/persisted-config.d.ts +625 -0
  367. package/dist/server/server/persisted-config.d.ts.map +1 -0
  368. package/dist/server/server/persisted-config.js +265 -0
  369. package/dist/server/server/persisted-config.js.map +1 -0
  370. package/dist/server/server/persistence-hooks.d.ts +24 -0
  371. package/dist/server/server/persistence-hooks.d.ts.map +1 -0
  372. package/dist/server/server/persistence-hooks.js +60 -0
  373. package/dist/server/server/persistence-hooks.js.map +1 -0
  374. package/dist/server/server/pid-lock.d.ts +29 -0
  375. package/dist/server/server/pid-lock.d.ts.map +1 -0
  376. package/dist/server/server/pid-lock.js +148 -0
  377. package/dist/server/server/pid-lock.js.map +1 -0
  378. package/dist/server/server/push/push-service.d.ts +22 -0
  379. package/dist/server/server/push/push-service.d.ts.map +1 -0
  380. package/dist/server/server/push/push-service.js +69 -0
  381. package/dist/server/server/push/push-service.js.map +1 -0
  382. package/dist/server/server/push/token-store.d.ts +18 -0
  383. package/dist/server/server/push/token-store.d.ts.map +1 -0
  384. package/dist/server/server/push/token-store.js +70 -0
  385. package/dist/server/server/push/token-store.js.map +1 -0
  386. package/dist/server/server/relay-transport.d.ts +23 -0
  387. package/dist/server/server/relay-transport.d.ts.map +1 -0
  388. package/dist/server/server/relay-transport.js +461 -0
  389. package/dist/server/server/relay-transport.js.map +1 -0
  390. package/dist/server/server/schedule/cron.d.ts +4 -0
  391. package/dist/server/server/schedule/cron.d.ts.map +1 -0
  392. package/dist/server/server/schedule/cron.js +103 -0
  393. package/dist/server/server/schedule/cron.js.map +1 -0
  394. package/dist/server/server/schedule/rpc-schemas.d.ts +2773 -0
  395. package/dist/server/server/schedule/rpc-schemas.d.ts.map +1 -0
  396. package/dist/server/server/schedule/rpc-schemas.js +112 -0
  397. package/dist/server/server/schedule/rpc-schemas.js.map +1 -0
  398. package/dist/server/server/schedule/service.d.ts +39 -0
  399. package/dist/server/server/schedule/service.d.ts.map +1 -0
  400. package/dist/server/server/schedule/service.js +410 -0
  401. package/dist/server/server/schedule/service.js.map +1 -0
  402. package/dist/server/server/schedule/store.d.ts +13 -0
  403. package/dist/server/server/schedule/store.d.ts.map +1 -0
  404. package/dist/server/server/schedule/store.js +56 -0
  405. package/dist/server/server/schedule/store.js.map +1 -0
  406. package/dist/server/server/schedule/types.d.ts +710 -0
  407. package/dist/server/server/schedule/types.d.ts.map +1 -0
  408. package/dist/server/server/schedule/types.js +73 -0
  409. package/dist/server/server/schedule/types.js.map +1 -0
  410. package/dist/server/server/seawork-home.d.ts +2 -0
  411. package/dist/server/server/seawork-home.d.ts.map +1 -0
  412. package/dist/server/server/seawork-home.js +19 -0
  413. package/dist/server/server/seawork-home.js.map +1 -0
  414. package/dist/server/server/server-id.d.ts +17 -0
  415. package/dist/server/server/server-id.d.ts.map +1 -0
  416. package/dist/server/server/server-id.js +63 -0
  417. package/dist/server/server/server-id.js.map +1 -0
  418. package/dist/server/server/session.d.ts +510 -0
  419. package/dist/server/server/session.d.ts.map +1 -0
  420. package/dist/server/server/session.js +6414 -0
  421. package/dist/server/server/session.js.map +1 -0
  422. package/dist/server/server/speech/audio.d.ts +10 -0
  423. package/dist/server/server/speech/audio.d.ts.map +1 -0
  424. package/dist/server/server/speech/audio.js +101 -0
  425. package/dist/server/server/speech/audio.js.map +1 -0
  426. package/dist/server/server/speech/provider-resolver.d.ts +3 -0
  427. package/dist/server/server/speech/provider-resolver.d.ts.map +1 -0
  428. package/dist/server/server/speech/provider-resolver.js +7 -0
  429. package/dist/server/server/speech/provider-resolver.js.map +1 -0
  430. package/dist/server/server/speech/providers/local/config.d.ts +25 -0
  431. package/dist/server/server/speech/providers/local/config.d.ts.map +1 -0
  432. package/dist/server/server/speech/providers/local/config.js +74 -0
  433. package/dist/server/server/speech/providers/local/config.js.map +1 -0
  434. package/dist/server/server/speech/providers/local/models.d.ts +11 -0
  435. package/dist/server/server/speech/providers/local/models.d.ts.map +1 -0
  436. package/dist/server/server/speech/providers/local/models.js +17 -0
  437. package/dist/server/server/speech/providers/local/models.js.map +1 -0
  438. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts +24 -0
  439. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts.map +1 -0
  440. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js +436 -0
  441. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -0
  442. package/dist/server/server/speech/providers/local/runtime.d.ts +31 -0
  443. package/dist/server/server/speech/providers/local/runtime.d.ts.map +1 -0
  444. package/dist/server/server/speech/providers/local/runtime.js +247 -0
  445. package/dist/server/server/speech/providers/local/runtime.js.map +1 -0
  446. package/dist/server/server/speech/providers/local/sherpa/assets/silero_vad.onnx +0 -0
  447. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts +117 -0
  448. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts.map +1 -0
  449. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js +166 -0
  450. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js.map +1 -0
  451. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts +15 -0
  452. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts.map +1 -0
  453. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js +165 -0
  454. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js.map +1 -0
  455. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts +28 -0
  456. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts.map +1 -0
  457. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +73 -0
  458. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -0
  459. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts +37 -0
  460. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts.map +1 -0
  461. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +84 -0
  462. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -0
  463. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts +7 -0
  464. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts.map +1 -0
  465. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.js +11 -0
  466. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.js.map +1 -0
  467. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts +9 -0
  468. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts.map +1 -0
  469. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +102 -0
  470. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +1 -0
  471. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts +28 -0
  472. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts.map +1 -0
  473. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +135 -0
  474. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -0
  475. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts +21 -0
  476. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts.map +1 -0
  477. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +131 -0
  478. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -0
  479. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.d.ts +23 -0
  480. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.d.ts.map +1 -0
  481. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js +110 -0
  482. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -0
  483. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts +18 -0
  484. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts.map +1 -0
  485. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.js +84 -0
  486. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.js.map +1 -0
  487. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts +23 -0
  488. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts.map +1 -0
  489. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js +138 -0
  490. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -0
  491. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts +21 -0
  492. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts.map +1 -0
  493. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js +108 -0
  494. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -0
  495. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.d.ts +19 -0
  496. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.d.ts.map +1 -0
  497. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.js +49 -0
  498. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.js.map +1 -0
  499. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.d.ts +38 -0
  500. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.d.ts.map +1 -0
  501. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.js +176 -0
  502. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.js.map +1 -0
  503. package/dist/server/server/speech/providers/openai/config.d.ts +22 -0
  504. package/dist/server/server/speech/providers/openai/config.d.ts.map +1 -0
  505. package/dist/server/server/speech/providers/openai/config.js +80 -0
  506. package/dist/server/server/speech/providers/openai/config.js.map +1 -0
  507. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts +42 -0
  508. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts.map +1 -0
  509. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +168 -0
  510. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js.map +1 -0
  511. package/dist/server/server/speech/providers/openai/runtime.d.ts +29 -0
  512. package/dist/server/server/speech/providers/openai/runtime.d.ts.map +1 -0
  513. package/dist/server/server/speech/providers/openai/runtime.js +112 -0
  514. package/dist/server/server/speech/providers/openai/runtime.js.map +1 -0
  515. package/dist/server/server/speech/providers/openai/stt.d.ts +22 -0
  516. package/dist/server/server/speech/providers/openai/stt.d.ts.map +1 -0
  517. package/dist/server/server/speech/providers/openai/stt.js +206 -0
  518. package/dist/server/server/speech/providers/openai/stt.js.map +1 -0
  519. package/dist/server/server/speech/providers/openai/tts.d.ts +18 -0
  520. package/dist/server/server/speech/providers/openai/tts.d.ts.map +1 -0
  521. package/dist/server/server/speech/providers/openai/tts.js +46 -0
  522. package/dist/server/server/speech/providers/openai/tts.js.map +1 -0
  523. package/dist/server/server/speech/speech-config-resolver.d.ts +11 -0
  524. package/dist/server/server/speech/speech-config-resolver.d.ts.map +1 -0
  525. package/dist/server/server/speech/speech-config-resolver.js +104 -0
  526. package/dist/server/server/speech/speech-config-resolver.js.map +1 -0
  527. package/dist/server/server/speech/speech-provider.d.ts +59 -0
  528. package/dist/server/server/speech/speech-provider.d.ts.map +1 -0
  529. package/dist/server/server/speech/speech-provider.js +2 -0
  530. package/dist/server/server/speech/speech-provider.js.map +1 -0
  531. package/dist/server/server/speech/speech-runtime.d.ts +43 -0
  532. package/dist/server/server/speech/speech-runtime.d.ts.map +1 -0
  533. package/dist/server/server/speech/speech-runtime.js +560 -0
  534. package/dist/server/server/speech/speech-runtime.js.map +1 -0
  535. package/dist/server/server/speech/speech-types.d.ts +24 -0
  536. package/dist/server/server/speech/speech-types.d.ts.map +1 -0
  537. package/dist/server/server/speech/speech-types.js +8 -0
  538. package/dist/server/server/speech/speech-types.js.map +1 -0
  539. package/dist/server/server/speech/turn-detection-provider.d.ts +23 -0
  540. package/dist/server/server/speech/turn-detection-provider.d.ts.map +1 -0
  541. package/dist/server/server/speech/turn-detection-provider.js +2 -0
  542. package/dist/server/server/speech/turn-detection-provider.js.map +1 -0
  543. package/dist/server/server/types.d.ts +5 -0
  544. package/dist/server/server/types.d.ts.map +1 -0
  545. package/dist/server/server/types.js +3 -0
  546. package/dist/server/server/types.js.map +1 -0
  547. package/dist/server/server/utils/diff-highlighter.d.ts +60 -0
  548. package/dist/server/server/utils/diff-highlighter.d.ts.map +1 -0
  549. package/dist/server/server/utils/diff-highlighter.js +257 -0
  550. package/dist/server/server/utils/diff-highlighter.js.map +1 -0
  551. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.d.ts +16 -0
  552. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.d.ts.map +1 -0
  553. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.js +35 -0
  554. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.js.map +1 -0
  555. package/dist/server/server/voice/voice-turn-controller.d.ts +34 -0
  556. package/dist/server/server/voice/voice-turn-controller.d.ts.map +1 -0
  557. package/dist/server/server/voice/voice-turn-controller.js +160 -0
  558. package/dist/server/server/voice/voice-turn-controller.js.map +1 -0
  559. package/dist/server/server/voice-config.d.ts +15 -0
  560. package/dist/server/server/voice-config.d.ts.map +1 -0
  561. package/dist/server/server/voice-config.js +54 -0
  562. package/dist/server/server/voice-config.js.map +1 -0
  563. package/dist/server/server/voice-permission-policy.d.ts +4 -0
  564. package/dist/server/server/voice-permission-policy.d.ts.map +1 -0
  565. package/dist/server/server/voice-permission-policy.js +13 -0
  566. package/dist/server/server/voice-permission-policy.js.map +1 -0
  567. package/dist/server/server/voice-types.d.ts +12 -0
  568. package/dist/server/server/voice-types.d.ts.map +1 -0
  569. package/dist/server/server/voice-types.js +2 -0
  570. package/dist/server/server/voice-types.js.map +1 -0
  571. package/dist/server/server/websocket-server.d.ts +122 -0
  572. package/dist/server/server/websocket-server.d.ts.map +1 -0
  573. package/dist/server/server/websocket-server.js +1092 -0
  574. package/dist/server/server/websocket-server.js.map +1 -0
  575. package/dist/server/server/workspace-git-service.d.ts +108 -0
  576. package/dist/server/server/workspace-git-service.d.ts.map +1 -0
  577. package/dist/server/server/workspace-git-service.js +404 -0
  578. package/dist/server/server/workspace-git-service.js.map +1 -0
  579. package/dist/server/server/workspace-registry-bootstrap.d.ts +11 -0
  580. package/dist/server/server/workspace-registry-bootstrap.d.ts.map +1 -0
  581. package/dist/server/server/workspace-registry-bootstrap.js +100 -0
  582. package/dist/server/server/workspace-registry-bootstrap.js.map +1 -0
  583. package/dist/server/server/workspace-registry-model.d.ts +33 -0
  584. package/dist/server/server/workspace-registry-model.d.ts.map +1 -0
  585. package/dist/server/server/workspace-registry-model.js +167 -0
  586. package/dist/server/server/workspace-registry-model.js.map +1 -0
  587. package/dist/server/server/workspace-registry.d.ts +130 -0
  588. package/dist/server/server/workspace-registry.d.ts.map +1 -0
  589. package/dist/server/server/workspace-registry.js +151 -0
  590. package/dist/server/server/workspace-registry.js.map +1 -0
  591. package/dist/server/server/worktree-bootstrap.d.ts +29 -0
  592. package/dist/server/server/worktree-bootstrap.d.ts.map +1 -0
  593. package/dist/server/server/worktree-bootstrap.js +508 -0
  594. package/dist/server/server/worktree-bootstrap.js.map +1 -0
  595. package/dist/server/server/worktree-session.d.ts +131 -0
  596. package/dist/server/server/worktree-session.d.ts.map +1 -0
  597. package/dist/server/server/worktree-session.js +487 -0
  598. package/dist/server/server/worktree-session.js.map +1 -0
  599. package/dist/server/shared/agent-attention-notification.d.ts +40 -0
  600. package/dist/server/shared/agent-attention-notification.d.ts.map +1 -0
  601. package/dist/server/shared/agent-attention-notification.js +130 -0
  602. package/dist/server/shared/agent-attention-notification.js.map +1 -0
  603. package/dist/server/shared/agent-lifecycle.d.ts +3 -0
  604. package/dist/server/shared/agent-lifecycle.d.ts.map +1 -0
  605. package/dist/server/shared/agent-lifecycle.js +8 -0
  606. package/dist/server/shared/agent-lifecycle.js.map +1 -0
  607. package/dist/server/shared/connection-offer.d.ts +62 -0
  608. package/dist/server/shared/connection-offer.d.ts.map +1 -0
  609. package/dist/server/shared/connection-offer.js +17 -0
  610. package/dist/server/shared/connection-offer.js.map +1 -0
  611. package/dist/server/shared/daemon-endpoints.d.ts +28 -0
  612. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -0
  613. package/dist/server/shared/daemon-endpoints.js +122 -0
  614. package/dist/server/shared/daemon-endpoints.js.map +1 -0
  615. package/dist/server/shared/literal-union.d.ts +2 -0
  616. package/dist/server/shared/literal-union.d.ts.map +1 -0
  617. package/dist/server/shared/literal-union.js +2 -0
  618. package/dist/server/shared/literal-union.js.map +1 -0
  619. package/dist/server/shared/messages.d.ts +81816 -0
  620. package/dist/server/shared/messages.d.ts.map +1 -0
  621. package/dist/server/shared/messages.js +2553 -0
  622. package/dist/server/shared/messages.js.map +1 -0
  623. package/dist/server/shared/path-utils.d.ts +2 -0
  624. package/dist/server/shared/path-utils.d.ts.map +1 -0
  625. package/dist/server/shared/path-utils.js +16 -0
  626. package/dist/server/shared/path-utils.js.map +1 -0
  627. package/dist/server/shared/terminal-stream-protocol.d.ts +36 -0
  628. package/dist/server/shared/terminal-stream-protocol.d.ts.map +1 -0
  629. package/dist/server/shared/terminal-stream-protocol.js +99 -0
  630. package/dist/server/shared/terminal-stream-protocol.js.map +1 -0
  631. package/dist/server/shared/tool-call-display.d.ts +11 -0
  632. package/dist/server/shared/tool-call-display.d.ts.map +1 -0
  633. package/dist/server/shared/tool-call-display.js +133 -0
  634. package/dist/server/shared/tool-call-display.js.map +1 -0
  635. package/dist/server/terminal/terminal-manager.d.ts +30 -0
  636. package/dist/server/terminal/terminal-manager.d.ts.map +1 -0
  637. package/dist/server/terminal/terminal-manager.js +136 -0
  638. package/dist/server/terminal/terminal-manager.js.map +1 -0
  639. package/dist/server/terminal/terminal.d.ts +68 -0
  640. package/dist/server/terminal/terminal.d.ts.map +1 -0
  641. package/dist/server/terminal/terminal.js +384 -0
  642. package/dist/server/terminal/terminal.js.map +1 -0
  643. package/dist/server/utils/checkout-git.d.ts +180 -0
  644. package/dist/server/utils/checkout-git.d.ts.map +1 -0
  645. package/dist/server/utils/checkout-git.js +1621 -0
  646. package/dist/server/utils/checkout-git.js.map +1 -0
  647. package/dist/server/utils/directory-suggestions.d.ts +24 -0
  648. package/dist/server/utils/directory-suggestions.d.ts.map +1 -0
  649. package/dist/server/utils/directory-suggestions.js +671 -0
  650. package/dist/server/utils/directory-suggestions.js.map +1 -0
  651. package/dist/server/utils/executable.d.ts +33 -0
  652. package/dist/server/utils/executable.d.ts.map +1 -0
  653. package/dist/server/utils/executable.js +134 -0
  654. package/dist/server/utils/executable.js.map +1 -0
  655. package/dist/server/utils/path.d.ts +5 -0
  656. package/dist/server/utils/path.d.ts.map +1 -0
  657. package/dist/server/utils/path.js +15 -0
  658. package/dist/server/utils/path.js.map +1 -0
  659. package/dist/server/utils/project-icon.d.ts +39 -0
  660. package/dist/server/utils/project-icon.d.ts.map +1 -0
  661. package/dist/server/utils/project-icon.js +389 -0
  662. package/dist/server/utils/project-icon.js.map +1 -0
  663. package/dist/server/utils/spawn.d.ts +13 -0
  664. package/dist/server/utils/spawn.d.ts.map +1 -0
  665. package/dist/server/utils/spawn.js +33 -0
  666. package/dist/server/utils/spawn.js.map +1 -0
  667. package/dist/server/utils/worktree-metadata.d.ts +47 -0
  668. package/dist/server/utils/worktree-metadata.d.ts.map +1 -0
  669. package/dist/server/utils/worktree-metadata.js +116 -0
  670. package/dist/server/utils/worktree-metadata.js.map +1 -0
  671. package/dist/server/utils/worktree.d.ts +144 -0
  672. package/dist/server/utils/worktree.d.ts.map +1 -0
  673. package/dist/server/utils/worktree.js +745 -0
  674. package/dist/server/utils/worktree.js.map +1 -0
  675. package/dist/src/server/pid-lock.js +148 -0
  676. package/dist/src/server/pid-lock.js.map +1 -0
  677. package/dist/src/server/seawork-home.js +19 -0
  678. package/dist/src/server/seawork-home.js.map +1 -0
  679. package/dist/src/server/speech/providers/local/sherpa/sherpa-runtime-env.js +84 -0
  680. package/dist/src/server/speech/providers/local/sherpa/sherpa-runtime-env.js.map +1 -0
  681. package/package.json +117 -0
  682. package/src/server/speech/providers/local/sherpa/assets/silero_vad.onnx +0 -0
@@ -0,0 +1,1621 @@
1
+ import { exec, execFile } from "child_process";
2
+ import { spawnProcess } from "./spawn.js";
3
+ import { promisify } from "util";
4
+ import { resolve, dirname, basename } from "path";
5
+ import { existsSync, realpathSync } from "fs";
6
+ import { open as openFile, stat as statFile } from "fs/promises";
7
+ import { TTLCache } from "@isaacs/ttlcache";
8
+ import { parseAndHighlightDiff } from "../server/utils/diff-highlighter.js";
9
+ import { findExecutable } from "./executable.js";
10
+ import { isSeaworkOwnedWorktreeCwd } from "./worktree.js";
11
+ import { requireSeaworkWorktreeBaseRefName } from "./worktree-metadata.js";
12
+ const execAsync = promisify(exec);
13
+ const execFileAsync = promisify(execFile);
14
+ const READ_ONLY_GIT_ENV = {
15
+ ...process.env,
16
+ GIT_OPTIONAL_LOCKS: "0",
17
+ };
18
+ const SMALL_OUTPUT_MAX_BUFFER = 20 * 1024 * 1024; // 20MB
19
+ const DEFAULT_PULL_REQUEST_STATUS_CACHE_TTL_MS = 30000;
20
+ const PULL_REQUEST_STATUS_CACHE_MAX = 1000;
21
+ let pullRequestStatusCacheTtlMs = DEFAULT_PULL_REQUEST_STATUS_CACHE_TTL_MS;
22
+ let pullRequestStatusCache = createPullRequestStatusCache(pullRequestStatusCacheTtlMs);
23
+ const pullRequestStatusInFlight = new Map();
24
+ let cachedGhPath = undefined;
25
+ function createPullRequestStatusCache(ttlMs) {
26
+ return new TTLCache({
27
+ ttl: ttlMs,
28
+ max: PULL_REQUEST_STATUS_CACHE_MAX,
29
+ checkAgeOnGet: true,
30
+ });
31
+ }
32
+ function getPullRequestStatusCacheKey(cwd) {
33
+ return resolve(cwd);
34
+ }
35
+ export function __resetPullRequestStatusCacheForTests() {
36
+ pullRequestStatusCache.clear();
37
+ pullRequestStatusCache.cancelTimer();
38
+ pullRequestStatusCacheTtlMs = DEFAULT_PULL_REQUEST_STATUS_CACHE_TTL_MS;
39
+ pullRequestStatusCache = createPullRequestStatusCache(pullRequestStatusCacheTtlMs);
40
+ pullRequestStatusInFlight.clear();
41
+ }
42
+ export function __setPullRequestStatusCacheTtlForTests(ttlMs) {
43
+ pullRequestStatusCache.clear();
44
+ pullRequestStatusCache.cancelTimer();
45
+ pullRequestStatusCacheTtlMs = ttlMs;
46
+ pullRequestStatusCache = createPullRequestStatusCache(ttlMs);
47
+ pullRequestStatusInFlight.clear();
48
+ }
49
+ export function __resetGhPathCacheForTests() {
50
+ cachedGhPath = undefined;
51
+ }
52
+ export function __setGhPathForTests(path) {
53
+ cachedGhPath = path;
54
+ }
55
+ async function execGit(command, options) {
56
+ return execAsync(command, { ...options, maxBuffer: SMALL_OUTPUT_MAX_BUFFER });
57
+ }
58
+ async function spawnLimitedText(params) {
59
+ const accept = new Set(params.acceptExitCodes ?? [0]);
60
+ return new Promise((resolvePromise, rejectPromise) => {
61
+ const child = spawnProcess(params.cmd, params.args, {
62
+ cwd: params.cwd,
63
+ env: params.env,
64
+ stdio: ["ignore", "pipe", "pipe"],
65
+ });
66
+ const stdoutChunks = [];
67
+ let stdoutBytes = 0;
68
+ let truncated = false;
69
+ const stop = () => {
70
+ if (child.killed)
71
+ return;
72
+ try {
73
+ child.kill("SIGKILL");
74
+ }
75
+ catch {
76
+ // ignore
77
+ }
78
+ };
79
+ child.stdout.on("data", (chunk) => {
80
+ if (truncated)
81
+ return;
82
+ stdoutBytes += chunk.length;
83
+ if (stdoutBytes > params.maxBytes) {
84
+ truncated = true;
85
+ stop();
86
+ return;
87
+ }
88
+ stdoutChunks.push(chunk);
89
+ });
90
+ // We don't buffer stderr (it can be large too). Keep it minimal for debugging.
91
+ let stderrPreview = "";
92
+ child.stderr.on("data", (chunk) => {
93
+ if (stderrPreview.length > 2048)
94
+ return;
95
+ stderrPreview += chunk.toString("utf8");
96
+ });
97
+ child.on("error", (error) => {
98
+ rejectPromise(error);
99
+ });
100
+ child.on("close", (code, signal) => {
101
+ if (code !== null && !accept.has(code) && !truncated) {
102
+ rejectPromise(new Error(`Command failed: ${params.cmd} ${params.args.join(" ")} (code ${code})\n${stderrPreview}`));
103
+ return;
104
+ }
105
+ resolvePromise({
106
+ text: Buffer.concat(stdoutChunks).toString("utf8"),
107
+ truncated,
108
+ exitCode: code,
109
+ signal,
110
+ });
111
+ });
112
+ });
113
+ }
114
+ function normalizeBranchSuggestionName(raw) {
115
+ const trimmed = raw.trim();
116
+ if (!trimmed) {
117
+ return null;
118
+ }
119
+ let normalized = trimmed;
120
+ if (normalized.startsWith("refs/heads/")) {
121
+ normalized = normalized.slice("refs/heads/".length);
122
+ }
123
+ else if (normalized.startsWith("refs/remotes/")) {
124
+ normalized = normalized.slice("refs/remotes/".length);
125
+ }
126
+ if (normalized.startsWith("origin/")) {
127
+ normalized = normalized.slice("origin/".length);
128
+ }
129
+ if (!normalized || normalized === "HEAD" || normalized === "origin") {
130
+ return null;
131
+ }
132
+ return normalized;
133
+ }
134
+ async function listGitRefs(cwd, refPrefix) {
135
+ const { stdout } = await execGit(`git for-each-ref --sort=-committerdate --format="%(refname)%09%(committerdate:unix)" ${refPrefix}`, { cwd, env: READ_ONLY_GIT_ENV });
136
+ return stdout
137
+ .split("\n")
138
+ .map((line) => {
139
+ const trimmed = line.trim();
140
+ if (!trimmed)
141
+ return null;
142
+ const [name, dateStr] = trimmed.split("\t");
143
+ if (!name)
144
+ return null;
145
+ return { name, committerDate: Number(dateStr) || 0 };
146
+ })
147
+ .filter((ref) => ref !== null);
148
+ }
149
+ function sortBranchSuggestions(branchNames, branchMeta, query) {
150
+ const normalizedQuery = query.trim().toLowerCase();
151
+ const hasQuery = normalizedQuery.length > 0;
152
+ return branchNames.sort((a, b) => {
153
+ if (hasQuery) {
154
+ const aPrefix = a.toLowerCase().startsWith(normalizedQuery);
155
+ const bPrefix = b.toLowerCase().startsWith(normalizedQuery);
156
+ if (aPrefix !== bPrefix) {
157
+ return aPrefix ? -1 : 1;
158
+ }
159
+ }
160
+ const aMeta = branchMeta.get(a);
161
+ const bMeta = branchMeta.get(b);
162
+ const aDate = aMeta?.committerDate ?? 0;
163
+ const bDate = bMeta?.committerDate ?? 0;
164
+ if (aDate !== bDate) {
165
+ return bDate - aDate;
166
+ }
167
+ return a.localeCompare(b);
168
+ });
169
+ }
170
+ export async function listBranchSuggestions(cwd, options) {
171
+ await requireGitRepo(cwd);
172
+ const requestedLimit = options?.limit ?? 50;
173
+ const limit = Math.max(1, Math.min(200, requestedLimit));
174
+ const query = options?.query?.trim().toLowerCase() ?? "";
175
+ const [localRefs, remoteRefs] = await Promise.all([
176
+ listGitRefs(cwd, "refs/heads"),
177
+ listGitRefs(cwd, "refs/remotes/origin"),
178
+ ]);
179
+ const branchMeta = new Map();
180
+ for (const ref of localRefs) {
181
+ const normalized = normalizeBranchSuggestionName(ref.name);
182
+ if (!normalized)
183
+ continue;
184
+ const existing = branchMeta.get(normalized);
185
+ branchMeta.set(normalized, {
186
+ isLocal: true,
187
+ committerDate: Math.max(ref.committerDate, existing?.committerDate ?? 0),
188
+ });
189
+ }
190
+ for (const ref of remoteRefs) {
191
+ const normalized = normalizeBranchSuggestionName(ref.name);
192
+ if (!normalized)
193
+ continue;
194
+ const existing = branchMeta.get(normalized);
195
+ if (!existing) {
196
+ branchMeta.set(normalized, { isLocal: false, committerDate: ref.committerDate });
197
+ }
198
+ else {
199
+ branchMeta.set(normalized, {
200
+ ...existing,
201
+ committerDate: Math.max(ref.committerDate, existing.committerDate),
202
+ });
203
+ }
204
+ }
205
+ const filteredNames = Array.from(branchMeta.keys()).filter((name) => query ? name.toLowerCase().includes(query) : true);
206
+ if (filteredNames.length === 0) {
207
+ return [];
208
+ }
209
+ const ordered = sortBranchSuggestions(filteredNames, branchMeta, query);
210
+ return ordered.slice(0, limit);
211
+ }
212
+ async function listCheckoutFileChanges(cwd, ref, ignoreWhitespace = false) {
213
+ const changes = [];
214
+ const { stdout: nameStatusOut } = await execFileAsync("git", buildGitDiffArgs({
215
+ ignoreWhitespace,
216
+ extra: ["--name-status", ref],
217
+ }), {
218
+ cwd,
219
+ env: READ_ONLY_GIT_ENV,
220
+ maxBuffer: SMALL_OUTPUT_MAX_BUFFER,
221
+ });
222
+ for (const line of nameStatusOut
223
+ .split("\n")
224
+ .map((l) => l.trim())
225
+ .filter(Boolean)) {
226
+ // `--name-status` uses TAB separators, which preserves filenames with spaces.
227
+ const tabParts = line.split("\t");
228
+ const rawStatus = (tabParts[0] ?? "").trim();
229
+ if (!rawStatus)
230
+ continue;
231
+ if (rawStatus.startsWith("R") || rawStatus.startsWith("C")) {
232
+ const oldPath = tabParts[1];
233
+ const newPath = tabParts[2];
234
+ if (newPath) {
235
+ changes.push({
236
+ path: newPath,
237
+ ...(oldPath ? { oldPath } : {}),
238
+ status: rawStatus,
239
+ isNew: false,
240
+ isDeleted: false,
241
+ });
242
+ }
243
+ continue;
244
+ }
245
+ const path = tabParts[1];
246
+ if (!path)
247
+ continue;
248
+ const code = rawStatus[0];
249
+ changes.push({
250
+ path,
251
+ status: rawStatus,
252
+ isNew: code === "A",
253
+ isDeleted: code === "D",
254
+ });
255
+ }
256
+ const { stdout: untrackedOut } = await execGit("git ls-files --others --exclude-standard", {
257
+ cwd,
258
+ env: READ_ONLY_GIT_ENV,
259
+ });
260
+ for (const file of untrackedOut
261
+ .split("\n")
262
+ .map((l) => l.trim())
263
+ .filter(Boolean)) {
264
+ changes.push({
265
+ path: file,
266
+ status: "U",
267
+ isNew: true,
268
+ isDeleted: false,
269
+ isUntracked: true,
270
+ });
271
+ }
272
+ // Deduplicate by path (prefer tracked status over untracked marker if both appear).
273
+ const byPath = new Map();
274
+ for (const change of changes) {
275
+ const existing = byPath.get(change.path);
276
+ if (!existing) {
277
+ byPath.set(change.path, change);
278
+ continue;
279
+ }
280
+ if (existing.isUntracked && !change.isUntracked) {
281
+ byPath.set(change.path, change);
282
+ }
283
+ }
284
+ return Array.from(byPath.values());
285
+ }
286
+ async function readGitFileContentAtRef(cwd, ref, path) {
287
+ try {
288
+ const { stdout } = await execFileAsync("git", ["show", `${ref}:${path}`], {
289
+ cwd,
290
+ env: READ_ONLY_GIT_ENV,
291
+ maxBuffer: SMALL_OUTPUT_MAX_BUFFER,
292
+ });
293
+ return stdout;
294
+ }
295
+ catch {
296
+ return null;
297
+ }
298
+ }
299
+ async function tryResolveMergeBase(cwd, baseRef) {
300
+ try {
301
+ const { stdout } = await execGit(`git merge-base ${baseRef} HEAD`, {
302
+ cwd,
303
+ env: READ_ONLY_GIT_ENV,
304
+ });
305
+ const sha = stdout.trim();
306
+ return sha.length > 0 ? sha : null;
307
+ }
308
+ catch {
309
+ return null;
310
+ }
311
+ }
312
+ function normalizeNumstatPath(pathField) {
313
+ const braceRenameMatch = pathField.match(/^(.*)\{(.*) => (.*)\}(.*)$/);
314
+ if (braceRenameMatch) {
315
+ const [, prefix, , renamed, suffix] = braceRenameMatch;
316
+ return `${prefix}${renamed}${suffix}`;
317
+ }
318
+ const inlineRenameMatch = pathField.match(/^(.*) => (.*)$/);
319
+ if (inlineRenameMatch) {
320
+ return inlineRenameMatch[2] ?? pathField;
321
+ }
322
+ return pathField;
323
+ }
324
+ function buildGitDiffArgs(args) {
325
+ return ["diff", ...(args.ignoreWhitespace ? ["-w"] : []), ...args.extra];
326
+ }
327
+ const TRACKED_DIFF_NUMSTAT_MAX_BYTES = 2 * 1024 * 1024; // 2MB
328
+ const TRACKED_MAX_CHANGED_LINES = 40000;
329
+ async function getTrackedNumstatByPath(cwd, ref, ignoreWhitespace = false) {
330
+ const result = await spawnLimitedText({
331
+ cmd: "git",
332
+ args: buildGitDiffArgs({
333
+ ignoreWhitespace,
334
+ extra: ["--numstat", ref],
335
+ }),
336
+ cwd,
337
+ env: READ_ONLY_GIT_ENV,
338
+ maxBytes: TRACKED_DIFF_NUMSTAT_MAX_BYTES,
339
+ acceptExitCodes: [0],
340
+ });
341
+ const stats = new Map();
342
+ const lines = result.text
343
+ .split("\n")
344
+ .map((line) => line.trim())
345
+ .filter(Boolean);
346
+ for (const line of lines) {
347
+ const parts = line.split("\t");
348
+ if (parts.length < 3) {
349
+ continue;
350
+ }
351
+ const additionsField = parts[0] ?? "";
352
+ const deletionsField = parts[1] ?? "";
353
+ const rawPath = parts.slice(2).join("\t");
354
+ const path = normalizeNumstatPath(rawPath);
355
+ if (!path) {
356
+ continue;
357
+ }
358
+ if (additionsField === "-" || deletionsField === "-") {
359
+ stats.set(path, { additions: 0, deletions: 0, isBinary: true });
360
+ continue;
361
+ }
362
+ const additions = Number.parseInt(additionsField, 10);
363
+ const deletions = Number.parseInt(deletionsField, 10);
364
+ if (Number.isNaN(additions) || Number.isNaN(deletions)) {
365
+ stats.set(path, null);
366
+ continue;
367
+ }
368
+ stats.set(path, { additions, deletions, isBinary: false });
369
+ }
370
+ return stats;
371
+ }
372
+ function isTrackedDiffTooLarge(stat) {
373
+ if (!stat || stat.isBinary) {
374
+ return false;
375
+ }
376
+ return stat.additions + stat.deletions > TRACKED_MAX_CHANGED_LINES;
377
+ }
378
+ export class NotGitRepoError extends Error {
379
+ constructor(cwd) {
380
+ super(`Not a git repository: ${cwd}`);
381
+ this.code = "NOT_GIT_REPO";
382
+ this.name = "NotGitRepoError";
383
+ this.cwd = cwd;
384
+ }
385
+ }
386
+ export class MergeConflictError extends Error {
387
+ constructor(options) {
388
+ super(`Merge conflict while merging ${options.currentBranch} into ${options.baseRef}`);
389
+ this.name = "MergeConflictError";
390
+ this.baseRef = options.baseRef;
391
+ this.currentBranch = options.currentBranch;
392
+ this.conflictFiles = options.conflictFiles;
393
+ }
394
+ }
395
+ export class MergeFromBaseConflictError extends Error {
396
+ constructor(options) {
397
+ super(`Merge conflict while merging ${options.baseRef} into ${options.currentBranch}. Please merge manually.`);
398
+ this.name = "MergeFromBaseConflictError";
399
+ this.baseRef = options.baseRef;
400
+ this.currentBranch = options.currentBranch;
401
+ this.conflictFiles = options.conflictFiles;
402
+ }
403
+ }
404
+ function isGitError(error) {
405
+ if (!(error instanceof Error)) {
406
+ return false;
407
+ }
408
+ return /not a git repository/i.test(error.message) || /git repository/i.test(error.message);
409
+ }
410
+ async function requireGitRepo(cwd) {
411
+ try {
412
+ await execAsync("git rev-parse --git-dir", { cwd, env: READ_ONLY_GIT_ENV });
413
+ }
414
+ catch (error) {
415
+ throw new NotGitRepoError(cwd);
416
+ }
417
+ }
418
+ export async function getCurrentBranch(cwd) {
419
+ const { stdout } = await execAsync("git rev-parse --abbrev-ref HEAD", {
420
+ cwd,
421
+ env: READ_ONLY_GIT_ENV,
422
+ });
423
+ const branch = stdout.trim();
424
+ return branch.length > 0 ? branch : null;
425
+ }
426
+ async function getWorktreeRoot(cwd) {
427
+ try {
428
+ const { stdout } = await execAsync("git rev-parse --path-format=absolute --show-toplevel", {
429
+ cwd,
430
+ env: READ_ONLY_GIT_ENV,
431
+ });
432
+ const root = stdout.trim();
433
+ return root.length > 0 ? root : null;
434
+ }
435
+ catch {
436
+ return null;
437
+ }
438
+ }
439
+ export async function getMainRepoRoot(cwd) {
440
+ const { stdout: commonDirOut } = await execAsync("git rev-parse --path-format=absolute --git-common-dir", { cwd, env: READ_ONLY_GIT_ENV });
441
+ const commonDir = commonDirOut.trim();
442
+ const normalized = realpathSync(commonDir);
443
+ if (basename(normalized) === ".git") {
444
+ return dirname(normalized);
445
+ }
446
+ const { stdout: worktreeOut } = await execAsync("git worktree list --porcelain", {
447
+ cwd,
448
+ env: READ_ONLY_GIT_ENV,
449
+ });
450
+ const worktrees = parseWorktreeList(worktreeOut);
451
+ const nonBareNonSeawork = worktrees.filter((wt) => !wt.isBare && !isSeaworkWorktreePath(wt.path));
452
+ const childrenOfBareRepo = nonBareNonSeawork.filter((wt) => isDescendantPath(wt.path, normalized));
453
+ const mainChild = childrenOfBareRepo.find((wt) => basename(wt.path) === "main");
454
+ return mainChild?.path ?? childrenOfBareRepo[0]?.path ?? nonBareNonSeawork[0]?.path ?? normalized;
455
+ }
456
+ /** Check whether a path contains a `.seawork/worktrees/` segment (both `/` and `\`). */
457
+ export function isSeaworkWorktreePath(p) {
458
+ return /[/\\]\.seawork[/\\]worktrees[/\\]/.test(p);
459
+ }
460
+ /** True when `child` is strictly inside `parent` (handles both `/` and `\`). */
461
+ export function isDescendantPath(child, parent) {
462
+ let c = child.replace(/\\/g, "/").replace(/\/+$/, "");
463
+ let p = parent.replace(/\\/g, "/").replace(/\/+$/, "");
464
+ // Case-insensitive on Windows (drive letter like C: or D:)
465
+ if (/^[A-Za-z]:/.test(c) || /^[A-Za-z]:/.test(p)) {
466
+ c = c.toLowerCase();
467
+ p = p.toLowerCase();
468
+ }
469
+ if (!c.startsWith(p))
470
+ return false;
471
+ if (c.length === p.length)
472
+ return false;
473
+ return c[p.length] === "/";
474
+ }
475
+ export function parseWorktreeList(output) {
476
+ const entries = [];
477
+ let current = null;
478
+ for (const line of output.split("\n")) {
479
+ const trimmed = line.trim();
480
+ if (!trimmed) {
481
+ continue;
482
+ }
483
+ if (trimmed.startsWith("worktree ")) {
484
+ if (current) {
485
+ entries.push(current);
486
+ }
487
+ current = { path: trimmed.slice("worktree ".length).trim() };
488
+ continue;
489
+ }
490
+ if (current && trimmed.startsWith("branch ")) {
491
+ current.branchRef = trimmed.slice("branch ".length).trim();
492
+ }
493
+ if (current && trimmed === "bare") {
494
+ current.isBare = true;
495
+ }
496
+ }
497
+ if (current) {
498
+ entries.push(current);
499
+ }
500
+ return entries;
501
+ }
502
+ async function getWorktreePathForBranch(cwd, branchName) {
503
+ try {
504
+ const { stdout } = await execAsync("git worktree list --porcelain", {
505
+ cwd,
506
+ env: READ_ONLY_GIT_ENV,
507
+ });
508
+ const entries = parseWorktreeList(stdout);
509
+ const ref = branchName.startsWith("refs/heads/") ? branchName : `refs/heads/${branchName}`;
510
+ return entries.find((entry) => entry.branchRef === ref)?.path ?? null;
511
+ }
512
+ catch {
513
+ return null;
514
+ }
515
+ }
516
+ export async function renameCurrentBranch(cwd, newName) {
517
+ await requireGitRepo(cwd);
518
+ const previousBranch = await getCurrentBranch(cwd);
519
+ if (!previousBranch || previousBranch === "HEAD") {
520
+ throw new Error("Cannot rename branch in detached HEAD state");
521
+ }
522
+ await execAsync(`git branch -m "${newName}"`, {
523
+ cwd,
524
+ });
525
+ const currentBranch = await getCurrentBranch(cwd);
526
+ return { previousBranch, currentBranch };
527
+ }
528
+ async function getConfiguredBaseRefForCwd(cwd, context) {
529
+ // Fast-path reject: non-worktree paths do not need expensive ownership checks.
530
+ if (!/[\\/]worktrees[\\/]/.test(cwd)) {
531
+ return { baseRef: null, isSeaworkOwnedWorktree: false };
532
+ }
533
+ const ownership = await isSeaworkOwnedWorktreeCwd(cwd, { seaworkHome: context?.seaworkHome });
534
+ if (!ownership.allowed) {
535
+ return { baseRef: null, isSeaworkOwnedWorktree: false };
536
+ }
537
+ const worktreeRoot = (await getWorktreeRoot(cwd)) ?? cwd;
538
+ return {
539
+ baseRef: requireSeaworkWorktreeBaseRefName(worktreeRoot),
540
+ isSeaworkOwnedWorktree: true,
541
+ };
542
+ }
543
+ async function isWorkingTreeDirty(cwd) {
544
+ const { stdout } = await execAsync("git status --porcelain", {
545
+ cwd,
546
+ env: READ_ONLY_GIT_ENV,
547
+ });
548
+ return stdout.trim().length > 0;
549
+ }
550
+ export async function getOriginRemoteUrl(cwd) {
551
+ try {
552
+ const { stdout } = await execAsync("git config --get remote.origin.url", {
553
+ cwd,
554
+ env: READ_ONLY_GIT_ENV,
555
+ });
556
+ const url = stdout.trim();
557
+ return url.length > 0 ? url : null;
558
+ }
559
+ catch {
560
+ return null;
561
+ }
562
+ }
563
+ export async function hasOriginRemote(cwd) {
564
+ const url = await getOriginRemoteUrl(cwd);
565
+ return url !== null;
566
+ }
567
+ export async function resolveAbsoluteGitDir(cwd) {
568
+ try {
569
+ const { stdout } = await execAsync("git rev-parse --absolute-git-dir", {
570
+ cwd,
571
+ env: READ_ONLY_GIT_ENV,
572
+ });
573
+ const gitDir = stdout.trim();
574
+ return gitDir.length > 0 ? gitDir : null;
575
+ }
576
+ catch {
577
+ return null;
578
+ }
579
+ }
580
+ async function abortGitPullConflictState(cwd) {
581
+ const gitDir = await resolveAbsoluteGitDir(cwd);
582
+ if (!gitDir) {
583
+ return;
584
+ }
585
+ const mergeHeadPath = resolve(gitDir, "MERGE_HEAD");
586
+ const rebaseMergePath = resolve(gitDir, "rebase-merge");
587
+ const rebaseApplyPath = resolve(gitDir, "rebase-apply");
588
+ if (existsSync(mergeHeadPath)) {
589
+ try {
590
+ await execAsync("git merge --abort", { cwd });
591
+ }
592
+ catch {
593
+ // ignore
594
+ }
595
+ }
596
+ if (existsSync(rebaseMergePath) || existsSync(rebaseApplyPath)) {
597
+ try {
598
+ await execAsync("git rebase --abort", { cwd });
599
+ }
600
+ catch {
601
+ // ignore
602
+ }
603
+ }
604
+ }
605
+ export async function resolveRepositoryDefaultBranch(repoRoot) {
606
+ try {
607
+ const { stdout } = await execAsync("git symbolic-ref --quiet refs/remotes/origin/HEAD", {
608
+ cwd: repoRoot,
609
+ env: READ_ONLY_GIT_ENV,
610
+ });
611
+ const ref = stdout.trim();
612
+ if (ref) {
613
+ // Prefer a local branch name (e.g. "main") over the remote-tracking ref (e.g. "origin/main")
614
+ // so that status/diff/merge all operate against the same base ref.
615
+ const remoteShort = ref.replace(/^refs\/remotes\//, "");
616
+ const localName = remoteShort.startsWith("origin/")
617
+ ? remoteShort.slice("origin/".length)
618
+ : remoteShort;
619
+ try {
620
+ await execAsync(`git show-ref --verify --quiet refs/heads/${localName}`, {
621
+ cwd: repoRoot,
622
+ env: READ_ONLY_GIT_ENV,
623
+ });
624
+ return localName;
625
+ }
626
+ catch {
627
+ return remoteShort;
628
+ }
629
+ }
630
+ }
631
+ catch {
632
+ // ignore
633
+ }
634
+ const { stdout } = await execAsync("git branch --format='%(refname:short)'", {
635
+ cwd: repoRoot,
636
+ env: READ_ONLY_GIT_ENV,
637
+ });
638
+ const branches = stdout
639
+ .split("\n")
640
+ .map((line) => line.trim())
641
+ .filter((line) => line.length > 0);
642
+ if (branches.includes("main")) {
643
+ return "main";
644
+ }
645
+ if (branches.includes("master")) {
646
+ return "master";
647
+ }
648
+ return null;
649
+ }
650
+ async function resolveBaseRef(repoRoot) {
651
+ return resolveRepositoryDefaultBranch(repoRoot);
652
+ }
653
+ function normalizeLocalBranchRefName(input) {
654
+ return input.startsWith("origin/") ? input.slice("origin/".length) : input;
655
+ }
656
+ async function doesGitRefExist(cwd, fullRef) {
657
+ try {
658
+ await execAsync(`git show-ref --verify --quiet ${fullRef}`, {
659
+ cwd,
660
+ env: READ_ONLY_GIT_ENV,
661
+ });
662
+ return true;
663
+ }
664
+ catch {
665
+ return false;
666
+ }
667
+ }
668
+ async function resolveBestComparisonBaseRef(cwd, normalizedBaseRef) {
669
+ const [hasLocal, hasOrigin] = await Promise.all([
670
+ doesGitRefExist(cwd, `refs/heads/${normalizedBaseRef}`),
671
+ doesGitRefExist(cwd, `refs/remotes/origin/${normalizedBaseRef}`),
672
+ ]);
673
+ if (hasLocal && !hasOrigin) {
674
+ return normalizedBaseRef;
675
+ }
676
+ if (!hasLocal && hasOrigin) {
677
+ return `origin/${normalizedBaseRef}`;
678
+ }
679
+ if (!hasLocal && !hasOrigin) {
680
+ throw new Error(`Base branch not found locally or on origin: ${normalizedBaseRef}`);
681
+ }
682
+ // Both exist: choose the ref with more unique commits compared to the other.
683
+ try {
684
+ const { stdout } = await execAsync(`git rev-list --left-right --count ${normalizedBaseRef}...origin/${normalizedBaseRef}`, { cwd, env: READ_ONLY_GIT_ENV });
685
+ const [localOnlyRaw, originOnlyRaw] = stdout.trim().split(/\s+/);
686
+ const localOnly = Number.parseInt(localOnlyRaw ?? "0", 10);
687
+ const originOnly = Number.parseInt(originOnlyRaw ?? "0", 10);
688
+ if (!Number.isNaN(localOnly) && !Number.isNaN(originOnly) && originOnly > localOnly) {
689
+ return `origin/${normalizedBaseRef}`;
690
+ }
691
+ }
692
+ catch {
693
+ // ignore and fall back to local
694
+ }
695
+ return normalizedBaseRef;
696
+ }
697
+ async function getAheadBehind(cwd, baseRef, currentBranch) {
698
+ const normalizedBaseRef = normalizeLocalBranchRefName(baseRef);
699
+ if (!normalizedBaseRef || !currentBranch || normalizedBaseRef === currentBranch) {
700
+ return null;
701
+ }
702
+ const comparisonBaseRef = await resolveBestComparisonBaseRef(cwd, normalizedBaseRef);
703
+ const { stdout } = await execAsync(`git rev-list --left-right --count ${comparisonBaseRef}...${currentBranch}`, { cwd, env: READ_ONLY_GIT_ENV });
704
+ const [behindRaw, aheadRaw] = stdout.trim().split(/\s+/);
705
+ const behind = Number.parseInt(behindRaw ?? "0", 10);
706
+ const ahead = Number.parseInt(aheadRaw ?? "0", 10);
707
+ if (Number.isNaN(behind) || Number.isNaN(ahead)) {
708
+ return null;
709
+ }
710
+ return { ahead, behind };
711
+ }
712
+ async function getAheadOfOrigin(cwd, currentBranch) {
713
+ if (!currentBranch) {
714
+ return null;
715
+ }
716
+ try {
717
+ const { stdout } = await execAsync(`git rev-list --count origin/${currentBranch}..${currentBranch}`, { cwd, env: READ_ONLY_GIT_ENV });
718
+ const count = Number.parseInt(stdout.trim(), 10);
719
+ return Number.isNaN(count) ? null : count;
720
+ }
721
+ catch {
722
+ try {
723
+ const { stdout } = await execAsync(`git rev-list --count ${currentBranch}`, {
724
+ cwd,
725
+ env: READ_ONLY_GIT_ENV,
726
+ });
727
+ const count = Number.parseInt(stdout.trim(), 10);
728
+ return Number.isNaN(count) ? null : count;
729
+ }
730
+ catch {
731
+ return null;
732
+ }
733
+ }
734
+ }
735
+ async function getBehindOfOrigin(cwd, currentBranch) {
736
+ if (!currentBranch) {
737
+ return null;
738
+ }
739
+ try {
740
+ const { stdout } = await execAsync(`git rev-list --count ${currentBranch}..origin/${currentBranch}`, { cwd, env: READ_ONLY_GIT_ENV });
741
+ const count = Number.parseInt(stdout.trim(), 10);
742
+ return Number.isNaN(count) ? null : count;
743
+ }
744
+ catch {
745
+ return null;
746
+ }
747
+ }
748
+ async function inspectCheckoutContext(cwd, context) {
749
+ try {
750
+ const root = await getWorktreeRoot(cwd);
751
+ if (!root) {
752
+ return null;
753
+ }
754
+ const [currentBranch, remoteUrl, configured] = await Promise.all([
755
+ getCurrentBranch(cwd),
756
+ getOriginRemoteUrl(cwd),
757
+ getConfiguredBaseRefForCwd(cwd, context),
758
+ ]);
759
+ return {
760
+ worktreeRoot: root,
761
+ currentBranch,
762
+ remoteUrl,
763
+ configured,
764
+ };
765
+ }
766
+ catch (error) {
767
+ if (isGitError(error)) {
768
+ return null;
769
+ }
770
+ throw error;
771
+ }
772
+ }
773
+ const PER_FILE_DIFF_MAX_BYTES = 1024 * 1024; // 1MB
774
+ const TOTAL_DIFF_MAX_BYTES = 2 * 1024 * 1024; // 2MB
775
+ const UNTRACKED_BINARY_SNIFF_BYTES = 16 * 1024;
776
+ async function isLikelyBinaryFile(absolutePath) {
777
+ const handle = await openFile(absolutePath, "r");
778
+ try {
779
+ const buffer = Buffer.allocUnsafe(UNTRACKED_BINARY_SNIFF_BYTES);
780
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
781
+ if (bytesRead === 0) {
782
+ return false;
783
+ }
784
+ let suspicious = 0;
785
+ for (let i = 0; i < bytesRead; i += 1) {
786
+ const byte = buffer[i];
787
+ if (byte === 0) {
788
+ return true;
789
+ }
790
+ // Treat control bytes as suspicious while allowing common whitespace.
791
+ if (byte < 7 || (byte > 14 && byte < 32) || byte === 127) {
792
+ suspicious += 1;
793
+ }
794
+ }
795
+ return suspicious / bytesRead > 0.3;
796
+ }
797
+ finally {
798
+ await handle.close();
799
+ }
800
+ }
801
+ async function inspectUntrackedFile(cwd, relativePath) {
802
+ const absolutePath = resolve(cwd, relativePath);
803
+ const metadata = await statFile(absolutePath);
804
+ if (!metadata.isFile()) {
805
+ return { stat: null, truncated: false };
806
+ }
807
+ if (await isLikelyBinaryFile(absolutePath)) {
808
+ return {
809
+ stat: { additions: 0, deletions: 0, isBinary: true },
810
+ truncated: false,
811
+ };
812
+ }
813
+ if (metadata.size > PER_FILE_DIFF_MAX_BYTES) {
814
+ return {
815
+ stat: { additions: 0, deletions: 0, isBinary: false },
816
+ truncated: true,
817
+ };
818
+ }
819
+ return {
820
+ stat: { additions: 0, deletions: 0, isBinary: false },
821
+ truncated: false,
822
+ };
823
+ }
824
+ function buildPlaceholderParsedDiffFile(change, options) {
825
+ return {
826
+ path: change.path,
827
+ isNew: change.isNew,
828
+ isDeleted: change.isDeleted,
829
+ additions: options.stat?.additions ?? 0,
830
+ deletions: options.stat?.deletions ?? 0,
831
+ hunks: [],
832
+ status: options.status,
833
+ };
834
+ }
835
+ async function getUntrackedDiffText(cwd, change, ignoreWhitespace = false) {
836
+ try {
837
+ const inspected = await inspectUntrackedFile(cwd, change.path);
838
+ if (inspected.stat?.isBinary || inspected.truncated) {
839
+ return { text: "", truncated: inspected.truncated, stat: inspected.stat };
840
+ }
841
+ }
842
+ catch {
843
+ // Fall through to git diff path if metadata probing fails.
844
+ }
845
+ const result = await spawnLimitedText({
846
+ cmd: "git",
847
+ args: buildGitDiffArgs({
848
+ ignoreWhitespace,
849
+ extra: ["--no-index", "/dev/null", "--", change.path],
850
+ }),
851
+ cwd,
852
+ env: READ_ONLY_GIT_ENV,
853
+ maxBytes: PER_FILE_DIFF_MAX_BYTES,
854
+ acceptExitCodes: [0, 1],
855
+ });
856
+ return {
857
+ text: result.text,
858
+ truncated: result.truncated,
859
+ stat: { additions: 0, deletions: 0, isBinary: false },
860
+ };
861
+ }
862
+ export async function getCheckoutStatus(cwd, context) {
863
+ const inspected = await inspectCheckoutContext(cwd, context);
864
+ if (!inspected) {
865
+ return { isGit: false };
866
+ }
867
+ const worktreeRoot = inspected.worktreeRoot;
868
+ const currentBranch = inspected.currentBranch;
869
+ const remoteUrl = inspected.remoteUrl;
870
+ const configured = inspected.configured;
871
+ const isDirty = await isWorkingTreeDirty(cwd);
872
+ const hasRemote = remoteUrl !== null;
873
+ const baseRef = configured.baseRef ?? (await resolveBaseRef(cwd));
874
+ const [aheadBehind, aheadOfOrigin, behindOfOrigin] = await Promise.all([
875
+ baseRef && currentBranch ? getAheadBehind(cwd, baseRef, currentBranch) : Promise.resolve(null),
876
+ hasRemote && currentBranch ? getAheadOfOrigin(cwd, currentBranch) : Promise.resolve(null),
877
+ hasRemote && currentBranch ? getBehindOfOrigin(cwd, currentBranch) : Promise.resolve(null),
878
+ ]);
879
+ if (configured.isSeaworkOwnedWorktree) {
880
+ const mainRepoRoot = await getMainRepoRoot(cwd);
881
+ return {
882
+ isGit: true,
883
+ repoRoot: worktreeRoot,
884
+ mainRepoRoot,
885
+ currentBranch,
886
+ isDirty,
887
+ baseRef: configured.baseRef,
888
+ aheadBehind,
889
+ aheadOfOrigin,
890
+ behindOfOrigin,
891
+ hasRemote,
892
+ remoteUrl,
893
+ isSeaworkOwnedWorktree: true,
894
+ };
895
+ }
896
+ return {
897
+ isGit: true,
898
+ repoRoot: worktreeRoot,
899
+ currentBranch,
900
+ isDirty,
901
+ baseRef,
902
+ aheadBehind,
903
+ aheadOfOrigin,
904
+ behindOfOrigin,
905
+ hasRemote,
906
+ remoteUrl,
907
+ isSeaworkOwnedWorktree: false,
908
+ };
909
+ }
910
+ export async function getCheckoutStatusLite(cwd, context) {
911
+ const inspected = await inspectCheckoutContext(cwd, context);
912
+ if (!inspected) {
913
+ return {
914
+ isGit: false,
915
+ currentBranch: null,
916
+ remoteUrl: null,
917
+ worktreeRoot: null,
918
+ isSeaworkOwnedWorktree: false,
919
+ mainRepoRoot: null,
920
+ };
921
+ }
922
+ if (inspected.configured.isSeaworkOwnedWorktree) {
923
+ return {
924
+ isGit: true,
925
+ currentBranch: inspected.currentBranch,
926
+ remoteUrl: inspected.remoteUrl,
927
+ worktreeRoot: inspected.worktreeRoot,
928
+ isSeaworkOwnedWorktree: true,
929
+ mainRepoRoot: await getMainRepoRoot(cwd),
930
+ };
931
+ }
932
+ return {
933
+ isGit: true,
934
+ currentBranch: inspected.currentBranch,
935
+ remoteUrl: inspected.remoteUrl,
936
+ worktreeRoot: inspected.worktreeRoot,
937
+ isSeaworkOwnedWorktree: false,
938
+ mainRepoRoot: null,
939
+ };
940
+ }
941
+ export async function getCheckoutShortstat(cwd, context) {
942
+ try {
943
+ await requireGitRepo(cwd);
944
+ }
945
+ catch {
946
+ return null;
947
+ }
948
+ const configured = await getConfiguredBaseRefForCwd(cwd, context);
949
+ const localBaseRef = configured.baseRef ?? (await resolveBaseRef(cwd));
950
+ const currentBranch = await getCurrentBranch(cwd);
951
+ let diffTarget;
952
+ if (currentBranch && localBaseRef && currentBranch !== localBaseRef) {
953
+ // Feature branch: diff against the merge-base with the base branch
954
+ const comparisonBaseRef = await resolveBestComparisonBaseRef(cwd, normalizeLocalBranchRefName(localBaseRef));
955
+ try {
956
+ const { stdout } = await execAsync(`git merge-base HEAD ${comparisonBaseRef}`, {
957
+ cwd,
958
+ env: READ_ONLY_GIT_ENV,
959
+ });
960
+ const mergeBase = stdout.trim();
961
+ if (!mergeBase) {
962
+ return null;
963
+ }
964
+ diffTarget = mergeBase;
965
+ }
966
+ catch {
967
+ return null;
968
+ }
969
+ }
970
+ else if (currentBranch) {
971
+ // On the base branch (or no base ref configured): diff against remote tracking branch
972
+ const hasOrigin = await doesGitRefExist(cwd, `refs/remotes/origin/${currentBranch}`);
973
+ if (!hasOrigin) {
974
+ return null;
975
+ }
976
+ diffTarget = `origin/${currentBranch}`;
977
+ }
978
+ else {
979
+ return null;
980
+ }
981
+ try {
982
+ // Omit HEAD so the diff includes uncommitted (staged + unstaged) changes
983
+ const { stdout } = await execAsync(`git diff --shortstat ${diffTarget}`, {
984
+ cwd,
985
+ env: READ_ONLY_GIT_ENV,
986
+ });
987
+ const text = stdout.trim();
988
+ if (!text) {
989
+ return null;
990
+ }
991
+ let additions = 0;
992
+ let deletions = 0;
993
+ const addMatch = text.match(/(\d+)\s+insertion/);
994
+ if (addMatch) {
995
+ additions = Number.parseInt(addMatch[1], 10);
996
+ }
997
+ const delMatch = text.match(/(\d+)\s+deletion/);
998
+ if (delMatch) {
999
+ deletions = Number.parseInt(delMatch[1], 10);
1000
+ }
1001
+ if (additions === 0 && deletions === 0) {
1002
+ return null;
1003
+ }
1004
+ return { additions, deletions };
1005
+ }
1006
+ catch {
1007
+ return null;
1008
+ }
1009
+ }
1010
+ export async function getCheckoutDiff(cwd, compare, context) {
1011
+ await requireGitRepo(cwd);
1012
+ let refForDiff;
1013
+ if (compare.mode === "uncommitted") {
1014
+ refForDiff = "HEAD";
1015
+ }
1016
+ else {
1017
+ const configured = await getConfiguredBaseRefForCwd(cwd, context);
1018
+ const baseRef = configured.baseRef ?? compare.baseRef ?? (await resolveBaseRef(cwd));
1019
+ if (!baseRef) {
1020
+ return { diff: "" };
1021
+ }
1022
+ if (configured.isSeaworkOwnedWorktree && compare.baseRef && compare.baseRef !== baseRef) {
1023
+ throw new Error(`Base ref mismatch: expected ${baseRef}, got ${compare.baseRef}`);
1024
+ }
1025
+ const normalizedBaseRef = normalizeLocalBranchRefName(baseRef);
1026
+ const bestBaseRef = await resolveBestComparisonBaseRef(cwd, normalizedBaseRef);
1027
+ refForDiff = (await tryResolveMergeBase(cwd, bestBaseRef)) ?? bestBaseRef;
1028
+ }
1029
+ const ignoreWhitespace = compare.ignoreWhitespace === true;
1030
+ const changes = await listCheckoutFileChanges(cwd, refForDiff, ignoreWhitespace);
1031
+ changes.sort((a, b) => {
1032
+ if (a.path === b.path)
1033
+ return 0;
1034
+ return a.path < b.path ? -1 : 1;
1035
+ });
1036
+ const structured = [];
1037
+ let diffText = "";
1038
+ let diffBytes = 0;
1039
+ const appendDiff = (text) => {
1040
+ if (!text)
1041
+ return;
1042
+ if (diffBytes >= TOTAL_DIFF_MAX_BYTES)
1043
+ return;
1044
+ const buf = Buffer.from(text, "utf8");
1045
+ if (diffBytes + buf.length <= TOTAL_DIFF_MAX_BYTES) {
1046
+ diffText += text;
1047
+ diffBytes += buf.length;
1048
+ return;
1049
+ }
1050
+ const remaining = TOTAL_DIFF_MAX_BYTES - diffBytes;
1051
+ if (remaining > 0) {
1052
+ diffText += buf.subarray(0, remaining).toString("utf8");
1053
+ diffBytes = TOTAL_DIFF_MAX_BYTES;
1054
+ }
1055
+ };
1056
+ const trackedChanges = changes.filter((change) => !change.isUntracked);
1057
+ const untrackedChanges = changes.filter((change) => change.isUntracked === true);
1058
+ const trackedChangeByPath = new Map(trackedChanges.map((change) => [change.path, change]));
1059
+ const trackedNumstatByPath = trackedChanges.length > 0
1060
+ ? await getTrackedNumstatByPath(cwd, refForDiff, ignoreWhitespace)
1061
+ : new Map();
1062
+ const trackedDiffPaths = [];
1063
+ const trackedPlaceholderByPath = new Map();
1064
+ for (const change of trackedChanges) {
1065
+ const stat = trackedNumstatByPath.get(change.path) ?? null;
1066
+ if (stat?.isBinary) {
1067
+ trackedPlaceholderByPath.set(change.path, { status: "binary", stat });
1068
+ continue;
1069
+ }
1070
+ if (isTrackedDiffTooLarge(stat)) {
1071
+ trackedPlaceholderByPath.set(change.path, { status: "too_large", stat });
1072
+ continue;
1073
+ }
1074
+ trackedDiffPaths.push(change.path);
1075
+ }
1076
+ let trackedDiffText = "";
1077
+ let trackedDiffTruncated = false;
1078
+ if (trackedDiffPaths.length > 0) {
1079
+ const trackedDiffResult = await spawnLimitedText({
1080
+ cmd: "git",
1081
+ args: buildGitDiffArgs({
1082
+ ignoreWhitespace,
1083
+ extra: [refForDiff, "--", ...trackedDiffPaths],
1084
+ }),
1085
+ cwd,
1086
+ env: READ_ONLY_GIT_ENV,
1087
+ maxBytes: TOTAL_DIFF_MAX_BYTES,
1088
+ });
1089
+ trackedDiffText = trackedDiffResult.text;
1090
+ trackedDiffTruncated = trackedDiffResult.truncated;
1091
+ appendDiff(trackedDiffText);
1092
+ if (trackedDiffTruncated) {
1093
+ appendDiff("# tracked diff truncated\n");
1094
+ }
1095
+ }
1096
+ const appendTrackedPlaceholderComment = (change, status) => {
1097
+ if (status === "binary") {
1098
+ appendDiff(`# ${change.path}: binary diff omitted\n`);
1099
+ return;
1100
+ }
1101
+ appendDiff(`# ${change.path}: diff too large omitted\n`);
1102
+ };
1103
+ if (compare.includeStructured) {
1104
+ const parsedTrackedFiles = trackedDiffText.length > 0
1105
+ ? await parseAndHighlightDiff(trackedDiffText, cwd, {
1106
+ getOldFileContent: async (file) => {
1107
+ const change = trackedChangeByPath.get(file.path);
1108
+ if (!change || change.isNew) {
1109
+ return null;
1110
+ }
1111
+ const refPath = change.oldPath ?? change.path;
1112
+ return readGitFileContentAtRef(cwd, refForDiff, refPath);
1113
+ },
1114
+ })
1115
+ : [];
1116
+ const parsedTrackedByPath = new Map(parsedTrackedFiles.map((file) => [file.path, file]));
1117
+ for (const change of trackedChanges) {
1118
+ const placeholder = trackedPlaceholderByPath.get(change.path);
1119
+ if (placeholder) {
1120
+ structured.push(buildPlaceholderParsedDiffFile(change, {
1121
+ status: placeholder.status,
1122
+ stat: placeholder.stat,
1123
+ }));
1124
+ appendTrackedPlaceholderComment(change, placeholder.status);
1125
+ continue;
1126
+ }
1127
+ const stat = trackedNumstatByPath.get(change.path) ?? null;
1128
+ const parsedFile = parsedTrackedByPath.get(change.path);
1129
+ if (parsedFile) {
1130
+ structured.push({
1131
+ ...parsedFile,
1132
+ path: change.path,
1133
+ isNew: change.isNew,
1134
+ isDeleted: change.isDeleted,
1135
+ status: "ok",
1136
+ });
1137
+ continue;
1138
+ }
1139
+ // `git diff -w --name-status` can still report a modified path even when the
1140
+ // whitespace-filtered patch and numstat are both empty. Skip emitting a
1141
+ // structured placeholder in that case so whitespace-only edits truly disappear.
1142
+ if (ignoreWhitespace && !trackedDiffTruncated && stat === null) {
1143
+ continue;
1144
+ }
1145
+ structured.push({
1146
+ path: change.path,
1147
+ isNew: change.isNew,
1148
+ isDeleted: change.isDeleted,
1149
+ additions: stat?.additions ?? 0,
1150
+ deletions: stat?.deletions ?? 0,
1151
+ hunks: [],
1152
+ status: trackedDiffTruncated ? "too_large" : "ok",
1153
+ });
1154
+ }
1155
+ }
1156
+ else {
1157
+ for (const change of trackedChanges) {
1158
+ const placeholder = trackedPlaceholderByPath.get(change.path);
1159
+ if (placeholder) {
1160
+ appendTrackedPlaceholderComment(change, placeholder.status);
1161
+ }
1162
+ }
1163
+ }
1164
+ for (const change of untrackedChanges) {
1165
+ if (diffBytes >= TOTAL_DIFF_MAX_BYTES) {
1166
+ break;
1167
+ }
1168
+ const { text, truncated, stat } = await getUntrackedDiffText(cwd, change, ignoreWhitespace);
1169
+ if (!compare.includeStructured) {
1170
+ if (stat?.isBinary) {
1171
+ appendDiff(`# ${change.path}: binary diff omitted\n`);
1172
+ }
1173
+ else if (truncated) {
1174
+ appendDiff(`# ${change.path}: diff too large omitted\n`);
1175
+ }
1176
+ else {
1177
+ appendDiff(text);
1178
+ }
1179
+ continue;
1180
+ }
1181
+ if (stat?.isBinary) {
1182
+ structured.push(buildPlaceholderParsedDiffFile(change, { status: "binary", stat }));
1183
+ appendDiff(`# ${change.path}: binary diff omitted\n`);
1184
+ continue;
1185
+ }
1186
+ if (truncated) {
1187
+ structured.push(buildPlaceholderParsedDiffFile(change, { status: "too_large", stat }));
1188
+ appendDiff(`# ${change.path}: diff too large omitted\n`);
1189
+ continue;
1190
+ }
1191
+ appendDiff(text);
1192
+ const parsed = await parseAndHighlightDiff(text, cwd);
1193
+ const parsedFile = parsed[0] ??
1194
+ {
1195
+ path: change.path,
1196
+ isNew: change.isNew,
1197
+ isDeleted: change.isDeleted,
1198
+ additions: stat?.additions ?? 0,
1199
+ deletions: stat?.deletions ?? 0,
1200
+ hunks: [],
1201
+ };
1202
+ structured.push({
1203
+ ...parsedFile,
1204
+ path: change.path,
1205
+ isNew: change.isNew,
1206
+ isDeleted: change.isDeleted,
1207
+ status: "ok",
1208
+ });
1209
+ }
1210
+ if (compare.includeStructured) {
1211
+ return { diff: diffText, structured };
1212
+ }
1213
+ return { diff: diffText };
1214
+ }
1215
+ export async function commitChanges(cwd, options) {
1216
+ await requireGitRepo(cwd);
1217
+ if (options.addAll ?? true) {
1218
+ await execFileAsync("git", ["add", "-A"], { cwd });
1219
+ }
1220
+ await execFileAsync("git", ["-c", "commit.gpgsign=false", "commit", "-m", options.message], {
1221
+ cwd,
1222
+ });
1223
+ }
1224
+ export async function commitAll(cwd, message) {
1225
+ await commitChanges(cwd, { message, addAll: true });
1226
+ }
1227
+ export async function mergeToBase(cwd, options = {}, context) {
1228
+ await requireGitRepo(cwd);
1229
+ const currentBranch = await getCurrentBranch(cwd);
1230
+ const configured = await getConfiguredBaseRefForCwd(cwd, context);
1231
+ const baseRef = configured.baseRef ?? options.baseRef ?? (await resolveBaseRef(cwd));
1232
+ if (!baseRef) {
1233
+ throw new Error("Unable to determine base branch for merge");
1234
+ }
1235
+ if (configured.isSeaworkOwnedWorktree && options.baseRef && options.baseRef !== baseRef) {
1236
+ throw new Error(`Base ref mismatch: expected ${baseRef}, got ${options.baseRef}`);
1237
+ }
1238
+ if (!currentBranch) {
1239
+ throw new Error("Unable to determine current branch for merge");
1240
+ }
1241
+ let normalizedBaseRef = baseRef;
1242
+ normalizedBaseRef = normalizeLocalBranchRefName(normalizedBaseRef);
1243
+ if (normalizedBaseRef === currentBranch) {
1244
+ return;
1245
+ }
1246
+ const currentWorktreeRoot = (await getWorktreeRoot(cwd)) ?? cwd;
1247
+ const baseWorktree = await getWorktreePathForBranch(cwd, normalizedBaseRef);
1248
+ const operationCwd = baseWorktree ?? currentWorktreeRoot;
1249
+ const isSameCheckout = resolve(operationCwd) === resolve(currentWorktreeRoot);
1250
+ const originalBranch = await getCurrentBranch(operationCwd);
1251
+ const mode = options.mode ?? "merge";
1252
+ try {
1253
+ await execAsync(`git checkout ${normalizedBaseRef}`, { cwd: operationCwd });
1254
+ if (mode === "squash") {
1255
+ await execAsync(`git merge --squash ${currentBranch}`, { cwd: operationCwd });
1256
+ const message = options.commitMessage ?? `Squash merge ${currentBranch} into ${normalizedBaseRef}`;
1257
+ await execFileAsync("git", ["-c", "commit.gpgsign=false", "commit", "-m", message], {
1258
+ cwd: operationCwd,
1259
+ });
1260
+ }
1261
+ else {
1262
+ await execAsync(`git merge ${currentBranch}`, { cwd: operationCwd });
1263
+ }
1264
+ }
1265
+ catch (error) {
1266
+ const errorDetails = error instanceof Error
1267
+ ? `${error.message}\n${error.stderr ?? ""}\n${error.stdout ?? ""}`
1268
+ : String(error);
1269
+ try {
1270
+ const [unmergedOutput, lsFilesOutput, statusOutput] = await Promise.all([
1271
+ execAsync("git diff --name-only --diff-filter=U", { cwd: operationCwd }),
1272
+ execAsync("git ls-files -u", { cwd: operationCwd }),
1273
+ execAsync("git status --porcelain", { cwd: operationCwd }),
1274
+ ]);
1275
+ const statusConflicts = statusOutput.stdout
1276
+ .split("\n")
1277
+ .map((line) => line.trim())
1278
+ .filter(Boolean)
1279
+ .filter((line) => /^(UU|AA|DD|AU|UA|UD|DU)\s/.test(line))
1280
+ .map((line) => line.slice(3).trim());
1281
+ const conflicts = [
1282
+ ...unmergedOutput.stdout
1283
+ .split("\n")
1284
+ .map((line) => line.trim())
1285
+ .filter(Boolean),
1286
+ ...lsFilesOutput.stdout
1287
+ .split("\n")
1288
+ .map((line) => line.trim())
1289
+ .filter(Boolean)
1290
+ .map((line) => line.split("\t").pop()),
1291
+ ...statusConflicts,
1292
+ ].filter(Boolean);
1293
+ const conflictDetected = conflicts.length > 0 || /CONFLICT|Automatic merge failed/i.test(errorDetails);
1294
+ if (conflictDetected) {
1295
+ try {
1296
+ await execAsync("git merge --abort", { cwd: operationCwd });
1297
+ }
1298
+ catch {
1299
+ // ignore
1300
+ }
1301
+ throw new MergeConflictError({
1302
+ baseRef: normalizedBaseRef,
1303
+ currentBranch,
1304
+ conflictFiles: conflicts.length > 0 ? conflicts : [],
1305
+ });
1306
+ }
1307
+ }
1308
+ catch (innerError) {
1309
+ if (innerError instanceof MergeConflictError) {
1310
+ throw innerError;
1311
+ }
1312
+ // ignore detection failures
1313
+ }
1314
+ throw error;
1315
+ }
1316
+ finally {
1317
+ if (isSameCheckout && originalBranch && originalBranch !== normalizedBaseRef) {
1318
+ try {
1319
+ await execAsync(`git checkout ${originalBranch}`, { cwd: operationCwd });
1320
+ }
1321
+ catch {
1322
+ // ignore
1323
+ }
1324
+ }
1325
+ }
1326
+ }
1327
+ export async function mergeFromBase(cwd, options = {}, context) {
1328
+ await requireGitRepo(cwd);
1329
+ const currentBranch = await getCurrentBranch(cwd);
1330
+ if (!currentBranch || currentBranch === "HEAD") {
1331
+ throw new Error("Unable to determine current branch for merge");
1332
+ }
1333
+ const configured = await getConfiguredBaseRefForCwd(cwd, context);
1334
+ const baseRef = configured.baseRef ?? options.baseRef ?? (await resolveBaseRef(cwd));
1335
+ if (!baseRef) {
1336
+ throw new Error("Unable to determine base branch for merge");
1337
+ }
1338
+ if (configured.isSeaworkOwnedWorktree && options.baseRef && options.baseRef !== baseRef) {
1339
+ throw new Error(`Base ref mismatch: expected ${baseRef}, got ${options.baseRef}`);
1340
+ }
1341
+ const requireCleanTarget = options.requireCleanTarget ?? true;
1342
+ if (requireCleanTarget) {
1343
+ const { stdout } = await execAsync("git status --porcelain", {
1344
+ cwd,
1345
+ env: READ_ONLY_GIT_ENV,
1346
+ });
1347
+ if (stdout.trim().length > 0) {
1348
+ throw new Error("Working directory has uncommitted changes.");
1349
+ }
1350
+ }
1351
+ const normalizedBaseRef = normalizeLocalBranchRefName(baseRef);
1352
+ const bestBaseRef = await resolveBestComparisonBaseRef(cwd, normalizedBaseRef);
1353
+ if (bestBaseRef === currentBranch) {
1354
+ return;
1355
+ }
1356
+ try {
1357
+ await execAsync(`git merge ${bestBaseRef}`, { cwd });
1358
+ }
1359
+ catch (error) {
1360
+ const errorDetails = error instanceof Error
1361
+ ? `${error.message}\n${error.stderr ?? ""}\n${error.stdout ?? ""}`
1362
+ : String(error);
1363
+ try {
1364
+ const [unmergedOutput, lsFilesOutput, statusOutput] = await Promise.all([
1365
+ execAsync("git diff --name-only --diff-filter=U", { cwd }),
1366
+ execAsync("git ls-files -u", { cwd }),
1367
+ execAsync("git status --porcelain", { cwd }),
1368
+ ]);
1369
+ const statusConflicts = statusOutput.stdout
1370
+ .split("\n")
1371
+ .map((line) => line.trim())
1372
+ .filter(Boolean)
1373
+ .filter((line) => /^(UU|AA|DD|AU|UA|UD|DU)\s/.test(line))
1374
+ .map((line) => line.slice(3).trim());
1375
+ const conflicts = [
1376
+ ...unmergedOutput.stdout
1377
+ .split("\n")
1378
+ .map((line) => line.trim())
1379
+ .filter(Boolean),
1380
+ ...lsFilesOutput.stdout
1381
+ .split("\n")
1382
+ .map((line) => line.trim())
1383
+ .filter(Boolean)
1384
+ .map((line) => line.split("\t").pop()),
1385
+ ...statusConflicts,
1386
+ ].filter(Boolean);
1387
+ const conflictDetected = conflicts.length > 0 || /CONFLICT|Automatic merge failed/i.test(errorDetails);
1388
+ if (conflictDetected) {
1389
+ try {
1390
+ await execAsync("git merge --abort", { cwd });
1391
+ }
1392
+ catch {
1393
+ // ignore
1394
+ }
1395
+ throw new MergeFromBaseConflictError({
1396
+ baseRef: bestBaseRef,
1397
+ currentBranch,
1398
+ conflictFiles: conflicts.length > 0 ? conflicts : [],
1399
+ });
1400
+ }
1401
+ }
1402
+ catch (innerError) {
1403
+ if (innerError instanceof MergeFromBaseConflictError) {
1404
+ throw innerError;
1405
+ }
1406
+ // ignore detection failures
1407
+ }
1408
+ throw error;
1409
+ }
1410
+ }
1411
+ export async function pullCurrentBranch(cwd) {
1412
+ await requireGitRepo(cwd);
1413
+ const currentBranch = await getCurrentBranch(cwd);
1414
+ if (!currentBranch || currentBranch === "HEAD") {
1415
+ throw new Error("Unable to determine current branch for pull");
1416
+ }
1417
+ const hasRemote = await hasOriginRemote(cwd);
1418
+ if (!hasRemote) {
1419
+ throw new Error("Remote 'origin' is not configured.");
1420
+ }
1421
+ try {
1422
+ await execAsync("git pull", { cwd });
1423
+ }
1424
+ catch (error) {
1425
+ await abortGitPullConflictState(cwd);
1426
+ throw error;
1427
+ }
1428
+ }
1429
+ export async function pushCurrentBranch(cwd) {
1430
+ await requireGitRepo(cwd);
1431
+ const currentBranch = await getCurrentBranch(cwd);
1432
+ if (!currentBranch || currentBranch === "HEAD") {
1433
+ throw new Error("Unable to determine current branch for push");
1434
+ }
1435
+ const hasRemote = await hasOriginRemote(cwd);
1436
+ if (!hasRemote) {
1437
+ throw new Error("Remote 'origin' is not configured.");
1438
+ }
1439
+ await execAsync(`git push -u origin ${currentBranch}`, { cwd });
1440
+ }
1441
+ export async function resolveGhPath() {
1442
+ if (cachedGhPath === undefined) {
1443
+ cachedGhPath = await findExecutable("gh");
1444
+ }
1445
+ if (cachedGhPath === null) {
1446
+ throw new Error("GitHub CLI (gh) is not installed or not in PATH");
1447
+ }
1448
+ return cachedGhPath;
1449
+ }
1450
+ function getCommandErrorText(error) {
1451
+ if (!(error instanceof Error)) {
1452
+ return String(error);
1453
+ }
1454
+ const stderr = typeof error?.stderr === "string" ? error.stderr : "";
1455
+ const stdout = typeof error?.stdout === "string" ? error.stdout : "";
1456
+ return `${error.message}\n${stderr}\n${stdout}`.toLowerCase();
1457
+ }
1458
+ function isGhAuthError(error) {
1459
+ const text = getCommandErrorText(error);
1460
+ return (text.includes("gh auth login") ||
1461
+ text.includes("not logged into any github hosts") ||
1462
+ text.includes("authentication failed") ||
1463
+ text.includes("authentication required") ||
1464
+ text.includes("bad credentials") ||
1465
+ text.includes("http 401"));
1466
+ }
1467
+ async function resolveGitHubRepo(cwd) {
1468
+ try {
1469
+ const { stdout } = await execAsync("git config --get remote.origin.url", {
1470
+ cwd,
1471
+ env: READ_ONLY_GIT_ENV,
1472
+ });
1473
+ const url = stdout.trim();
1474
+ if (!url) {
1475
+ return null;
1476
+ }
1477
+ let cleaned = url;
1478
+ if (cleaned.startsWith("git@github.com:")) {
1479
+ cleaned = cleaned.slice("git@github.com:".length);
1480
+ }
1481
+ else if (cleaned.startsWith("https://github.com/")) {
1482
+ cleaned = cleaned.slice("https://github.com/".length);
1483
+ }
1484
+ else if (cleaned.startsWith("http://github.com/")) {
1485
+ cleaned = cleaned.slice("http://github.com/".length);
1486
+ }
1487
+ else {
1488
+ const marker = "github.com/";
1489
+ const index = cleaned.indexOf(marker);
1490
+ if (index !== -1) {
1491
+ cleaned = cleaned.slice(index + marker.length);
1492
+ }
1493
+ else {
1494
+ return null;
1495
+ }
1496
+ }
1497
+ if (cleaned.endsWith(".git")) {
1498
+ cleaned = cleaned.slice(0, -".git".length);
1499
+ }
1500
+ if (!cleaned.includes("/")) {
1501
+ return null;
1502
+ }
1503
+ return cleaned;
1504
+ }
1505
+ catch {
1506
+ // ignore
1507
+ }
1508
+ return null;
1509
+ }
1510
+ export async function createPullRequest(cwd, options) {
1511
+ await requireGitRepo(cwd);
1512
+ const ghPath = await resolveGhPath();
1513
+ const repo = await resolveGitHubRepo(cwd);
1514
+ if (!repo) {
1515
+ throw new Error("Unable to determine GitHub repo from git remote");
1516
+ }
1517
+ const head = options.head ?? (await getCurrentBranch(cwd));
1518
+ const configured = await getConfiguredBaseRefForCwd(cwd);
1519
+ const base = configured.baseRef ?? options.base ?? (await resolveBaseRef(cwd));
1520
+ if (!head) {
1521
+ throw new Error("Unable to determine head branch for PR");
1522
+ }
1523
+ if (!base) {
1524
+ throw new Error("Unable to determine base branch for PR");
1525
+ }
1526
+ const normalizedBase = normalizeLocalBranchRefName(base);
1527
+ if (configured.isSeaworkOwnedWorktree && options.base && options.base !== base) {
1528
+ throw new Error(`Base ref mismatch: expected ${base}, got ${options.base}`);
1529
+ }
1530
+ await execAsync(`git push -u origin ${head}`, { cwd });
1531
+ const ghEnv = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
1532
+ const args = ["api", "-X", "POST", `repos/${repo}/pulls`, "-f", `title=${options.title}`];
1533
+ args.push("-f", `head=${head}`);
1534
+ args.push("-f", `base=${normalizedBase}`);
1535
+ if (options.body) {
1536
+ args.push("-f", `body=${options.body}`);
1537
+ }
1538
+ const { stdout } = await execFileAsync(ghPath, args, { cwd, env: ghEnv });
1539
+ const parsed = JSON.parse(stdout.trim());
1540
+ if (!parsed?.url || !parsed?.number) {
1541
+ throw new Error("GitHub CLI did not return PR url/number");
1542
+ }
1543
+ return { url: parsed.url, number: parsed.number };
1544
+ }
1545
+ export async function getPullRequestStatus(cwd) {
1546
+ const cacheKey = getPullRequestStatusCacheKey(cwd);
1547
+ const cached = pullRequestStatusCache.get(cacheKey);
1548
+ if (cached) {
1549
+ return cached;
1550
+ }
1551
+ const existing = pullRequestStatusInFlight.get(cacheKey);
1552
+ if (existing) {
1553
+ return existing;
1554
+ }
1555
+ const lookup = getPullRequestStatusUncached(cwd)
1556
+ .then((status) => {
1557
+ pullRequestStatusCache.set(cacheKey, status);
1558
+ return status;
1559
+ })
1560
+ .finally(() => {
1561
+ pullRequestStatusInFlight.delete(cacheKey);
1562
+ });
1563
+ pullRequestStatusInFlight.set(cacheKey, lookup);
1564
+ return lookup;
1565
+ }
1566
+ async function getPullRequestStatusUncached(cwd) {
1567
+ await requireGitRepo(cwd);
1568
+ const head = await getCurrentBranch(cwd);
1569
+ if (!head) {
1570
+ return {
1571
+ status: null,
1572
+ githubFeaturesEnabled: false,
1573
+ };
1574
+ }
1575
+ let ghPath;
1576
+ try {
1577
+ ghPath = await resolveGhPath();
1578
+ }
1579
+ catch {
1580
+ return {
1581
+ status: null,
1582
+ githubFeaturesEnabled: false,
1583
+ };
1584
+ }
1585
+ try {
1586
+ const { stdout } = await execFileAsync(ghPath, ["pr", "view", "--json", "url,title,state,baseRefName,headRefName,mergedAt"], { cwd, env: { ...process.env, GIT_TERMINAL_PROMPT: "0" } });
1587
+ const pr = JSON.parse(stdout.trim());
1588
+ if (!pr || typeof pr !== "object" || !pr.url || !pr.title) {
1589
+ return { status: null, githubFeaturesEnabled: true };
1590
+ }
1591
+ const mergedAt = typeof pr.mergedAt === "string" && pr.mergedAt.trim().length > 0 ? pr.mergedAt : null;
1592
+ const state = mergedAt !== null
1593
+ ? "merged"
1594
+ : typeof pr.state === "string" && pr.state.trim().length > 0
1595
+ ? pr.state.toLowerCase()
1596
+ : "";
1597
+ return {
1598
+ status: {
1599
+ url: pr.url,
1600
+ title: pr.title,
1601
+ state,
1602
+ baseRefName: pr.baseRefName ?? "",
1603
+ headRefName: pr.headRefName ?? head,
1604
+ isMerged: mergedAt !== null,
1605
+ },
1606
+ githubFeaturesEnabled: true,
1607
+ };
1608
+ }
1609
+ catch (error) {
1610
+ if (isGhAuthError(error)) {
1611
+ return { status: null, githubFeaturesEnabled: false };
1612
+ }
1613
+ // gh pr view exits non-zero when no PR exists for the branch
1614
+ const message = error instanceof Error ? error.message : String(error);
1615
+ if (message.includes("no pull requests found") || message.includes("Could not resolve")) {
1616
+ return { status: null, githubFeaturesEnabled: true };
1617
+ }
1618
+ throw error;
1619
+ }
1620
+ }
1621
+ //# sourceMappingURL=checkout-git.js.map