@otto-code/server 0.5.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 (734) hide show
  1. package/.env.example +31 -0
  2. package/README.md +111 -0
  3. package/dist/scripts/dev-runner.js +37 -0
  4. package/dist/scripts/mcp-stdio-socket-bridge-cli.mjs +62 -0
  5. package/dist/scripts/supervisor-entrypoint.js +141 -0
  6. package/dist/scripts/supervisor-log-config.js +31 -0
  7. package/dist/scripts/supervisor.js +252 -0
  8. package/dist/server/executable-resolution/executable-resolution.d.ts +10 -0
  9. package/dist/server/executable-resolution/executable-resolution.js +118 -0
  10. package/dist/server/executable-resolution/windows.d.ts +18 -0
  11. package/dist/server/executable-resolution/windows.js +65 -0
  12. package/dist/server/server/agent/activity-curator.d.ts +28 -0
  13. package/dist/server/server/agent/activity-curator.js +227 -0
  14. package/dist/server/server/agent/agent-archive.d.ts +11 -0
  15. package/dist/server/server/agent/agent-archive.js +16 -0
  16. package/dist/server/server/agent/agent-loading.d.ts +14 -0
  17. package/dist/server/server/agent/agent-loading.js +54 -0
  18. package/dist/server/server/agent/agent-manager.d.ts +470 -0
  19. package/dist/server/server/agent/agent-manager.js +3049 -0
  20. package/dist/server/server/agent/agent-personalities.d.ts +59 -0
  21. package/dist/server/server/agent/agent-personalities.js +103 -0
  22. package/dist/server/server/agent/agent-projections.d.ts +35 -0
  23. package/dist/server/server/agent/agent-projections.js +488 -0
  24. package/dist/server/server/agent/agent-prompt.d.ts +76 -0
  25. package/dist/server/server/agent/agent-prompt.js +230 -0
  26. package/dist/server/server/agent/agent-response-loop.d.ts +72 -0
  27. package/dist/server/server/agent/agent-response-loop.js +333 -0
  28. package/dist/server/server/agent/agent-sdk-types.d.ts +736 -0
  29. package/dist/server/server/agent/agent-sdk-types.js +22 -0
  30. package/dist/server/server/agent/agent-storage.d.ts +147 -0
  31. package/dist/server/server/agent/agent-storage.js +326 -0
  32. package/dist/server/server/agent/agent-stream-coalescer.d.ts +41 -0
  33. package/dist/server/server/agent/agent-stream-coalescer.js +166 -0
  34. package/dist/server/server/agent/agent-timeline-store-types.d.ts +50 -0
  35. package/dist/server/server/agent/agent-timeline-store-types.js +2 -0
  36. package/dist/server/server/agent/agent-timeline-store.d.ts +27 -0
  37. package/dist/server/server/agent/agent-timeline-store.js +230 -0
  38. package/dist/server/server/agent/audio-utils.d.ts +3 -0
  39. package/dist/server/server/agent/audio-utils.js +19 -0
  40. package/dist/server/server/agent/create-agent/create.d.ts +91 -0
  41. package/dist/server/server/agent/create-agent/create.js +370 -0
  42. package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts +54 -0
  43. package/dist/server/server/agent/create-agent-lifecycle-dispatch.js +152 -0
  44. package/dist/server/server/agent/create-agent-mode.d.ts +13 -0
  45. package/dist/server/server/agent/create-agent-mode.js +62 -0
  46. package/dist/server/server/agent/create-agent-title.d.ts +10 -0
  47. package/dist/server/server/agent/create-agent-title.js +34 -0
  48. package/dist/server/server/agent/dictation-debug.d.ts +13 -0
  49. package/dist/server/server/agent/dictation-debug.js +50 -0
  50. package/dist/server/server/agent/effort-levels.d.ts +2 -0
  51. package/dist/server/server/agent/effort-levels.js +7 -0
  52. package/dist/server/server/agent/foreground-run-state.d.ts +50 -0
  53. package/dist/server/server/agent/foreground-run-state.js +160 -0
  54. package/dist/server/server/agent/import-sessions.d.ts +47 -0
  55. package/dist/server/server/agent/import-sessions.js +145 -0
  56. package/dist/server/server/agent/lifecycle-command.d.ts +73 -0
  57. package/dist/server/server/agent/lifecycle-command.js +92 -0
  58. package/dist/server/server/agent/mcp-server.d.ts +5 -0
  59. package/dist/server/server/agent/mcp-server.js +66 -0
  60. package/dist/server/server/agent/mcp-shared.d.ts +192 -0
  61. package/dist/server/server/agent/mcp-shared.js +201 -0
  62. package/dist/server/server/agent/pcm16-resampler.d.ts +14 -0
  63. package/dist/server/server/agent/pcm16-resampler.js +63 -0
  64. package/dist/server/server/agent/permission-response.d.ts +15 -0
  65. package/dist/server/server/agent/permission-response.js +14 -0
  66. package/dist/server/server/agent/personality-stats-store.d.ts +23 -0
  67. package/dist/server/server/agent/personality-stats-store.js +65 -0
  68. package/dist/server/server/agent/prompt-attachments.d.ts +7 -0
  69. package/dist/server/server/agent/prompt-attachments.js +117 -0
  70. package/dist/server/server/agent/provider-history-timestamps.d.ts +2 -0
  71. package/dist/server/server/agent/provider-history-timestamps.js +16 -0
  72. package/dist/server/server/agent/provider-launch-config.d.ts +43 -0
  73. package/dist/server/server/agent/provider-launch-config.js +167 -0
  74. package/dist/server/server/agent/provider-notices.d.ts +3 -0
  75. package/dist/server/server/agent/provider-notices.js +5 -0
  76. package/dist/server/server/agent/provider-registry.d.ts +41 -0
  77. package/dist/server/server/agent/provider-registry.js +532 -0
  78. package/dist/server/server/agent/provider-session-import.d.ts +10 -0
  79. package/dist/server/server/agent/provider-session-import.js +49 -0
  80. package/dist/server/server/agent/provider-snapshot-manager.d.ts +142 -0
  81. package/dist/server/server/agent/provider-snapshot-manager.js +690 -0
  82. package/dist/server/server/agent/providers/acp-agent.d.ts +353 -0
  83. package/dist/server/server/agent/providers/acp-agent.js +2439 -0
  84. package/dist/server/server/agent/providers/claude/agent.d.ts +66 -0
  85. package/dist/server/server/agent/providers/claude/agent.js +4535 -0
  86. package/dist/server/server/agent/providers/claude/feature-definitions.d.ts +8 -0
  87. package/dist/server/server/agent/providers/claude/feature-definitions.js +24 -0
  88. package/dist/server/server/agent/providers/claude/model-manifest.d.ts +90 -0
  89. package/dist/server/server/agent/providers/claude/model-manifest.js +205 -0
  90. package/dist/server/server/agent/providers/claude/models.d.ts +11 -0
  91. package/dist/server/server/agent/providers/claude/models.js +97 -0
  92. package/dist/server/server/agent/providers/claude/partial-json.d.ts +5 -0
  93. package/dist/server/server/agent/providers/claude/partial-json.js +306 -0
  94. package/dist/server/server/agent/providers/claude/project-dir.d.ts +6 -0
  95. package/dist/server/server/agent/providers/claude/project-dir.js +57 -0
  96. package/dist/server/server/agent/providers/claude/query.d.ts +17 -0
  97. package/dist/server/server/agent/providers/claude/query.js +86 -0
  98. package/dist/server/server/agent/providers/claude/rewind.d.ts +30 -0
  99. package/dist/server/server/agent/providers/claude/rewind.js +30 -0
  100. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts +22 -0
  101. package/dist/server/server/agent/providers/claude/sidechain-tracker.js +232 -0
  102. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +35 -0
  103. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +272 -0
  104. package/dist/server/server/agent/providers/claude/test-rewind-claude-sdk.d.ts +24 -0
  105. package/dist/server/server/agent/providers/claude/test-rewind-claude-sdk.js +23 -0
  106. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts +3 -0
  107. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +130 -0
  108. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts +16 -0
  109. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +129 -0
  110. package/dist/server/server/agent/providers/codex/app-server-transport.d.ts +90 -0
  111. package/dist/server/server/agent/providers/codex/app-server-transport.js +262 -0
  112. package/dist/server/server/agent/providers/codex/rewind.d.ts +21 -0
  113. package/dist/server/server/agent/providers/codex/rewind.js +46 -0
  114. package/dist/server/server/agent/providers/codex/test-utils/fake-app-server.d.ts +36 -0
  115. package/dist/server/server/agent/providers/codex/test-utils/fake-app-server.js +217 -0
  116. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts +12 -0
  117. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.js +104 -0
  118. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts +24 -0
  119. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +830 -0
  120. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +308 -0
  121. package/dist/server/server/agent/providers/codex-app-server-agent.js +4515 -0
  122. package/dist/server/server/agent/providers/codex-feature-definitions.d.ts +11 -0
  123. package/dist/server/server/agent/providers/codex-feature-definitions.js +45 -0
  124. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts +26 -0
  125. package/dist/server/server/agent/providers/copilot-acp-agent.js +188 -0
  126. package/dist/server/server/agent/providers/cursor-acp-agent.d.ts +15 -0
  127. package/dist/server/server/agent/providers/cursor-acp-agent.js +18 -0
  128. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +36 -0
  129. package/dist/server/server/agent/providers/diagnostic-utils.js +355 -0
  130. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +42 -0
  131. package/dist/server/server/agent/providers/generic-acp-agent.js +160 -0
  132. package/dist/server/server/agent/providers/kiro-acp-agent.d.ts +17 -0
  133. package/dist/server/server/agent/providers/kiro-acp-agent.js +78 -0
  134. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts +85 -0
  135. package/dist/server/server/agent/providers/mock-load-test-agent.js +1010 -0
  136. package/dist/server/server/agent/providers/mock-slow-provider.d.ts +14 -0
  137. package/dist/server/server/agent/providers/mock-slow-provider.js +39 -0
  138. package/dist/server/server/agent/providers/openai-compat-agent.d.ts +422 -0
  139. package/dist/server/server/agent/providers/openai-compat-agent.js +2536 -0
  140. package/dist/server/server/agent/providers/openai-compat-feature-definitions.d.ts +40 -0
  141. package/dist/server/server/agent/providers/openai-compat-feature-definitions.js +82 -0
  142. package/dist/server/server/agent/providers/openai-compat-mcp.d.ts +87 -0
  143. package/dist/server/server/agent/providers/openai-compat-mcp.js +353 -0
  144. package/dist/server/server/agent/providers/openai-compat-otto-tool-permissions.d.ts +29 -0
  145. package/dist/server/server/agent/providers/openai-compat-otto-tool-permissions.js +96 -0
  146. package/dist/server/server/agent/providers/openai-compat-tools.d.ts +69 -0
  147. package/dist/server/server/agent/providers/openai-compat-tools.js +1224 -0
  148. package/dist/server/server/agent/providers/opencode/paths.d.ts +2 -0
  149. package/dist/server/server/agent/providers/opencode/paths.js +7 -0
  150. package/dist/server/server/agent/providers/opencode/rewind.d.ts +18 -0
  151. package/dist/server/server/agent/providers/opencode/rewind.js +14 -0
  152. package/dist/server/server/agent/providers/opencode/server-manager.d.ts +91 -0
  153. package/dist/server/server/agent/providers/opencode/server-manager.js +425 -0
  154. package/dist/server/server/agent/providers/opencode/test-server-manager.d.ts +25 -0
  155. package/dist/server/server/agent/providers/opencode/test-server-manager.js +39 -0
  156. package/dist/server/server/agent/providers/opencode/test-utils/test-opencode-harness.d.ts +92 -0
  157. package/dist/server/server/agent/providers/opencode/test-utils/test-opencode-harness.js +260 -0
  158. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.d.ts +3 -0
  159. package/dist/server/server/agent/providers/opencode/tool-call-detail-parser.js +256 -0
  160. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts +13 -0
  161. package/dist/server/server/agent/providers/opencode/tool-call-mapper.js +53 -0
  162. package/dist/server/server/agent/providers/opencode-agent.d.ts +286 -0
  163. package/dist/server/server/agent/providers/opencode-agent.js +2830 -0
  164. package/dist/server/server/agent/providers/pi/agent.d.ts +132 -0
  165. package/dist/server/server/agent/providers/pi/agent.js +1649 -0
  166. package/dist/server/server/agent/providers/pi/cli-runtime.d.ts +21 -0
  167. package/dist/server/server/agent/providers/pi/cli-runtime.js +261 -0
  168. package/dist/server/server/agent/providers/pi/history-mapper.d.ts +9 -0
  169. package/dist/server/server/agent/providers/pi/history-mapper.js +140 -0
  170. package/dist/server/server/agent/providers/pi/rewind.d.ts +8 -0
  171. package/dist/server/server/agent/providers/pi/rewind.js +8 -0
  172. package/dist/server/server/agent/providers/pi/rpc-types.d.ts +208 -0
  173. package/dist/server/server/agent/providers/pi/rpc-types.js +2 -0
  174. package/dist/server/server/agent/providers/pi/runtime.d.ts +57 -0
  175. package/dist/server/server/agent/providers/pi/runtime.js +56 -0
  176. package/dist/server/server/agent/providers/pi/session-descriptor.d.ts +16 -0
  177. package/dist/server/server/agent/providers/pi/session-descriptor.js +346 -0
  178. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.d.ts +83 -0
  179. package/dist/server/server/agent/providers/pi/test-utils/fake-pi.js +184 -0
  180. package/dist/server/server/agent/providers/pi/tool-call-mapper.d.ts +112 -0
  181. package/dist/server/server/agent/providers/pi/tool-call-mapper.js +284 -0
  182. package/dist/server/server/agent/providers/provider-image-output.d.ts +25 -0
  183. package/dist/server/server/agent/providers/provider-image-output.js +111 -0
  184. package/dist/server/server/agent/providers/provider-runner.d.ts +27 -0
  185. package/dist/server/server/agent/providers/provider-runner.js +81 -0
  186. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.d.ts +3 -0
  187. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js +60 -0
  188. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +884 -0
  189. package/dist/server/server/agent/providers/tool-call-detail-primitives.js +778 -0
  190. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts +25 -0
  191. package/dist/server/server/agent/providers/tool-call-mapper-utils.js +208 -0
  192. package/dist/server/server/agent/providers/trae-acp-agent.d.ts +15 -0
  193. package/dist/server/server/agent/providers/trae-acp-agent.js +18 -0
  194. package/dist/server/server/agent/recordings-debug.d.ts +3 -0
  195. package/dist/server/server/agent/recordings-debug.js +19 -0
  196. package/dist/server/server/agent/rewind/rewind.d.ts +10 -0
  197. package/dist/server/server/agent/rewind/rewind.js +29 -0
  198. package/dist/server/server/agent/rewind/test-rewind-session.d.ts +48 -0
  199. package/dist/server/server/agent/rewind/test-rewind-session.js +88 -0
  200. package/dist/server/server/agent/runtime-mcp-config.d.ts +14 -0
  201. package/dist/server/server/agent/runtime-mcp-config.js +53 -0
  202. package/dist/server/server/agent/structured-generation-providers.d.ts +29 -0
  203. package/dist/server/server/agent/structured-generation-providers.js +236 -0
  204. package/dist/server/server/agent/stt-debug.d.ts +10 -0
  205. package/dist/server/server/agent/stt-debug.js +33 -0
  206. package/dist/server/server/agent/stt-manager.d.ts +38 -0
  207. package/dist/server/server/agent/stt-manager.js +246 -0
  208. package/dist/server/server/agent/system-prompt.d.ts +2 -0
  209. package/dist/server/server/agent/system-prompt.js +8 -0
  210. package/dist/server/server/agent/timeline-append.d.ts +10 -0
  211. package/dist/server/server/agent/timeline-append.js +27 -0
  212. package/dist/server/server/agent/timeline-projection.d.ts +71 -0
  213. package/dist/server/server/agent/timeline-projection.js +373 -0
  214. package/dist/server/server/agent/tools/otto-tools.d.ts +80 -0
  215. package/dist/server/server/agent/tools/otto-tools.js +2912 -0
  216. package/dist/server/server/agent/tools/types.d.ts +36 -0
  217. package/dist/server/server/agent/tools/types.js +2 -0
  218. package/dist/server/server/agent/tts-debug.d.ts +8 -0
  219. package/dist/server/server/agent/tts-debug.js +24 -0
  220. package/dist/server/server/agent/tts-manager.d.ts +41 -0
  221. package/dist/server/server/agent/tts-manager.js +375 -0
  222. package/dist/server/server/agent-attention-policy.d.ts +29 -0
  223. package/dist/server/server/agent-attention-policy.js +36 -0
  224. package/dist/server/server/artifact/artifact-prompt.d.ts +2 -0
  225. package/dist/server/server/artifact/artifact-prompt.js +15 -0
  226. package/dist/server/server/artifact/artifact-service.d.ts +91 -0
  227. package/dist/server/server/artifact/artifact-service.js +419 -0
  228. package/dist/server/server/artifact/artifact-store.d.ts +24 -0
  229. package/dist/server/server/artifact/artifact-store.js +168 -0
  230. package/dist/server/server/artifact/artifact-watcher.d.ts +34 -0
  231. package/dist/server/server/artifact/artifact-watcher.js +146 -0
  232. package/dist/server/server/artifact/html-validator.d.ts +26 -0
  233. package/dist/server/server/artifact/html-validator.js +92 -0
  234. package/dist/server/server/atomic-file.d.ts +5 -0
  235. package/dist/server/server/atomic-file.js +19 -0
  236. package/dist/server/server/auth.d.ts +38 -0
  237. package/dist/server/server/auth.js +143 -0
  238. package/dist/server/server/auto-archive-on-merge/archive-if-safe.d.ts +40 -0
  239. package/dist/server/server/auto-archive-on-merge/archive-if-safe.js +92 -0
  240. package/dist/server/server/auto-archive-on-merge/index.d.ts +8 -0
  241. package/dist/server/server/auto-archive-on-merge/index.js +15 -0
  242. package/dist/server/server/bootstrap.d.ts +127 -0
  243. package/dist/server/server/bootstrap.js +1331 -0
  244. package/dist/server/server/browser-tools/broker.d.ts +45 -0
  245. package/dist/server/server/browser-tools/broker.js +390 -0
  246. package/dist/server/server/browser-tools/errors.d.ts +22 -0
  247. package/dist/server/server/browser-tools/errors.js +27 -0
  248. package/dist/server/server/browser-tools/policy.d.ts +10 -0
  249. package/dist/server/server/browser-tools/policy.js +16 -0
  250. package/dist/server/server/browser-tools/tools.d.ts +24 -0
  251. package/dist/server/server/browser-tools/tools.js +967 -0
  252. package/dist/server/server/chat/chat-mentions.d.ts +47 -0
  253. package/dist/server/server/chat/chat-mentions.js +113 -0
  254. package/dist/server/server/chat/chat-service.d.ts +78 -0
  255. package/dist/server/server/chat/chat-service.js +337 -0
  256. package/dist/server/server/checkout/status-projection.d.ts +19 -0
  257. package/dist/server/server/checkout/status-projection.js +117 -0
  258. package/dist/server/server/checkout-diff-manager.d.ts +41 -0
  259. package/dist/server/server/checkout-diff-manager.js +189 -0
  260. package/dist/server/server/checkout-git-utils.d.ts +11 -0
  261. package/dist/server/server/checkout-git-utils.js +34 -0
  262. package/dist/server/server/client-message-id.d.ts +3 -0
  263. package/dist/server/server/client-message-id.js +12 -0
  264. package/dist/server/server/config.d.ts +22 -0
  265. package/dist/server/server/config.js +330 -0
  266. package/dist/server/server/connection-offer.d.ts +20 -0
  267. package/dist/server/server/connection-offer.js +59 -0
  268. package/dist/server/server/daemon-config-store.d.ts +44 -0
  269. package/dist/server/server/daemon-config-store.js +530 -0
  270. package/dist/server/server/daemon-keypair.d.ts +8 -0
  271. package/dist/server/server/daemon-keypair.js +42 -0
  272. package/dist/server/server/daemon-version.d.ts +5 -0
  273. package/dist/server/server/daemon-version.js +22 -0
  274. package/dist/server/server/daemon-worker.d.ts +2 -0
  275. package/dist/server/server/daemon-worker.js +251 -0
  276. package/dist/server/server/dictation/dictation-stream-manager.d.ts +87 -0
  277. package/dist/server/server/dictation/dictation-stream-manager.js +572 -0
  278. package/dist/server/server/exports.d.ts +24 -0
  279. package/dist/server/server/exports.js +24 -0
  280. package/dist/server/server/file-download/token-store.d.ts +24 -0
  281. package/dist/server/server/file-download/token-store.js +40 -0
  282. package/dist/server/server/file-explorer/code-index.d.ts +28 -0
  283. package/dist/server/server/file-explorer/code-index.js +127 -0
  284. package/dist/server/server/file-explorer/file-search.d.ts +72 -0
  285. package/dist/server/server/file-explorer/file-search.js +297 -0
  286. package/dist/server/server/file-explorer/file-watcher.d.ts +40 -0
  287. package/dist/server/server/file-explorer/file-watcher.js +0 -0
  288. package/dist/server/server/file-explorer/gitignore.d.ts +39 -0
  289. package/dist/server/server/file-explorer/gitignore.js +191 -0
  290. package/dist/server/server/file-explorer/service.d.ts +103 -0
  291. package/dist/server/server/file-explorer/service.js +420 -0
  292. package/dist/server/server/file-upload/index.d.ts +27 -0
  293. package/dist/server/server/file-upload/index.js +158 -0
  294. package/dist/server/server/hostnames.d.ts +13 -0
  295. package/dist/server/server/hostnames.js +94 -0
  296. package/dist/server/server/json-utils.d.ts +11 -0
  297. package/dist/server/server/json-utils.js +45 -0
  298. package/dist/server/server/lifecycle-reasons.d.ts +4 -0
  299. package/dist/server/server/lifecycle-reasons.js +6 -0
  300. package/dist/server/server/logger.d.ts +29 -0
  301. package/dist/server/server/logger.js +125 -0
  302. package/dist/server/server/loop-service.d.ts +234 -0
  303. package/dist/server/server/loop-service.js +804 -0
  304. package/dist/server/server/managed-processes/managed-processes.d.ts +76 -0
  305. package/dist/server/server/managed-processes/managed-processes.js +326 -0
  306. package/dist/server/server/messages.d.ts +9 -0
  307. package/dist/server/server/messages.js +29 -0
  308. package/dist/server/server/migrations/backfill-workspace-id.migration.d.ts +9 -0
  309. package/dist/server/server/migrations/backfill-workspace-id.migration.js +64 -0
  310. package/dist/server/server/otto-env.d.ts +13 -0
  311. package/dist/server/server/otto-env.js +53 -0
  312. package/dist/server/server/otto-home.d.ts +2 -0
  313. package/dist/server/server/otto-home.js +19 -0
  314. package/dist/server/server/otto-worktree-service.d.ts +52 -0
  315. package/dist/server/server/otto-worktree-service.js +294 -0
  316. package/dist/server/server/package-version.d.ts +19 -0
  317. package/dist/server/server/package-version.js +60 -0
  318. package/dist/server/server/pagination/cursor.d.ts +16 -0
  319. package/dist/server/server/pagination/cursor.js +62 -0
  320. package/dist/server/server/pagination/sortable-pager.d.ts +24 -0
  321. package/dist/server/server/pagination/sortable-pager.js +68 -0
  322. package/dist/server/server/pairing-offer.d.ts +18 -0
  323. package/dist/server/server/pairing-offer.js +47 -0
  324. package/dist/server/server/pairing-qr.d.ts +7 -0
  325. package/dist/server/server/pairing-qr.js +45 -0
  326. package/dist/server/server/path-utils.d.ts +5 -0
  327. package/dist/server/server/path-utils.js +34 -0
  328. package/dist/server/server/persisted-config.d.ts +417 -0
  329. package/dist/server/server/persisted-config.js +471 -0
  330. package/dist/server/server/persistence-hooks.d.ts +31 -0
  331. package/dist/server/server/persistence-hooks.js +93 -0
  332. package/dist/server/server/pid-lock.d.ts +32 -0
  333. package/dist/server/server/pid-lock.js +170 -0
  334. package/dist/server/server/preview/dev-server-manager.d.ts +108 -0
  335. package/dist/server/server/preview/dev-server-manager.js +426 -0
  336. package/dist/server/server/preview/launch-config.d.ts +37 -0
  337. package/dist/server/server/preview/launch-config.js +63 -0
  338. package/dist/server/server/preview/preview-tools.d.ts +30 -0
  339. package/dist/server/server/preview/preview-tools.js +249 -0
  340. package/dist/server/server/private-files.d.ts +6 -0
  341. package/dist/server/server/private-files.js +37 -0
  342. package/dist/server/server/process-diagnostics.d.ts +17 -0
  343. package/dist/server/server/process-diagnostics.js +22 -0
  344. package/dist/server/server/push/notifications.d.ts +9 -0
  345. package/dist/server/server/push/notifications.js +15 -0
  346. package/dist/server/server/push/push-service.d.ts +20 -0
  347. package/dist/server/server/push/push-service.js +66 -0
  348. package/dist/server/server/push/token-store.d.ts +18 -0
  349. package/dist/server/server/push/token-store.js +68 -0
  350. package/dist/server/server/relay-transport.d.ts +31 -0
  351. package/dist/server/server/relay-transport.js +514 -0
  352. package/dist/server/server/resolve-workspace-id-for-path.d.ts +3 -0
  353. package/dist/server/server/resolve-workspace-id-for-path.js +41 -0
  354. package/dist/server/server/resolve-worktree-creation-intent.d.ts +32 -0
  355. package/dist/server/server/resolve-worktree-creation-intent.js +121 -0
  356. package/dist/server/server/schedule/cron.d.ts +4 -0
  357. package/dist/server/server/schedule/cron.js +81 -0
  358. package/dist/server/server/schedule/service.d.ts +89 -0
  359. package/dist/server/server/schedule/service.js +882 -0
  360. package/dist/server/server/schedule/store.d.ts +27 -0
  361. package/dist/server/server/schedule/store.js +190 -0
  362. package/dist/server/server/script-health-monitor.d.ts +39 -0
  363. package/dist/server/server/script-health-monitor.js +159 -0
  364. package/dist/server/server/script-proxy.d.ts +3 -0
  365. package/dist/server/server/script-proxy.js +2 -0
  366. package/dist/server/server/script-route-branch-handler.d.ts +10 -0
  367. package/dist/server/server/script-route-branch-handler.js +11 -0
  368. package/dist/server/server/script-status-projection.d.ts +36 -0
  369. package/dist/server/server/script-status-projection.js +200 -0
  370. package/dist/server/server/server-id.d.ts +17 -0
  371. package/dist/server/server/server-id.js +68 -0
  372. package/dist/server/server/service-proxy.d.ts +237 -0
  373. package/dist/server/server/service-proxy.js +714 -0
  374. package/dist/server/server/session/agent-config/agent-config-session.d.ts +59 -0
  375. package/dist/server/server/session/agent-config/agent-config-session.js +110 -0
  376. package/dist/server/server/session/agent-updates/agent-updates-service.d.ts +65 -0
  377. package/dist/server/server/session/agent-updates/agent-updates-service.js +232 -0
  378. package/dist/server/server/session/artifact/artifact-session.d.ts +45 -0
  379. package/dist/server/server/session/artifact/artifact-session.js +293 -0
  380. package/dist/server/server/session/chat/chat-schedule-loop-session.d.ts +120 -0
  381. package/dist/server/server/session/chat/chat-schedule-loop-session.js +489 -0
  382. package/dist/server/server/session/checkout/checkout-session.d.ts +146 -0
  383. package/dist/server/server/session/checkout/checkout-session.js +1000 -0
  384. package/dist/server/server/session/checkout/git-metadata-generator.d.ts +53 -0
  385. package/dist/server/server/session/checkout/git-metadata-generator.js +159 -0
  386. package/dist/server/server/session/daemon/daemon-self-update-session-controller.d.ts +32 -0
  387. package/dist/server/server/session/daemon/daemon-self-update-session-controller.js +88 -0
  388. package/dist/server/server/session/daemon/daemon-self-updater.d.ts +32 -0
  389. package/dist/server/server/session/daemon/daemon-self-updater.js +56 -0
  390. package/dist/server/server/session/daemon/daemon-session.d.ts +76 -0
  391. package/dist/server/server/session/daemon/daemon-session.js +148 -0
  392. package/dist/server/server/session/daemon/diagnostics.d.ts +41 -0
  393. package/dist/server/server/session/daemon/diagnostics.js +431 -0
  394. package/dist/server/server/session/daemon/install-origin.d.ts +7 -0
  395. package/dist/server/server/session/daemon/install-origin.js +64 -0
  396. package/dist/server/server/session/daemon/npm-global-cli.d.ts +29 -0
  397. package/dist/server/server/session/daemon/npm-global-cli.js +98 -0
  398. package/dist/server/server/session/files/workspace-files-session.d.ts +60 -0
  399. package/dist/server/server/session/files/workspace-files-session.js +518 -0
  400. package/dist/server/server/session/git-mutation/git-mutation-service.d.ts +34 -0
  401. package/dist/server/server/session/git-mutation/git-mutation-service.js +71 -0
  402. package/dist/server/server/session/project-config/project-config-session.d.ts +34 -0
  403. package/dist/server/server/session/project-config/project-config-session.js +125 -0
  404. package/dist/server/server/session/provider/provider-catalog-session.d.ts +74 -0
  405. package/dist/server/server/session/provider/provider-catalog-session.js +343 -0
  406. package/dist/server/server/session/voice/voice-session.d.ts +167 -0
  407. package/dist/server/server/session/voice/voice-session.js +912 -0
  408. package/dist/server/server/session/voice/voice-turn-controller.d.ts +38 -0
  409. package/dist/server/server/session/voice/voice-turn-controller.js +393 -0
  410. package/dist/server/server/session/workspace-git-observer/workspace-git-observer-service.d.ts +36 -0
  411. package/dist/server/server/session/workspace-git-observer/workspace-git-observer-service.js +134 -0
  412. package/dist/server/server/session/workspace-provisioning/workspace-provisioning-service.d.ts +34 -0
  413. package/dist/server/server/session/workspace-provisioning/workspace-provisioning-service.js +190 -0
  414. package/dist/server/server/session/workspace-scripts/workspace-scripts-service.d.ts +41 -0
  415. package/dist/server/server/session/workspace-scripts/workspace-scripts-service.js +100 -0
  416. package/dist/server/server/session.d.ts +450 -0
  417. package/dist/server/server/session.js +4763 -0
  418. package/dist/server/server/speech/audio.d.ts +10 -0
  419. package/dist/server/server/speech/audio.js +101 -0
  420. package/dist/server/server/speech/provider-resolver.d.ts +3 -0
  421. package/dist/server/server/speech/provider-resolver.js +7 -0
  422. package/dist/server/server/speech/providers/local/config.d.ts +30 -0
  423. package/dist/server/server/speech/providers/local/config.js +133 -0
  424. package/dist/server/server/speech/providers/local/models.d.ts +13 -0
  425. package/dist/server/server/speech/providers/local/models.js +21 -0
  426. package/dist/server/server/speech/providers/local/runtime.d.ts +31 -0
  427. package/dist/server/server/speech/providers/local/runtime.js +135 -0
  428. package/dist/server/server/speech/providers/local/sherpa/assets/silero_vad.onnx +0 -0
  429. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts +109 -0
  430. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js +129 -0
  431. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts +16 -0
  432. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js +195 -0
  433. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts +49 -0
  434. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js +73 -0
  435. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts +9 -0
  436. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +107 -0
  437. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts +28 -0
  438. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +137 -0
  439. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts +21 -0
  440. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +133 -0
  441. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts +18 -0
  442. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.js +84 -0
  443. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts +24 -0
  444. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js +145 -0
  445. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.d.ts +19 -0
  446. package/dist/server/server/speech/providers/local/sherpa/silero-vad-provider.js +49 -0
  447. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.d.ts +38 -0
  448. package/dist/server/server/speech/providers/local/sherpa/silero-vad-session.js +176 -0
  449. package/dist/server/server/speech/providers/local/sherpa/tts-voices.d.ts +10 -0
  450. package/dist/server/server/speech/providers/local/sherpa/tts-voices.js +86 -0
  451. package/dist/server/server/speech/providers/local/worker-bytes.d.ts +4 -0
  452. package/dist/server/server/speech/providers/local/worker-bytes.js +9 -0
  453. package/dist/server/server/speech/providers/local/worker-client.d.ts +93 -0
  454. package/dist/server/server/speech/providers/local/worker-client.js +591 -0
  455. package/dist/server/server/speech/providers/local/worker-process.d.ts +2 -0
  456. package/dist/server/server/speech/providers/local/worker-process.js +270 -0
  457. package/dist/server/server/speech/providers/local/worker-protocol.d.ts +96 -0
  458. package/dist/server/server/speech/providers/local/worker-protocol.js +2 -0
  459. package/dist/server/server/speech/providers/openai/config.d.ts +19 -0
  460. package/dist/server/server/speech/providers/openai/config.js +160 -0
  461. package/dist/server/server/speech/providers/openai/runtime.d.ts +29 -0
  462. package/dist/server/server/speech/providers/openai/runtime.js +102 -0
  463. package/dist/server/server/speech/providers/openai/stt.d.ts +23 -0
  464. package/dist/server/server/speech/providers/openai/stt.js +209 -0
  465. package/dist/server/server/speech/providers/openai/tts.d.ts +20 -0
  466. package/dist/server/server/speech/providers/openai/tts.js +70 -0
  467. package/dist/server/server/speech/speech-config-resolver.d.ts +11 -0
  468. package/dist/server/server/speech/speech-config-resolver.js +132 -0
  469. package/dist/server/server/speech/speech-provider.d.ts +71 -0
  470. package/dist/server/server/speech/speech-provider.js +2 -0
  471. package/dist/server/server/speech/speech-runtime.d.ts +67 -0
  472. package/dist/server/server/speech/speech-runtime.js +615 -0
  473. package/dist/server/server/speech/speech-settings-options.d.ts +14 -0
  474. package/dist/server/server/speech/speech-settings-options.js +73 -0
  475. package/dist/server/server/speech/speech-types.d.ts +22 -0
  476. package/dist/server/server/speech/speech-types.js +8 -0
  477. package/dist/server/server/speech/turn-detection-provider.d.ts +23 -0
  478. package/dist/server/server/speech/turn-detection-provider.js +2 -0
  479. package/dist/server/server/utils/diff-highlighter.d.ts +57 -0
  480. package/dist/server/server/utils/diff-highlighter.js +279 -0
  481. package/dist/server/server/voice-config.d.ts +15 -0
  482. package/dist/server/server/voice-config.js +54 -0
  483. package/dist/server/server/voice-permission-policy.d.ts +4 -0
  484. package/dist/server/server/voice-permission-policy.js +13 -0
  485. package/dist/server/server/voice-types.d.ts +12 -0
  486. package/dist/server/server/voice-types.js +2 -0
  487. package/dist/server/server/web-ui.d.ts +10 -0
  488. package/dist/server/server/web-ui.js +205 -0
  489. package/dist/server/server/websocket/runtime-metrics.d.ts +94 -0
  490. package/dist/server/server/websocket/runtime-metrics.js +148 -0
  491. package/dist/server/server/websocket-server.d.ts +187 -0
  492. package/dist/server/server/websocket-server.js +1766 -0
  493. package/dist/server/server/workspace-archive-service.d.ts +65 -0
  494. package/dist/server/server/workspace-archive-service.js +229 -0
  495. package/dist/server/server/workspace-auto-name.d.ts +55 -0
  496. package/dist/server/server/workspace-auto-name.js +128 -0
  497. package/dist/server/server/workspace-bootstrap-dedupe.d.ts +34 -0
  498. package/dist/server/server/workspace-bootstrap-dedupe.js +23 -0
  499. package/dist/server/server/workspace-directory.d.ts +93 -0
  500. package/dist/server/server/workspace-directory.js +422 -0
  501. package/dist/server/server/workspace-git-metadata.d.ts +24 -0
  502. package/dist/server/server/workspace-git-metadata.js +55 -0
  503. package/dist/server/server/workspace-git-service.d.ts +270 -0
  504. package/dist/server/server/workspace-git-service.js +1423 -0
  505. package/dist/server/server/workspace-reconciliation-service.d.ts +57 -0
  506. package/dist/server/server/workspace-reconciliation-service.js +278 -0
  507. package/dist/server/server/workspace-registry-bootstrap.d.ts +13 -0
  508. package/dist/server/server/workspace-registry-bootstrap.js +121 -0
  509. package/dist/server/server/workspace-registry-model.d.ts +55 -0
  510. package/dist/server/server/workspace-registry-model.js +190 -0
  511. package/dist/server/server/workspace-registry.d.ts +117 -0
  512. package/dist/server/server/workspace-registry.js +194 -0
  513. package/dist/server/server/workspace-script-runtime-store.d.ts +28 -0
  514. package/dist/server/server/workspace-script-runtime-store.js +78 -0
  515. package/dist/server/server/workspace-service-env.d.ts +18 -0
  516. package/dist/server/server/workspace-service-env.js +85 -0
  517. package/dist/server/server/workspace-service-port-registry.d.ts +19 -0
  518. package/dist/server/server/workspace-service-port-registry.js +59 -0
  519. package/dist/server/server/worktree/commands.d.ts +55 -0
  520. package/dist/server/server/worktree/commands.js +107 -0
  521. package/dist/server/server/worktree-bootstrap.d.ts +76 -0
  522. package/dist/server/server/worktree-bootstrap.js +720 -0
  523. package/dist/server/server/worktree-branch-name-generator.d.ts +35 -0
  524. package/dist/server/server/worktree-branch-name-generator.js +91 -0
  525. package/dist/server/server/worktree-core.d.ts +31 -0
  526. package/dist/server/server/worktree-core.js +105 -0
  527. package/dist/server/server/worktree-errors.d.ts +12 -0
  528. package/dist/server/server/worktree-errors.js +28 -0
  529. package/dist/server/server/worktree-session.d.ts +152 -0
  530. package/dist/server/server/worktree-session.js +466 -0
  531. package/dist/server/services/git-hosting/bitbucket-cloud-service.d.ts +24 -0
  532. package/dist/server/services/git-hosting/bitbucket-cloud-service.js +754 -0
  533. package/dist/server/services/git-hosting/github-hosting-service.d.ts +4 -0
  534. package/dist/server/services/git-hosting/github-hosting-service.js +11 -0
  535. package/dist/server/services/git-hosting/hosting-http-client.d.ts +20 -0
  536. package/dist/server/services/git-hosting/hosting-http-client.js +131 -0
  537. package/dist/server/services/git-hosting/request-cache.d.ts +20 -0
  538. package/dist/server/services/git-hosting/request-cache.js +68 -0
  539. package/dist/server/services/git-hosting/resolver.d.ts +32 -0
  540. package/dist/server/services/git-hosting/resolver.js +152 -0
  541. package/dist/server/services/git-hosting/router.d.ts +4 -0
  542. package/dist/server/services/git-hosting/router.js +105 -0
  543. package/dist/server/services/git-hosting/status-poller.d.ts +39 -0
  544. package/dist/server/services/git-hosting/status-poller.js +149 -0
  545. package/dist/server/services/git-hosting/types.d.ts +53 -0
  546. package/dist/server/services/git-hosting/types.js +75 -0
  547. package/dist/server/services/github-service.d.ts +339 -0
  548. package/dist/server/services/github-service.js +2109 -0
  549. package/dist/server/services/quota-fetcher/manifest.d.ts +4 -0
  550. package/dist/server/services/quota-fetcher/manifest.js +52 -0
  551. package/dist/server/services/quota-fetcher/provider.d.ts +17 -0
  552. package/dist/server/services/quota-fetcher/provider.js +2 -0
  553. package/dist/server/services/quota-fetcher/providers/claude.d.ts +26 -0
  554. package/dist/server/services/quota-fetcher/providers/claude.js +217 -0
  555. package/dist/server/services/quota-fetcher/providers/codex.d.ts +23 -0
  556. package/dist/server/services/quota-fetcher/providers/codex.js +211 -0
  557. package/dist/server/services/quota-fetcher/providers/copilot.d.ts +17 -0
  558. package/dist/server/services/quota-fetcher/providers/copilot.js +75 -0
  559. package/dist/server/services/quota-fetcher/providers/cursor.d.ts +17 -0
  560. package/dist/server/services/quota-fetcher/providers/cursor.js +123 -0
  561. package/dist/server/services/quota-fetcher/providers/grok.d.ts +18 -0
  562. package/dist/server/services/quota-fetcher/providers/grok.js +89 -0
  563. package/dist/server/services/quota-fetcher/providers/kimi.d.ts +20 -0
  564. package/dist/server/services/quota-fetcher/providers/kimi.js +89 -0
  565. package/dist/server/services/quota-fetcher/providers/minimax.d.ts +29 -0
  566. package/dist/server/services/quota-fetcher/providers/minimax.js +227 -0
  567. package/dist/server/services/quota-fetcher/providers/zai.d.ts +17 -0
  568. package/dist/server/services/quota-fetcher/providers/zai.js +58 -0
  569. package/dist/server/services/quota-fetcher/service.d.ts +28 -0
  570. package/dist/server/services/quota-fetcher/service.js +58 -0
  571. package/dist/server/services/quota-fetcher/usage.d.ts +22 -0
  572. package/dist/server/services/quota-fetcher/usage.js +49 -0
  573. package/dist/server/terminal/activity/terminal-activity-tracker.d.ts +20 -0
  574. package/dist/server/terminal/activity/terminal-activity-tracker.js +59 -0
  575. package/dist/server/terminal/agent-hooks/agent-hook-installer.d.ts +62 -0
  576. package/dist/server/terminal/agent-hooks/agent-hook-installer.js +117 -0
  577. package/dist/server/terminal/agent-hooks/claude/claude-settings.d.ts +7 -0
  578. package/dist/server/terminal/agent-hooks/claude/claude-settings.js +88 -0
  579. package/dist/server/terminal/agent-hooks/claude/claude.d.ts +4 -0
  580. package/dist/server/terminal/agent-hooks/claude/claude.js +47 -0
  581. package/dist/server/terminal/agent-hooks/codex/codex-settings.d.ts +7 -0
  582. package/dist/server/terminal/agent-hooks/codex/codex-settings.js +99 -0
  583. package/dist/server/terminal/agent-hooks/codex/codex.d.ts +4 -0
  584. package/dist/server/terminal/agent-hooks/codex/codex.js +30 -0
  585. package/dist/server/terminal/agent-hooks/opencode/opencode-plugin.d.ts +4 -0
  586. package/dist/server/terminal/agent-hooks/opencode/opencode-plugin.js +46 -0
  587. package/dist/server/terminal/agent-hooks/opencode/opencode.d.ts +3 -0
  588. package/dist/server/terminal/agent-hooks/opencode/opencode.js +23 -0
  589. package/dist/server/terminal/agent-hooks/provider-registry.d.ts +24 -0
  590. package/dist/server/terminal/agent-hooks/provider-registry.js +36 -0
  591. package/dist/server/terminal/agent-hooks/terminal-agent-hook-setting.d.ts +10 -0
  592. package/dist/server/terminal/agent-hooks/terminal-agent-hook-setting.js +26 -0
  593. package/dist/server/terminal/shell-integration/zsh/.zshenv +17 -0
  594. package/dist/server/terminal/shell-integration/zsh/otto-integration.zsh +32 -0
  595. package/dist/server/terminal/terminal-capture.d.ts +12 -0
  596. package/dist/server/terminal/terminal-capture.js +43 -0
  597. package/dist/server/terminal/terminal-manager-factory.d.ts +6 -0
  598. package/dist/server/terminal/terminal-manager-factory.js +5 -0
  599. package/dist/server/terminal/terminal-manager.d.ts +78 -0
  600. package/dist/server/terminal/terminal-manager.js +319 -0
  601. package/dist/server/terminal/terminal-output-coalescer.d.ts +34 -0
  602. package/dist/server/terminal/terminal-output-coalescer.js +73 -0
  603. package/dist/server/terminal/terminal-restore.d.ts +18 -0
  604. package/dist/server/terminal/terminal-restore.js +52 -0
  605. package/dist/server/terminal/terminal-session-controller.d.ts +85 -0
  606. package/dist/server/terminal/terminal-session-controller.js +819 -0
  607. package/dist/server/terminal/terminal-ts-loader.mjs +20 -0
  608. package/dist/server/terminal/terminal-worker-process.d.ts +2 -0
  609. package/dist/server/terminal/terminal-worker-process.js +304 -0
  610. package/dist/server/terminal/terminal-worker-protocol.d.ts +119 -0
  611. package/dist/server/terminal/terminal-worker-protocol.js +2 -0
  612. package/dist/server/terminal/terminal.d.ts +151 -0
  613. package/dist/server/terminal/terminal.js +1155 -0
  614. package/dist/server/terminal/worker-terminal-manager.d.ts +20 -0
  615. package/dist/server/terminal/worker-terminal-manager.js +688 -0
  616. package/dist/server/utils/build-metadata-prompt.d.ts +19 -0
  617. package/dist/server/utils/build-metadata-prompt.js +29 -0
  618. package/dist/server/utils/checkout-git.d.ts +253 -0
  619. package/dist/server/utils/checkout-git.js +2241 -0
  620. package/dist/server/utils/directory-suggestions.d.ts +26 -0
  621. package/dist/server/utils/directory-suggestions.js +830 -0
  622. package/dist/server/utils/git-rev-parse-path.d.ts +3 -0
  623. package/dist/server/utils/git-rev-parse-path.js +21 -0
  624. package/dist/server/utils/github-remote.d.ts +9 -0
  625. package/dist/server/utils/github-remote.js +62 -0
  626. package/dist/server/utils/otto-config-file.d.ts +30 -0
  627. package/dist/server/utils/otto-config-file.js +90 -0
  628. package/dist/server/utils/path.d.ts +18 -0
  629. package/dist/server/utils/path.js +123 -0
  630. package/dist/server/utils/project-icon.d.ts +39 -0
  631. package/dist/server/utils/project-icon.js +364 -0
  632. package/dist/server/utils/promise-timeout.d.ts +9 -0
  633. package/dist/server/utils/promise-timeout.js +25 -0
  634. package/dist/server/utils/run-git-command.d.ts +37 -0
  635. package/dist/server/utils/run-git-command.js +232 -0
  636. package/dist/server/utils/spawn.d.ts +25 -0
  637. package/dist/server/utils/spawn.js +59 -0
  638. package/dist/server/utils/string-command-shell.d.ts +13 -0
  639. package/dist/server/utils/string-command-shell.js +37 -0
  640. package/dist/server/utils/tree-kill.d.ts +18 -0
  641. package/dist/server/utils/tree-kill.js +77 -0
  642. package/dist/server/utils/windows-command.d.ts +15 -0
  643. package/dist/server/utils/windows-command.js +41 -0
  644. package/dist/server/utils/worktree-metadata.d.ts +39 -0
  645. package/dist/server/utils/worktree-metadata.js +174 -0
  646. package/dist/server/utils/worktree.d.ts +205 -0
  647. package/dist/server/utils/worktree.js +1120 -0
  648. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css +1 -0
  649. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css.br +0 -0
  650. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css.gz +0 -0
  651. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-a25c6055b348629689f75618db2c83e1.js +1 -0
  652. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-a25c6055b348629689f75618db2c83e1.js.br +0 -0
  653. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-a25c6055b348629689f75618db2c83e1.js.gz +0 -0
  654. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-7dc26ea1611eb9d7c2971a6745e5bf5c.js +1 -0
  655. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-7dc26ea1611eb9d7c2971a6745e5bf5c.js.br +0 -0
  656. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-7dc26ea1611eb9d7c2971a6745e5bf5c.js.gz +0 -0
  657. package/dist/server/web-ui/_expo/static/js/web/index-ea91f496cee180fa5bf308c8cc177646.js +3199 -0
  658. package/dist/server/web-ui/_expo/static/js/web/index-ea91f496cee180fa5bf308c8cc177646.js.br +0 -0
  659. package/dist/server/web-ui/_expo/static/js/web/index-ea91f496cee180fa5bf308c8cc177646.js.gz +0 -0
  660. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-b6b853a967343babf305512fe8c5958c.js +1 -0
  661. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-b6b853a967343babf305512fe8c5958c.js.br +0 -0
  662. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-b6b853a967343babf305512fe8c5958c.js.gz +0 -0
  663. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-17223e158406802adc686d02d946573d.js +3 -0
  664. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-17223e158406802adc686d02d946573d.js.br +0 -0
  665. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-17223e158406802adc686d02d946573d.js.gz +0 -0
  666. package/dist/server/web-ui/apple-touch-icon.png +0 -0
  667. package/dist/server/web-ui/assets/__node_modules/@expo-google-fonts/inter/400Regular/Inter_400Regular.51b6ad87261f18b6433ec52871ddfabc.ttf +0 -0
  668. package/dist/server/web-ui/assets/__node_modules/@expo-google-fonts/jetbrains-mono/400Regular/JetBrainsMono_400Regular.a0147b5ab9e4946e81879aef45313def.ttf +0 -0
  669. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
  670. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
  671. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
  672. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
  673. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
  674. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
  675. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
  676. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
  677. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
  678. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
  679. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
  680. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
  681. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
  682. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
  683. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
  684. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
  685. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
  686. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
  687. package/dist/server/web-ui/assets/assets/images/editor-apps/antigravity.6e91a685c33435e0b466a56db86cf141.png +0 -0
  688. package/dist/server/web-ui/assets/assets/images/editor-apps/clion.baa1f4eb572e962a6117bdbee95749e4.png +0 -0
  689. package/dist/server/web-ui/assets/assets/images/editor-apps/cursor.c31d6bce4fe9aadc3fe59962f4c4fcf3.png +0 -0
  690. package/dist/server/web-ui/assets/assets/images/editor-apps/finder.7f68fc2c475621a672e1be09309d5567.png +0 -0
  691. package/dist/server/web-ui/assets/assets/images/editor-apps/goland.0796ab2b9be2637fd1cdcde891fad3ca.png +0 -0
  692. package/dist/server/web-ui/assets/assets/images/editor-apps/intellij-idea.33bc9ff9c0815d8ad43f618c8c244401.png +0 -0
  693. package/dist/server/web-ui/assets/assets/images/editor-apps/phpstorm.c60b33bc7a8309143d232e14b76554c5.png +0 -0
  694. package/dist/server/web-ui/assets/assets/images/editor-apps/pycharm.88f25ac484989c45c25323e0adccfa9f.png +0 -0
  695. package/dist/server/web-ui/assets/assets/images/editor-apps/rider.1a1091dc3a0ede0461f0aa38a54f080a.png +0 -0
  696. package/dist/server/web-ui/assets/assets/images/editor-apps/rubymine.0e5b66fd7d43f8cbac0f05bba97c9a21.png +0 -0
  697. package/dist/server/web-ui/assets/assets/images/editor-apps/rustrover.3590ef05482369f41d3484c90272570d.png +0 -0
  698. package/dist/server/web-ui/assets/assets/images/editor-apps/vscode.832bdb4c685d930f1c864c793703600b.png +0 -0
  699. package/dist/server/web-ui/assets/assets/images/editor-apps/webstorm.aa5dc2cd8c20cc0a155c4c5c5ab3c5f5.png +0 -0
  700. package/dist/server/web-ui/assets/assets/images/editor-apps/zed.f3a670b7f9aa226da4fe53fb86f1abbd.png +0 -0
  701. package/dist/server/web-ui/assets/assets/images/favicon-dark-attention.3b2c331d11122d8f743c73a5878593be.png +0 -0
  702. package/dist/server/web-ui/assets/assets/images/favicon-dark-running.6077c2ab71021b31c82a42e0b42ad837.png +0 -0
  703. package/dist/server/web-ui/assets/assets/images/favicon-dark.12984efe6d435a13794a74cd2f858dcd.png +0 -0
  704. package/dist/server/web-ui/assets/assets/images/favicon-light-attention.3b2c331d11122d8f743c73a5878593be.png +0 -0
  705. package/dist/server/web-ui/assets/assets/images/favicon-light-running.6077c2ab71021b31c82a42e0b42ad837.png +0 -0
  706. package/dist/server/web-ui/assets/assets/images/favicon-light.12984efe6d435a13794a74cd2f858dcd.png +0 -0
  707. package/dist/server/web-ui/assets/assets/images/notification-icon.2394c3b427c0f5ee2bb84864d8fb0f45.png +0 -0
  708. package/dist/server/web-ui/favicon.ico +0 -0
  709. package/dist/server/web-ui/index.html +147 -0
  710. package/dist/server/web-ui/index.html.br +0 -0
  711. package/dist/server/web-ui/index.html.gz +0 -0
  712. package/dist/server/web-ui/manifest.json +27 -0
  713. package/dist/server/web-ui/manifest.json.br +0 -0
  714. package/dist/server/web-ui/manifest.json.gz +0 -0
  715. package/dist/server/web-ui/metadata.json +1 -0
  716. package/dist/server/web-ui/metadata.json.br +1 -0
  717. package/dist/server/web-ui/metadata.json.gz +0 -0
  718. package/dist/server/web-ui/pwa-icon-192.png +0 -0
  719. package/dist/server/web-ui/pwa-icon-512.png +0 -0
  720. package/dist/server/web-ui/robots.txt +2 -0
  721. package/dist/src/executable-resolution/executable-resolution.js +118 -0
  722. package/dist/src/executable-resolution/windows.js +65 -0
  723. package/dist/src/server/agent/provider-launch-config.js +167 -0
  724. package/dist/src/server/otto-env.js +53 -0
  725. package/dist/src/server/otto-home.js +19 -0
  726. package/dist/src/server/persisted-config.js +471 -0
  727. package/dist/src/server/pid-lock.js +170 -0
  728. package/dist/src/server/private-files.js +37 -0
  729. package/dist/src/server/speech/providers/local/sherpa/sherpa-runtime-env.js +84 -0
  730. package/dist/src/terminal/shell-integration/zsh/.zshenv +17 -0
  731. package/dist/src/terminal/shell-integration/zsh/otto-integration.zsh +32 -0
  732. package/dist/src/utils/spawn.js +59 -0
  733. package/dist/src/utils/windows-command.js +41 -0
  734. package/package.json +118 -0
@@ -0,0 +1,1120 @@
1
+ import { execFile } from "child_process";
2
+ import { promisify } from "util";
3
+ import { existsSync, mkdirSync, realpathSync, rmSync, statSync } from "fs";
4
+ import { copyFile, rm, stat } from "fs/promises";
5
+ import { join, basename, dirname, isAbsolute, resolve, sep } from "path";
6
+ import net from "node:net";
7
+ import { createHash } from "node:crypto";
8
+ import stripAnsi from "strip-ansi";
9
+ import { buildStringCommandShellInvocation, createStringCommandShellEnv, } from "./string-command-shell.js";
10
+ import { readOttoConfigJson, resolveOttoConfigPath } from "./otto-config-file.js";
11
+ export { OttoConfigRawSchema, OttoLifecycleCommandRawSchema, OttoScriptEntryRawSchema, OttoWorktreeConfigRawSchema, OttoConfigSchema, } from "@otto-code/protocol/otto-config-schema";
12
+ import { OttoConfigSchema } from "@otto-code/protocol/otto-config-schema";
13
+ import { normalizeBaseRefName, readOttoWorktreeMetadata, readOttoWorktreeRuntimePort, writeOttoWorktreeMetadata, writeOttoWorktreeRuntimeMetadata, } from "./worktree-metadata.js";
14
+ import { runGitCommand } from "./run-git-command.js";
15
+ import { spawnProcess } from "./spawn.js";
16
+ import { resolveOttoHome } from "../server/otto-home.js";
17
+ import { createExternalProcessEnv } from "../server/otto-env.js";
18
+ import { parseGitRevParsePath, resolveGitRevParsePath } from "./git-rev-parse-path.js";
19
+ import { validateBranchSlug } from "@otto-code/protocol/branch-slug";
20
+ import { expandTilde } from "./path.js";
21
+ export { slugify, validateBranchSlug } from "@otto-code/protocol/branch-slug";
22
+ const execFileAsync = promisify(execFile);
23
+ const READ_ONLY_GIT_ENV = {
24
+ GIT_OPTIONAL_LOCKS: "0",
25
+ };
26
+ export function isServiceScript(config) {
27
+ return "type" in config && config.type === "service";
28
+ }
29
+ export class WorktreeSetupError extends Error {
30
+ constructor(message, results) {
31
+ super(message);
32
+ this.name = "WorktreeSetupError";
33
+ this.results = results;
34
+ }
35
+ }
36
+ export class WorktreeTeardownError extends Error {
37
+ constructor(message, results) {
38
+ super(message);
39
+ this.name = "WorktreeTeardownError";
40
+ this.results = results;
41
+ }
42
+ }
43
+ export class BranchAlreadyCheckedOutError extends Error {
44
+ constructor(branchName) {
45
+ super(`Branch already checked out: ${branchName}`);
46
+ this.name = "BranchAlreadyCheckedOutError";
47
+ this.branchName = branchName;
48
+ }
49
+ }
50
+ export class UnknownBranchError extends Error {
51
+ constructor(params) {
52
+ super(`Unknown branch: ${params.branchName}`);
53
+ this.name = "UnknownBranchError";
54
+ this.branchName = params.branchName;
55
+ this.cwd = params.cwd;
56
+ }
57
+ }
58
+ export class InvalidGitBranchNameError extends Error {
59
+ constructor(branchName) {
60
+ super(`Invalid branch name: Git rejected ref name '${branchName}'`);
61
+ this.name = "InvalidGitBranchNameError";
62
+ this.branchName = branchName;
63
+ }
64
+ }
65
+ export function readOttoConfig(repoRoot) {
66
+ try {
67
+ const json = readOttoConfigJson(repoRoot);
68
+ if (json === null) {
69
+ return { ok: true, config: null };
70
+ }
71
+ return { ok: true, config: OttoConfigSchema.parse(json) };
72
+ }
73
+ catch (error) {
74
+ return { ok: false, configPath: resolveOttoConfigPath(repoRoot), error };
75
+ }
76
+ }
77
+ export function ottoConfigParseError(failure) {
78
+ const detail = failure.error instanceof Error ? failure.error.message : String(failure.error);
79
+ return new Error(`Failed to parse otto.json at ${failure.configPath}: ${detail}`, {
80
+ cause: failure.error,
81
+ });
82
+ }
83
+ function readOttoConfigOrThrow(repoRoot) {
84
+ const result = readOttoConfig(repoRoot);
85
+ if (!result.ok) {
86
+ throw ottoConfigParseError(result);
87
+ }
88
+ return result.config;
89
+ }
90
+ export function getWorktreeSetupCommands(repoRoot) {
91
+ return readOttoConfigOrThrow(repoRoot)?.worktree?.setup ?? [];
92
+ }
93
+ export function getWorktreeTeardownCommands(repoRoot) {
94
+ return readOttoConfigOrThrow(repoRoot)?.worktree?.teardown ?? [];
95
+ }
96
+ export function getWorktreeTerminalSpecs(repoRoot) {
97
+ const terminals = readOttoConfigOrThrow(repoRoot)?.worktree?.terminals;
98
+ if (!Array.isArray(terminals) || terminals.length === 0) {
99
+ return [];
100
+ }
101
+ const specs = [];
102
+ for (const terminal of terminals) {
103
+ if (!terminal || typeof terminal !== "object") {
104
+ continue;
105
+ }
106
+ const rawCommand = terminal.command;
107
+ if (typeof rawCommand !== "string") {
108
+ continue;
109
+ }
110
+ const command = rawCommand.trim();
111
+ if (!command) {
112
+ continue;
113
+ }
114
+ const rawName = terminal.name;
115
+ const name = typeof rawName === "string" && rawName.trim().length > 0 ? rawName.trim() : undefined;
116
+ specs.push({
117
+ ...(name ? { name } : {}),
118
+ command,
119
+ });
120
+ }
121
+ return specs;
122
+ }
123
+ export function getScriptConfigs(config) {
124
+ const scripts = config?.scripts;
125
+ if (!scripts || typeof scripts !== "object") {
126
+ return new Map();
127
+ }
128
+ const result = new Map();
129
+ for (const [name, entry] of Object.entries(scripts)) {
130
+ if (!entry || typeof entry !== "object") {
131
+ continue;
132
+ }
133
+ const rawCommand = entry.command;
134
+ if (typeof rawCommand !== "string") {
135
+ continue;
136
+ }
137
+ const command = rawCommand.trim();
138
+ if (!command) {
139
+ continue;
140
+ }
141
+ const scriptConfig = entry.type === "service"
142
+ ? {
143
+ type: "service",
144
+ command,
145
+ }
146
+ : { command };
147
+ if (isServiceScript(scriptConfig) &&
148
+ typeof entry.port === "number" &&
149
+ Number.isFinite(entry.port)) {
150
+ scriptConfig.port = entry.port;
151
+ }
152
+ result.set(name, scriptConfig);
153
+ }
154
+ return result;
155
+ }
156
+ export function processCarriageReturns(text) {
157
+ if (!text.includes("\r")) {
158
+ return text;
159
+ }
160
+ const output = [];
161
+ let line = [];
162
+ let cursor = 0;
163
+ const flushLine = () => {
164
+ output.push(line.join(""));
165
+ line = [];
166
+ cursor = 0;
167
+ };
168
+ for (let index = 0; index < text.length; index += 1) {
169
+ const char = text[index];
170
+ if (char === "\r") {
171
+ if (text[index + 1] === "\n") {
172
+ flushLine();
173
+ output.push("\n");
174
+ index += 1;
175
+ continue;
176
+ }
177
+ cursor = 0;
178
+ continue;
179
+ }
180
+ if (char === "\n") {
181
+ flushLine();
182
+ output.push("\n");
183
+ continue;
184
+ }
185
+ if (cursor < line.length) {
186
+ line[cursor] = char;
187
+ }
188
+ else {
189
+ line.push(char);
190
+ }
191
+ cursor += 1;
192
+ }
193
+ if (line.length > 0) {
194
+ output.push(line.join(""));
195
+ }
196
+ return output.join("");
197
+ }
198
+ async function execSetupCommand(command, options) {
199
+ const startedAt = Date.now();
200
+ const shellInvocation = buildStringCommandShellInvocation({ command });
201
+ try {
202
+ const { stdout, stderr } = await execFileAsync(shellInvocation.shell, shellInvocation.args, {
203
+ cwd: options.cwd,
204
+ env: options.env,
205
+ });
206
+ return {
207
+ command,
208
+ cwd: options.cwd,
209
+ stdout: stdout ?? "",
210
+ stderr: stderr ?? "",
211
+ exitCode: 0,
212
+ durationMs: Date.now() - startedAt,
213
+ };
214
+ }
215
+ catch (error) {
216
+ const execErr = error;
217
+ return {
218
+ command,
219
+ cwd: options.cwd,
220
+ stdout: execErr?.stdout ?? "",
221
+ stderr: execErr?.stderr ?? (error instanceof Error ? error.message : String(error)),
222
+ exitCode: typeof execErr?.code === "number" ? execErr.code : null,
223
+ durationMs: Date.now() - startedAt,
224
+ };
225
+ }
226
+ }
227
+ async function execSetupCommandStreamed(options) {
228
+ return new Promise((resolvePromise) => {
229
+ const startedAt = Date.now();
230
+ const stdoutChunks = [];
231
+ const stderrChunks = [];
232
+ let settled = false;
233
+ const emitOutput = (stream, chunk) => {
234
+ const text = stripAnsi(chunk);
235
+ if (!text) {
236
+ return;
237
+ }
238
+ if (stream === "stdout") {
239
+ stdoutChunks.push(text);
240
+ }
241
+ else {
242
+ stderrChunks.push(text);
243
+ }
244
+ options.onEvent?.({
245
+ type: "output",
246
+ index: options.index,
247
+ total: options.total,
248
+ command: options.command,
249
+ cwd: options.cwd,
250
+ stream,
251
+ chunk: text,
252
+ });
253
+ };
254
+ const finish = (exitCode) => {
255
+ if (settled) {
256
+ return;
257
+ }
258
+ settled = true;
259
+ const result = {
260
+ command: options.command,
261
+ cwd: options.cwd,
262
+ stdout: stdoutChunks.join(""),
263
+ stderr: stderrChunks.join(""),
264
+ exitCode,
265
+ durationMs: Date.now() - startedAt,
266
+ };
267
+ options.onEvent?.({
268
+ type: "command_completed",
269
+ index: options.index,
270
+ total: options.total,
271
+ command: options.command,
272
+ cwd: options.cwd,
273
+ exitCode: result.exitCode,
274
+ durationMs: result.durationMs,
275
+ stdout: result.stdout,
276
+ stderr: result.stderr,
277
+ });
278
+ resolvePromise(result);
279
+ };
280
+ options.onEvent?.({
281
+ type: "command_started",
282
+ index: options.index,
283
+ total: options.total,
284
+ command: options.command,
285
+ cwd: options.cwd,
286
+ });
287
+ const shellInvocation = buildStringCommandShellInvocation({ command: options.command });
288
+ const child = spawnProcess(shellInvocation.shell, shellInvocation.args, {
289
+ cwd: options.cwd,
290
+ env: options.env,
291
+ shell: false,
292
+ stdio: ["ignore", "pipe", "pipe"],
293
+ });
294
+ child.stdout?.on("data", (chunk) => {
295
+ emitOutput("stdout", chunk.toString());
296
+ });
297
+ child.stderr?.on("data", (chunk) => {
298
+ emitOutput("stderr", chunk.toString());
299
+ });
300
+ child.on("error", (error) => {
301
+ emitOutput("stderr", error instanceof Error ? error.message : String(error));
302
+ finish(null);
303
+ });
304
+ child.on("close", (code) => {
305
+ finish(typeof code === "number" ? code : null);
306
+ });
307
+ });
308
+ }
309
+ async function getAvailablePort() {
310
+ return new Promise((resolvePromise, reject) => {
311
+ const server = net.createServer();
312
+ server.once("error", reject);
313
+ server.listen(0, () => {
314
+ const address = server.address();
315
+ if (!address || typeof address === "string") {
316
+ server.close(() => reject(new Error("Failed to acquire available port")));
317
+ return;
318
+ }
319
+ server.close((error) => {
320
+ if (error) {
321
+ reject(error);
322
+ return;
323
+ }
324
+ resolvePromise(address.port);
325
+ });
326
+ });
327
+ });
328
+ }
329
+ async function assertPortAvailable(port) {
330
+ await new Promise((resolvePromise, reject) => {
331
+ const server = net.createServer();
332
+ server.once("error", (error) => {
333
+ let message;
334
+ if (error?.code === "EADDRINUSE") {
335
+ message = `Persisted worktree port ${port} is already in use`;
336
+ }
337
+ else if (error instanceof Error) {
338
+ message = error.message;
339
+ }
340
+ else {
341
+ message = String(error);
342
+ }
343
+ reject(new Error(message));
344
+ });
345
+ server.listen(port, () => {
346
+ server.close((error) => {
347
+ if (error) {
348
+ reject(error);
349
+ return;
350
+ }
351
+ resolvePromise();
352
+ });
353
+ });
354
+ });
355
+ }
356
+ async function inferRepoRootPathFromWorktreePath(worktreePath) {
357
+ try {
358
+ const commonDir = await getGitCommonDir(worktreePath);
359
+ const normalizedCommonDir = normalizePathForOwnership(commonDir);
360
+ // Normal repo/worktree: common dir is <repoRoot>/.git
361
+ if (basename(normalizedCommonDir) === ".git") {
362
+ return dirname(normalizedCommonDir);
363
+ }
364
+ // Bare repo: common dir is the repo dir itself
365
+ return normalizedCommonDir;
366
+ }
367
+ catch {
368
+ // Fallback: best-effort resolve toplevel (will be the worktree root in typical cases)
369
+ try {
370
+ const { stdout } = await runGitCommand(["rev-parse", "--show-toplevel"], {
371
+ cwd: worktreePath,
372
+ envOverlay: READ_ONLY_GIT_ENV,
373
+ });
374
+ const topLevel = parseGitRevParsePath(stdout);
375
+ if (topLevel) {
376
+ return normalizePathForOwnership(topLevel);
377
+ }
378
+ }
379
+ catch {
380
+ // ignore
381
+ }
382
+ return normalizePathForOwnership(worktreePath);
383
+ }
384
+ }
385
+ export async function runWorktreeSetupCommands(options) {
386
+ // Read otto.json from the worktree (it will have the same content as the source repo)
387
+ const setupCommands = getWorktreeSetupCommands(options.worktreePath);
388
+ if (setupCommands.length === 0) {
389
+ return [];
390
+ }
391
+ const runtimeEnv = options.runtimeEnv ??
392
+ (await resolveWorktreeRuntimeEnv({
393
+ worktreePath: options.worktreePath,
394
+ branchName: options.branchName,
395
+ ...(options.repoRootPath ? { repoRootPath: options.repoRootPath } : {}),
396
+ }));
397
+ const setupEnv = createStringCommandShellEnv(createExternalProcessEnv(process.env, runtimeEnv));
398
+ const results = [];
399
+ for (const [index, cmd] of setupCommands.entries()) {
400
+ const result = options.onEvent
401
+ ? await execSetupCommandStreamed({
402
+ command: cmd,
403
+ cwd: options.worktreePath,
404
+ env: setupEnv,
405
+ index: index + 1,
406
+ total: setupCommands.length,
407
+ onEvent: options.onEvent,
408
+ })
409
+ : await execSetupCommand(cmd, {
410
+ cwd: options.worktreePath,
411
+ env: setupEnv,
412
+ });
413
+ results.push(result);
414
+ if (result.exitCode !== 0) {
415
+ if (options.cleanupOnFailure) {
416
+ try {
417
+ await runGitCommand(["worktree", "remove", options.worktreePath, "--force"], {
418
+ cwd: options.worktreePath,
419
+ timeout: 120000,
420
+ });
421
+ }
422
+ catch {
423
+ rmSync(options.worktreePath, { recursive: true, force: true });
424
+ }
425
+ }
426
+ throw new WorktreeSetupError(`Worktree setup command failed: ${cmd}\n${result.stderr}`.trim(), results);
427
+ }
428
+ }
429
+ return results;
430
+ }
431
+ async function resolveBranchNameForWorktreePath(worktreePath) {
432
+ try {
433
+ const { stdout } = await runGitCommand(["branch", "--show-current"], {
434
+ cwd: worktreePath,
435
+ envOverlay: READ_ONLY_GIT_ENV,
436
+ });
437
+ const branchName = stdout.trim();
438
+ if (branchName.length > 0) {
439
+ return branchName;
440
+ }
441
+ }
442
+ catch {
443
+ // ignore
444
+ }
445
+ return basename(worktreePath);
446
+ }
447
+ export async function resolveWorktreeRuntimeEnv(options) {
448
+ const repoRootPath = options.repoRootPath ?? (await inferRepoRootPathFromWorktreePath(options.worktreePath));
449
+ const branchName = options.branchName ?? (await resolveBranchNameForWorktreePath(options.worktreePath));
450
+ let worktreePort = readOttoWorktreeRuntimePort(options.worktreePath);
451
+ if (worktreePort === null) {
452
+ worktreePort = await getAvailablePort();
453
+ const metadata = readOttoWorktreeMetadata(options.worktreePath);
454
+ if (metadata) {
455
+ writeOttoWorktreeRuntimeMetadata(options.worktreePath, { worktreePort });
456
+ }
457
+ }
458
+ else {
459
+ await assertPortAvailable(worktreePort);
460
+ }
461
+ return {
462
+ // Source checkout path is the original git repo root (shared across worktrees), not the
463
+ // worktree itself. This allows setup scripts to copy local files (e.g. .env) from the
464
+ // source checkout.
465
+ OTTO_SOURCE_CHECKOUT_PATH: repoRootPath,
466
+ // Backward-compatible alias.
467
+ OTTO_ROOT_PATH: repoRootPath,
468
+ OTTO_WORKTREE_PATH: options.worktreePath,
469
+ OTTO_BRANCH_NAME: branchName,
470
+ OTTO_WORKTREE_PORT: String(worktreePort),
471
+ };
472
+ }
473
+ export async function runWorktreeTeardownCommands(options) {
474
+ // Read otto.json from the worktree (it will have the same content as the source repo)
475
+ const teardownCommands = getWorktreeTeardownCommands(options.worktreePath);
476
+ if (teardownCommands.length === 0) {
477
+ return [];
478
+ }
479
+ const repoRootPath = options.repoRootPath ?? (await inferRepoRootPathFromWorktreePath(options.worktreePath));
480
+ const branchName = options.branchName ?? (await resolveBranchNameForWorktreePath(options.worktreePath));
481
+ const worktreePort = readOttoWorktreeRuntimePort(options.worktreePath);
482
+ const teardownEnv = createStringCommandShellEnv(createExternalProcessEnv(process.env, {
483
+ // Source checkout path is the original git repo root (shared across worktrees), not the
484
+ // worktree itself. This allows lifecycle scripts to copy or clean resources using paths
485
+ // from the source checkout.
486
+ OTTO_SOURCE_CHECKOUT_PATH: repoRootPath,
487
+ // Backward-compatible alias.
488
+ OTTO_ROOT_PATH: repoRootPath,
489
+ OTTO_WORKTREE_PATH: options.worktreePath,
490
+ OTTO_BRANCH_NAME: branchName,
491
+ ...(worktreePort !== null ? { OTTO_WORKTREE_PORT: String(worktreePort) } : {}),
492
+ }));
493
+ const results = [];
494
+ for (const cmd of teardownCommands) {
495
+ const result = await execSetupCommand(cmd, {
496
+ cwd: options.worktreePath,
497
+ env: teardownEnv,
498
+ });
499
+ results.push(result);
500
+ if (result.exitCode !== 0) {
501
+ throw new WorktreeTeardownError(`Worktree teardown command failed: ${cmd}\n${result.stderr}`.trim(), results);
502
+ }
503
+ }
504
+ return results;
505
+ }
506
+ /**
507
+ * Get the git common directory (shared across worktrees) for a given cwd.
508
+ * This is where refs, objects, etc. are stored.
509
+ */
510
+ export async function getGitCommonDir(cwd) {
511
+ const { stdout } = await runGitCommand(["rev-parse", "--git-common-dir"], {
512
+ cwd,
513
+ envOverlay: READ_ONLY_GIT_ENV,
514
+ });
515
+ const commonDir = resolveGitRevParsePath(cwd, stdout);
516
+ if (!commonDir) {
517
+ throw new Error("Not in a git repository");
518
+ }
519
+ return commonDir;
520
+ }
521
+ const WORKTREE_PROJECT_HASH_LENGTH = 8;
522
+ function deriveShortAlphanumericHash(value) {
523
+ const digest = createHash("sha256").update(value).digest();
524
+ let hashValue = 0n;
525
+ for (let index = 0; index < 8; index += 1) {
526
+ hashValue = (hashValue << 8n) | BigInt(digest[index] ?? 0);
527
+ }
528
+ return hashValue.toString(36).padStart(13, "0").slice(0, WORKTREE_PROJECT_HASH_LENGTH);
529
+ }
530
+ export async function deriveWorktreeProjectHash(cwd) {
531
+ try {
532
+ const commonDir = await getGitCommonDir(cwd);
533
+ const normalizedCommonDir = normalizePathForOwnership(commonDir);
534
+ const repoRoot = basename(normalizedCommonDir) === ".git" ? dirname(normalizedCommonDir) : normalizedCommonDir;
535
+ return deriveShortAlphanumericHash(repoRoot);
536
+ }
537
+ catch {
538
+ return deriveShortAlphanumericHash(normalizePathForOwnership(cwd));
539
+ }
540
+ }
541
+ export function resolveOttoWorktreesBaseRoot(options) {
542
+ if (options?.worktreesRoot) {
543
+ const expandedRoot = expandTilde(options.worktreesRoot);
544
+ if (isAbsolute(expandedRoot)) {
545
+ return resolve(expandedRoot);
546
+ }
547
+ const home = options.ottoHome ? resolve(options.ottoHome) : resolveOttoHome();
548
+ return resolve(home, expandedRoot);
549
+ }
550
+ const home = options?.ottoHome ? resolve(options.ottoHome) : resolveOttoHome();
551
+ return join(home, "worktrees");
552
+ }
553
+ export async function getOttoWorktreesRoot(cwd, ottoHome, worktreesRoot) {
554
+ const baseRoot = resolveOttoWorktreesBaseRoot({ ottoHome, worktreesRoot });
555
+ const projectHash = await deriveWorktreeProjectHash(cwd);
556
+ return join(baseRoot, projectHash);
557
+ }
558
+ export async function computeWorktreePath(cwd, slug, ottoHome, worktreesRoot) {
559
+ const projectWorktreesRoot = await getOttoWorktreesRoot(cwd, ottoHome, worktreesRoot);
560
+ return join(projectWorktreesRoot, slug);
561
+ }
562
+ function normalizePathForOwnership(input) {
563
+ try {
564
+ return realpathSync(input);
565
+ }
566
+ catch {
567
+ return resolve(input);
568
+ }
569
+ }
570
+ function resolveRepoRootFromGitCommonDir(commonDir) {
571
+ const normalizedCommonDir = normalizePathForOwnership(commonDir);
572
+ return basename(normalizedCommonDir) === ".git"
573
+ ? dirname(normalizedCommonDir)
574
+ : normalizedCommonDir;
575
+ }
576
+ export async function isOttoOwnedWorktreeCwd(cwd, options) {
577
+ const resolvedCwd = normalizePathForOwnership(cwd);
578
+ // repoRoot is best-effort: git may be unreachable from the worktree (e.g. a
579
+ // previous archive attempt removed the admin dir before the working tree
580
+ // could be fully cleaned up). We still want to allow archiving in that case.
581
+ let repoRoot;
582
+ try {
583
+ const gitCommonDir = await getGitCommonDir(cwd);
584
+ repoRoot = resolveRepoRootFromGitCommonDir(gitCommonDir);
585
+ }
586
+ catch {
587
+ // ignore
588
+ }
589
+ const worktreesBaseRoot = resolveOttoWorktreesBaseRoot(options);
590
+ const ottoWorktreesPrefix = normalizePathForOwnership(worktreesBaseRoot) + sep;
591
+ // Ownership is defined by the path living under <worktrees-root>/<hash>/<slug>[/...].
592
+ // The <hash>/<slug> prefix is Otto-private — nothing else writes there — so the
593
+ // path shape alone is sufficient proof of ownership, even when git has already
594
+ // forgotten about the worktree.
595
+ if (!resolvedCwd.startsWith(ottoWorktreesPrefix)) {
596
+ return {
597
+ allowed: false,
598
+ ...(repoRoot !== undefined ? { repoRoot } : {}),
599
+ worktreePath: resolvedCwd,
600
+ };
601
+ }
602
+ const relative = resolvedCwd.slice(ottoWorktreesPrefix.length);
603
+ const parts = relative.split(sep).filter((part) => part.length > 0);
604
+ if (parts.length < 2) {
605
+ return {
606
+ allowed: false,
607
+ ...(repoRoot !== undefined ? { repoRoot } : {}),
608
+ worktreePath: resolvedCwd,
609
+ };
610
+ }
611
+ const worktreesRoot = join(worktreesBaseRoot, parts[0]);
612
+ return {
613
+ allowed: true,
614
+ ...(repoRoot !== undefined ? { repoRoot } : {}),
615
+ worktreeRoot: worktreesRoot,
616
+ worktreePath: resolvedCwd,
617
+ };
618
+ }
619
+ function parseWorktreeList(output) {
620
+ const entries = [];
621
+ let current = null;
622
+ for (const line of output.split("\n")) {
623
+ if (line.startsWith("worktree ")) {
624
+ if (current?.path) {
625
+ entries.push(current);
626
+ }
627
+ current = { path: line.slice("worktree ".length).trim() };
628
+ continue;
629
+ }
630
+ if (!current) {
631
+ continue;
632
+ }
633
+ if (line.startsWith("branch ")) {
634
+ const ref = line.slice("branch ".length).trim();
635
+ current.branchName = ref.startsWith("refs/heads/") ? ref.slice("refs/heads/".length) : ref;
636
+ }
637
+ else if (line.startsWith("HEAD ")) {
638
+ current.head = line.slice("HEAD ".length).trim();
639
+ }
640
+ else if (line.trim().length === 0) {
641
+ if (current.path) {
642
+ entries.push(current);
643
+ }
644
+ current = null;
645
+ }
646
+ }
647
+ if (current?.path) {
648
+ entries.push(current);
649
+ }
650
+ return entries;
651
+ }
652
+ function resolveWorktreeCreatedAtIso(worktreePath) {
653
+ try {
654
+ const stats = statSync(worktreePath);
655
+ const birthtimeMs = stats.birthtimeMs;
656
+ const createdAtMs = Number.isFinite(birthtimeMs) && birthtimeMs > 0 ? birthtimeMs : stats.ctimeMs;
657
+ return new Date(createdAtMs).toISOString();
658
+ }
659
+ catch {
660
+ return new Date(0).toISOString();
661
+ }
662
+ }
663
+ export async function listOttoWorktrees({ cwd, ottoHome, worktreesRoot, }) {
664
+ const projectWorktreesRoot = await getOttoWorktreesRoot(cwd, ottoHome, worktreesRoot);
665
+ const { stdout } = await runGitCommand(["worktree", "list", "--porcelain"], {
666
+ cwd,
667
+ envOverlay: READ_ONLY_GIT_ENV,
668
+ });
669
+ const rootPrefix = normalizePathForOwnership(projectWorktreesRoot) + sep;
670
+ return parseWorktreeList(stdout)
671
+ .map((entry) => Object.assign({}, entry, { path: normalizePathForOwnership(entry.path) }))
672
+ .filter((entry) => entry.path.startsWith(rootPrefix))
673
+ .map((entry) => Object.assign({}, entry, { createdAt: resolveWorktreeCreatedAtIso(entry.path) }));
674
+ }
675
+ export async function resolveExistingWorktreeForSlug({ slug, repoRoot, ottoHome, worktreesRoot, }) {
676
+ const worktrees = await listOttoWorktrees({
677
+ cwd: repoRoot,
678
+ ottoHome,
679
+ worktreesRoot,
680
+ });
681
+ const slugSuffix = `${sep}${slug}`;
682
+ const existingWorktree = worktrees.find((worktree) => worktree.path.endsWith(slugSuffix));
683
+ if (!existingWorktree) {
684
+ return null;
685
+ }
686
+ const { stdout } = await runGitCommand(["branch", "--show-current"], {
687
+ cwd: existingWorktree.path,
688
+ envOverlay: READ_ONLY_GIT_ENV,
689
+ });
690
+ const branchName = stdout.trim();
691
+ if (!branchName) {
692
+ throw new Error(`Unable to resolve branch for existing worktree: ${existingWorktree.path}`);
693
+ }
694
+ return {
695
+ branchName,
696
+ worktreePath: existingWorktree.path,
697
+ };
698
+ }
699
+ export async function resolveOttoWorktreeRootForCwd(cwd, options) {
700
+ let gitCommonDir;
701
+ try {
702
+ gitCommonDir = await getGitCommonDir(cwd);
703
+ }
704
+ catch {
705
+ return null;
706
+ }
707
+ const worktreesRoot = await getOttoWorktreesRoot(cwd, options?.ottoHome, options?.worktreesRoot);
708
+ const resolvedRoot = normalizePathForOwnership(worktreesRoot) + sep;
709
+ let worktreeRoot = null;
710
+ try {
711
+ const { stdout } = await runGitCommand(["rev-parse", "--show-toplevel"], {
712
+ cwd,
713
+ envOverlay: READ_ONLY_GIT_ENV,
714
+ });
715
+ worktreeRoot = parseGitRevParsePath(stdout);
716
+ }
717
+ catch {
718
+ worktreeRoot = null;
719
+ }
720
+ if (!worktreeRoot) {
721
+ return null;
722
+ }
723
+ const resolvedWorktreeRoot = normalizePathForOwnership(worktreeRoot);
724
+ if (!resolvedWorktreeRoot.startsWith(resolvedRoot)) {
725
+ return null;
726
+ }
727
+ const knownWorktrees = await listOttoWorktrees({
728
+ cwd,
729
+ ottoHome: options?.ottoHome,
730
+ worktreesRoot: options?.worktreesRoot,
731
+ });
732
+ const match = knownWorktrees.find((entry) => entry.path === resolvedWorktreeRoot);
733
+ if (!match) {
734
+ return null;
735
+ }
736
+ return {
737
+ repoRoot: gitCommonDir,
738
+ worktreeRoot: worktreesRoot,
739
+ worktreePath: match.path,
740
+ };
741
+ }
742
+ export async function deleteOttoWorktree({ cwd, worktreePath, worktreeSlug, worktreesRoot, ottoHome, worktreesBaseRoot, }) {
743
+ if (!worktreePath && !worktreeSlug) {
744
+ throw new Error("worktreePath or worktreeSlug is required");
745
+ }
746
+ // Resolve the worktrees-root. With a repo cwd we hash it the normal way; if
747
+ // git has forgotten about the worktree we expect the caller to hand us the
748
+ // path-derived worktreesRoot from the ownership check.
749
+ let resolvedWorktreesRoot;
750
+ if (worktreesRoot) {
751
+ resolvedWorktreesRoot = worktreesRoot;
752
+ }
753
+ else if (cwd) {
754
+ resolvedWorktreesRoot = await getOttoWorktreesRoot(cwd, ottoHome, worktreesBaseRoot);
755
+ }
756
+ else {
757
+ throw new Error("cwd or worktreesRoot is required to delete a Otto worktree");
758
+ }
759
+ const resolvedRoot = normalizePathForOwnership(resolvedWorktreesRoot) + sep;
760
+ const requestedPath = worktreePath ?? join(resolvedWorktreesRoot, worktreeSlug);
761
+ const resolvedRequested = normalizePathForOwnership(requestedPath);
762
+ const resolvedWorktree = (await resolveOttoWorktreeRootForCwd(requestedPath, {
763
+ ottoHome,
764
+ worktreesRoot: worktreesBaseRoot,
765
+ }))?.worktreePath ?? resolvedRequested;
766
+ if (!resolvedWorktree.startsWith(resolvedRoot)) {
767
+ throw new Error("Refusing to delete non-Otto worktree");
768
+ }
769
+ if (await pathExists(resolvedWorktree)) {
770
+ await runWorktreeTeardownCommands({
771
+ worktreePath: resolvedWorktree,
772
+ });
773
+ }
774
+ if (cwd) {
775
+ try {
776
+ await runGitCommand(["worktree", "remove", resolvedWorktree, "--force"], {
777
+ cwd,
778
+ timeout: 120000,
779
+ });
780
+ }
781
+ catch {
782
+ // `git worktree remove` fails if the admin dir is already gone (e.g. a
783
+ // prior archive attempt removed it before the working tree could be
784
+ // fully cleaned up), or if the repo root has moved. Fall through to the
785
+ // rm retry loop below so the operation stays idempotent.
786
+ }
787
+ }
788
+ await removeDirectoryWithRetries(resolvedWorktree);
789
+ if (cwd) {
790
+ try {
791
+ await runGitCommand(["worktree", "prune"], { cwd, timeout: 30000 });
792
+ }
793
+ catch {
794
+ // not critical; git will prune lazily
795
+ }
796
+ }
797
+ }
798
+ async function pathExists(path) {
799
+ try {
800
+ await stat(path);
801
+ return true;
802
+ }
803
+ catch (error) {
804
+ if (error.code === "ENOENT") {
805
+ return false;
806
+ }
807
+ throw error;
808
+ }
809
+ }
810
+ async function removeDirectoryWithRetries(path) {
811
+ if (!(await pathExists(path))) {
812
+ return;
813
+ }
814
+ const delaysMs = [0, 100, 300, 700, 1500];
815
+ let lastError = null;
816
+ for (const delay of delaysMs) {
817
+ if (delay > 0) {
818
+ await new Promise((resolvePromise) => setTimeout(resolvePromise, delay));
819
+ }
820
+ try {
821
+ await rm(path, { recursive: true, force: true });
822
+ if (!(await pathExists(path))) {
823
+ return;
824
+ }
825
+ lastError = new Error(`Directory still present after rm: ${path}`);
826
+ }
827
+ catch (error) {
828
+ lastError = error;
829
+ }
830
+ }
831
+ if (await pathExists(path)) {
832
+ throw lastError instanceof Error
833
+ ? lastError
834
+ : new Error(`Failed to remove worktree directory: ${path}`);
835
+ }
836
+ }
837
+ /**
838
+ * Create a git worktree with proper naming conventions
839
+ */
840
+ export const createWorktree = async ({ cwd, source, worktreeSlug, runSetup, ottoHome, worktreesRoot, }) => {
841
+ const sourcePlan = await resolveWorktreeSourcePlan({ cwd, source, desiredSlug: worktreeSlug });
842
+ let worktreePath = join(await getOttoWorktreesRoot(cwd, ottoHome, worktreesRoot), worktreeSlug);
843
+ mkdirSync(dirname(worktreePath), { recursive: true });
844
+ // Also handle worktree path collision
845
+ let finalWorktreePath = worktreePath;
846
+ let pathSuffix = 1;
847
+ while (existsSync(finalWorktreePath)) {
848
+ finalWorktreePath = `${worktreePath}-${pathSuffix}`;
849
+ pathSuffix++;
850
+ }
851
+ // Primitive owner for `git worktree add`; callers route through createWorktreeCore.
852
+ await runGitCommand(["worktree", "add", finalWorktreePath, ...sourcePlan.addArguments], {
853
+ cwd,
854
+ timeout: 120000,
855
+ });
856
+ worktreePath = normalizePathForOwnership(finalWorktreePath);
857
+ if (sourcePlan.pushRemote) {
858
+ await configureWorktreePushRemote({
859
+ cwd,
860
+ branchName: sourcePlan.branchName,
861
+ remote: sourcePlan.pushRemote,
862
+ });
863
+ }
864
+ if (sourcePlan.trackingRemote) {
865
+ await configureWorktreeTrackingRemote({
866
+ cwd,
867
+ branchName: sourcePlan.branchName,
868
+ remote: sourcePlan.trackingRemote,
869
+ });
870
+ }
871
+ writeOttoWorktreeMetadata(worktreePath, { baseRefName: sourcePlan.metadataBaseRefName });
872
+ // If otto.json exists in the main repo but wasn't checked into the worktree
873
+ // (e.g. uncommitted on first-time setup), seed the worktree with it so setup
874
+ // commands and scripts pick up the user's intended config.
875
+ const mainConfigPath = join(cwd, "otto.json");
876
+ const worktreeConfigPath = join(worktreePath, "otto.json");
877
+ try {
878
+ await stat(worktreeConfigPath);
879
+ }
880
+ catch {
881
+ await copyFile(mainConfigPath, worktreeConfigPath).catch((err) => {
882
+ if (err.code !== "ENOENT")
883
+ throw err;
884
+ });
885
+ }
886
+ if (runSetup) {
887
+ await runWorktreeSetupCommands({
888
+ worktreePath,
889
+ branchName: sourcePlan.branchName,
890
+ cleanupOnFailure: true,
891
+ });
892
+ }
893
+ return {
894
+ branchName: sourcePlan.branchName,
895
+ worktreePath,
896
+ };
897
+ };
898
+ async function resolveWorktreeSourcePlan({ cwd, source, desiredSlug, }) {
899
+ switch (source.kind) {
900
+ case "branch-off": {
901
+ const branchName = source.branchName;
902
+ validateWorktreeBranchName(branchName);
903
+ const normalizedBaseBranch = normalizeRequiredBaseBranch(source.baseBranch);
904
+ const resolvedBaseBranch = await resolveBaseBranchForWorktree(cwd, normalizedBaseBranch);
905
+ const branchExists = await localBranchExists(cwd, branchName);
906
+ const base = branchExists ? branchName : resolvedBaseBranch;
907
+ const candidateBranch = branchExists ? desiredSlug : branchName;
908
+ const newBranchName = await resolveUniqueLocalBranchName(cwd, candidateBranch);
909
+ return {
910
+ branchName: newBranchName,
911
+ metadataBaseRefName: normalizedBaseBranch,
912
+ addArguments: ["-b", newBranchName, "--no-track", base],
913
+ };
914
+ }
915
+ case "checkout-branch": {
916
+ await validateExistingWorktreeBranchName(cwd, source.branchName);
917
+ if (!(await localBranchExists(cwd, source.branchName))) {
918
+ try {
919
+ await runGitCommand(["fetch", "origin", `${source.branchName}:${source.branchName}`], {
920
+ cwd,
921
+ timeout: 120000,
922
+ });
923
+ }
924
+ catch {
925
+ throw new UnknownBranchError({ branchName: source.branchName, cwd });
926
+ }
927
+ }
928
+ if (await isBranchCheckedOut(cwd, source.branchName)) {
929
+ throw new BranchAlreadyCheckedOutError(source.branchName);
930
+ }
931
+ return {
932
+ branchName: source.branchName,
933
+ metadataBaseRefName: source.branchName,
934
+ addArguments: [source.branchName],
935
+ };
936
+ }
937
+ case "checkout-github-pr": {
938
+ const localBranchCandidate = source.localBranchName ?? source.headRef;
939
+ await validateExistingWorktreeBranchName(cwd, localBranchCandidate);
940
+ const localBranchName = await resolveUniqueLocalBranchName(cwd, localBranchCandidate);
941
+ const normalizedBaseRefName = normalizeRequiredBaseBranch(source.baseRefName);
942
+ await runGitCommand([
943
+ "fetch",
944
+ "origin",
945
+ `refs/pull/${source.githubPrNumber}/head:refs/heads/${localBranchName}`,
946
+ "--force",
947
+ ], {
948
+ cwd,
949
+ timeout: 120000,
950
+ });
951
+ const trackingRemote = source.trackOriginHead
952
+ ? await tryFetchWorktreeTrackingRemote({
953
+ cwd,
954
+ remoteName: "origin",
955
+ headRef: source.headRef,
956
+ })
957
+ : undefined;
958
+ const remotePlan = {};
959
+ if (source.pushRemoteUrl) {
960
+ const remoteName = `otto-pr-${source.githubPrNumber}`;
961
+ remotePlan.pushRemote = {
962
+ name: remoteName,
963
+ url: source.pushRemoteUrl,
964
+ headRef: source.headRef,
965
+ track: true,
966
+ };
967
+ }
968
+ else if (source.trackOriginHead && localBranchName !== source.headRef) {
969
+ const originUrl = await getWorktreeRemotePushUrl(cwd, "origin");
970
+ if (originUrl) {
971
+ remotePlan.pushRemote = {
972
+ name: `otto-pr-${source.githubPrNumber}`,
973
+ url: originUrl,
974
+ headRef: source.headRef,
975
+ track: false,
976
+ };
977
+ }
978
+ }
979
+ if (trackingRemote) {
980
+ remotePlan.trackingRemote = trackingRemote;
981
+ }
982
+ return {
983
+ branchName: localBranchName,
984
+ metadataBaseRefName: normalizedBaseRefName,
985
+ addArguments: [localBranchName],
986
+ ...remotePlan,
987
+ };
988
+ }
989
+ }
990
+ }
991
+ async function configureWorktreePushRemote(options) {
992
+ await runGitCommand(["config", `remote.${options.remote.name}.url`, options.remote.url], {
993
+ cwd: options.cwd,
994
+ });
995
+ await runGitCommand(["config", `remote.${options.remote.name}.push`, `HEAD:refs/heads/${options.remote.headRef}`], { cwd: options.cwd });
996
+ await runGitCommand(["config", `branch.${options.branchName}.pushRemote`, options.remote.name], {
997
+ cwd: options.cwd,
998
+ });
999
+ if (!options.remote.track) {
1000
+ return;
1001
+ }
1002
+ await runGitCommand([
1003
+ "config",
1004
+ `remote.${options.remote.name}.fetch`,
1005
+ `+refs/heads/${options.remote.headRef}:refs/remotes/${options.remote.name}/${options.remote.headRef}`,
1006
+ ], { cwd: options.cwd });
1007
+ const trackingRemote = await tryFetchWorktreeTrackingRemote({
1008
+ cwd: options.cwd,
1009
+ remoteName: options.remote.name,
1010
+ headRef: options.remote.headRef,
1011
+ });
1012
+ if (trackingRemote) {
1013
+ await configureWorktreeTrackingRemote({
1014
+ cwd: options.cwd,
1015
+ branchName: options.branchName,
1016
+ remote: trackingRemote,
1017
+ });
1018
+ }
1019
+ }
1020
+ async function tryFetchWorktreeTrackingRemote(options) {
1021
+ const result = await runGitCommand([
1022
+ "fetch",
1023
+ options.remoteName,
1024
+ `+refs/heads/${options.headRef}:refs/remotes/${options.remoteName}/${options.headRef}`,
1025
+ ], {
1026
+ cwd: options.cwd,
1027
+ timeout: 120000,
1028
+ acceptExitCodes: [0, 1, 128],
1029
+ });
1030
+ return result.exitCode === 0 ? { name: options.remoteName, headRef: options.headRef } : undefined;
1031
+ }
1032
+ async function getWorktreeRemotePushUrl(cwd, remoteName) {
1033
+ try {
1034
+ const { stdout } = await runGitCommand(["remote", "get-url", "--push", remoteName], {
1035
+ cwd,
1036
+ });
1037
+ const url = stdout.trim();
1038
+ return url.length > 0 ? url : undefined;
1039
+ }
1040
+ catch {
1041
+ return undefined;
1042
+ }
1043
+ }
1044
+ async function configureWorktreeTrackingRemote(options) {
1045
+ await runGitCommand([
1046
+ "branch",
1047
+ "--set-upstream-to",
1048
+ `${options.remote.name}/${options.remote.headRef}`,
1049
+ options.branchName,
1050
+ ], { cwd: options.cwd });
1051
+ }
1052
+ function validateWorktreeBranchName(branchName) {
1053
+ const validation = validateBranchSlug(branchName);
1054
+ if (!validation.valid) {
1055
+ throw new Error(`Invalid branch name: ${validation.error}`);
1056
+ }
1057
+ }
1058
+ async function validateExistingWorktreeBranchName(cwd, branchName) {
1059
+ const result = await runGitCommand(["check-ref-format", "--branch", branchName], {
1060
+ cwd,
1061
+ timeout: 30000,
1062
+ acceptExitCodes: [0, 1, 128],
1063
+ });
1064
+ if (result.exitCode !== 0) {
1065
+ throw new InvalidGitBranchNameError(branchName);
1066
+ }
1067
+ }
1068
+ function normalizeRequiredBaseBranch(baseBranch) {
1069
+ const normalizedBaseBranch = normalizeBaseRefName(baseBranch);
1070
+ if (!normalizedBaseBranch) {
1071
+ throw new Error("Base branch is required when creating a Otto worktree");
1072
+ }
1073
+ if (normalizedBaseBranch === "HEAD") {
1074
+ throw new Error("Base branch cannot be HEAD when creating a Otto worktree");
1075
+ }
1076
+ return normalizedBaseBranch;
1077
+ }
1078
+ async function resolveBaseBranchForWorktree(cwd, normalizedBaseBranch) {
1079
+ try {
1080
+ await runGitCommand(["rev-parse", "--verify", `origin/${normalizedBaseBranch}`], { cwd });
1081
+ return `origin/${normalizedBaseBranch}`;
1082
+ }
1083
+ catch {
1084
+ try {
1085
+ await runGitCommand(["rev-parse", "--verify", normalizedBaseBranch], { cwd });
1086
+ return normalizedBaseBranch;
1087
+ }
1088
+ catch {
1089
+ throw new Error(`Base branch not found: ${normalizedBaseBranch}`);
1090
+ }
1091
+ }
1092
+ }
1093
+ async function localBranchExists(cwd, branchName) {
1094
+ try {
1095
+ await runGitCommand(["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`], {
1096
+ cwd,
1097
+ });
1098
+ return true;
1099
+ }
1100
+ catch {
1101
+ return false;
1102
+ }
1103
+ }
1104
+ async function resolveUniqueLocalBranchName(cwd, candidateBranch) {
1105
+ let newBranchName = candidateBranch;
1106
+ let suffix = 1;
1107
+ while (await localBranchExists(cwd, newBranchName)) {
1108
+ newBranchName = `${candidateBranch}-${suffix}`;
1109
+ suffix++;
1110
+ }
1111
+ return newBranchName;
1112
+ }
1113
+ async function isBranchCheckedOut(cwd, branchName) {
1114
+ const { stdout } = await runGitCommand(["worktree", "list", "--porcelain"], {
1115
+ cwd,
1116
+ envOverlay: READ_ONLY_GIT_ENV,
1117
+ });
1118
+ return parseWorktreeList(stdout).some((entry) => entry.branchName === branchName);
1119
+ }
1120
+ //# sourceMappingURL=worktree.js.map