@alan-ai-hq/agent-manager 0.1.113 → 0.1.115

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 (655) hide show
  1. package/LICENSE +88 -0
  2. package/dist/__tests__/binding-switch-git.test.d.ts +2 -0
  3. package/dist/__tests__/binding-switch-git.test.d.ts.map +1 -0
  4. package/dist/__tests__/binding-switch-git.test.js +555 -0
  5. package/dist/__tests__/binding-switch-git.test.js.map +1 -0
  6. package/dist/__tests__/cli-ensure-install.test.d.ts +2 -0
  7. package/dist/__tests__/cli-ensure-install.test.d.ts.map +1 -0
  8. package/dist/__tests__/cli-ensure-install.test.js +177 -0
  9. package/dist/__tests__/cli-ensure-install.test.js.map +1 -0
  10. package/dist/__tests__/cli-executable.test.d.ts +2 -0
  11. package/dist/__tests__/cli-executable.test.d.ts.map +1 -0
  12. package/dist/__tests__/cli-executable.test.js +155 -0
  13. package/dist/__tests__/cli-executable.test.js.map +1 -0
  14. package/dist/__tests__/cli-executable.windows.test.d.ts +2 -0
  15. package/dist/__tests__/cli-executable.windows.test.d.ts.map +1 -0
  16. package/dist/__tests__/cli-executable.windows.test.js +123 -0
  17. package/dist/__tests__/cli-executable.windows.test.js.map +1 -0
  18. package/dist/__tests__/cli-help.test.d.ts +2 -0
  19. package/dist/__tests__/cli-help.test.d.ts.map +1 -0
  20. package/dist/__tests__/cli-help.test.js +47 -0
  21. package/dist/__tests__/cli-help.test.js.map +1 -0
  22. package/dist/__tests__/computer-readiness.test.d.ts +2 -0
  23. package/dist/__tests__/computer-readiness.test.d.ts.map +1 -0
  24. package/dist/__tests__/computer-readiness.test.js +63 -0
  25. package/dist/__tests__/computer-readiness.test.js.map +1 -0
  26. package/dist/__tests__/core-agent-provider-auth-env.test.d.ts +2 -0
  27. package/dist/__tests__/core-agent-provider-auth-env.test.d.ts.map +1 -0
  28. package/dist/__tests__/core-agent-provider-auth-env.test.js +93 -0
  29. package/dist/__tests__/core-agent-provider-auth-env.test.js.map +1 -0
  30. package/dist/__tests__/core-agent-workflow-context.test.d.ts +2 -0
  31. package/dist/__tests__/core-agent-workflow-context.test.d.ts.map +1 -0
  32. package/dist/__tests__/core-agent-workflow-context.test.js +139 -0
  33. package/dist/__tests__/core-agent-workflow-context.test.js.map +1 -0
  34. package/dist/__tests__/daemon-native-hooks.test.d.ts +2 -0
  35. package/dist/__tests__/daemon-native-hooks.test.d.ts.map +1 -0
  36. package/dist/__tests__/daemon-native-hooks.test.js +94 -0
  37. package/dist/__tests__/daemon-native-hooks.test.js.map +1 -0
  38. package/dist/__tests__/daemon-reconcile-ask.test.d.ts +2 -0
  39. package/dist/__tests__/daemon-reconcile-ask.test.d.ts.map +1 -0
  40. package/dist/__tests__/daemon-reconcile-ask.test.js +100 -0
  41. package/dist/__tests__/daemon-reconcile-ask.test.js.map +1 -0
  42. package/dist/__tests__/daemon-runner-status.test.d.ts +2 -0
  43. package/dist/__tests__/daemon-runner-status.test.d.ts.map +1 -0
  44. package/dist/__tests__/daemon-runner-status.test.js +102 -0
  45. package/dist/__tests__/daemon-runner-status.test.js.map +1 -0
  46. package/dist/__tests__/daemon-socket.integration.test.d.ts +2 -0
  47. package/dist/__tests__/daemon-socket.integration.test.d.ts.map +1 -0
  48. package/dist/__tests__/daemon-socket.integration.test.js +435 -0
  49. package/dist/__tests__/daemon-socket.integration.test.js.map +1 -0
  50. package/dist/__tests__/daemon.test.d.ts +2 -0
  51. package/dist/__tests__/daemon.test.d.ts.map +1 -0
  52. package/dist/__tests__/daemon.test.js +4884 -0
  53. package/dist/__tests__/daemon.test.js.map +1 -0
  54. package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts +2 -0
  55. package/dist/__tests__/ensure-shared-checkout-branch.test.d.ts.map +1 -0
  56. package/dist/__tests__/ensure-shared-checkout-branch.test.js +129 -0
  57. package/dist/__tests__/ensure-shared-checkout-branch.test.js.map +1 -0
  58. package/dist/__tests__/event-journal-stress.test.d.ts +2 -0
  59. package/dist/__tests__/event-journal-stress.test.d.ts.map +1 -0
  60. package/dist/__tests__/event-journal-stress.test.js +124 -0
  61. package/dist/__tests__/event-journal-stress.test.js.map +1 -0
  62. package/dist/__tests__/event-journal.test.d.ts +2 -0
  63. package/dist/__tests__/event-journal.test.d.ts.map +1 -0
  64. package/dist/__tests__/event-journal.test.js +264 -0
  65. package/dist/__tests__/event-journal.test.js.map +1 -0
  66. package/dist/__tests__/event-outbox-persist-failure.test.d.ts +2 -0
  67. package/dist/__tests__/event-outbox-persist-failure.test.d.ts.map +1 -0
  68. package/dist/__tests__/event-outbox-persist-failure.test.js +143 -0
  69. package/dist/__tests__/event-outbox-persist-failure.test.js.map +1 -0
  70. package/dist/__tests__/event-outbox.test.d.ts +2 -0
  71. package/dist/__tests__/event-outbox.test.d.ts.map +1 -0
  72. package/dist/__tests__/event-outbox.test.js +602 -0
  73. package/dist/__tests__/event-outbox.test.js.map +1 -0
  74. package/dist/__tests__/execution-activity-tracker.test.d.ts +2 -0
  75. package/dist/__tests__/execution-activity-tracker.test.d.ts.map +1 -0
  76. package/dist/__tests__/execution-activity-tracker.test.js +64 -0
  77. package/dist/__tests__/execution-activity-tracker.test.js.map +1 -0
  78. package/dist/__tests__/execution-lease-client.test.d.ts +2 -0
  79. package/dist/__tests__/execution-lease-client.test.d.ts.map +1 -0
  80. package/dist/__tests__/execution-lease-client.test.js +274 -0
  81. package/dist/__tests__/execution-lease-client.test.js.map +1 -0
  82. package/dist/__tests__/fake-provider-cli.test.d.ts +2 -0
  83. package/dist/__tests__/fake-provider-cli.test.d.ts.map +1 -0
  84. package/dist/__tests__/fake-provider-cli.test.js +46 -0
  85. package/dist/__tests__/fake-provider-cli.test.js.map +1 -0
  86. package/dist/__tests__/generated-images.test.d.ts +2 -0
  87. package/dist/__tests__/generated-images.test.d.ts.map +1 -0
  88. package/dist/__tests__/generated-images.test.js +132 -0
  89. package/dist/__tests__/generated-images.test.js.map +1 -0
  90. package/dist/__tests__/helpers/sandbox-outbox.d.ts +3 -0
  91. package/dist/__tests__/helpers/sandbox-outbox.d.ts.map +1 -0
  92. package/dist/__tests__/helpers/sandbox-outbox.js +23 -0
  93. package/dist/__tests__/helpers/sandbox-outbox.js.map +1 -0
  94. package/dist/__tests__/install-command.test.d.ts +2 -0
  95. package/dist/__tests__/install-command.test.d.ts.map +1 -0
  96. package/dist/__tests__/install-command.test.js +185 -0
  97. package/dist/__tests__/install-command.test.js.map +1 -0
  98. package/dist/__tests__/integration-cli.test.d.ts +2 -0
  99. package/dist/__tests__/integration-cli.test.d.ts.map +1 -0
  100. package/dist/__tests__/integration-cli.test.js +150 -0
  101. package/dist/__tests__/integration-cli.test.js.map +1 -0
  102. package/dist/__tests__/lifecycle-contracts.test.d.ts +2 -0
  103. package/dist/__tests__/lifecycle-contracts.test.d.ts.map +1 -0
  104. package/dist/__tests__/lifecycle-contracts.test.js +66 -0
  105. package/dist/__tests__/lifecycle-contracts.test.js.map +1 -0
  106. package/dist/__tests__/lifecycle-logger.test.d.ts +2 -0
  107. package/dist/__tests__/lifecycle-logger.test.d.ts.map +1 -0
  108. package/dist/__tests__/lifecycle-logger.test.js +49 -0
  109. package/dist/__tests__/lifecycle-logger.test.js.map +1 -0
  110. package/dist/__tests__/local-daemon-lifecycle.test.d.ts +2 -0
  111. package/dist/__tests__/local-daemon-lifecycle.test.d.ts.map +1 -0
  112. package/dist/__tests__/local-daemon-lifecycle.test.js +594 -0
  113. package/dist/__tests__/local-daemon-lifecycle.test.js.map +1 -0
  114. package/dist/__tests__/local-git-status.test.d.ts +2 -0
  115. package/dist/__tests__/local-git-status.test.d.ts.map +1 -0
  116. package/dist/__tests__/local-git-status.test.js +31 -0
  117. package/dist/__tests__/local-git-status.test.js.map +1 -0
  118. package/dist/__tests__/mcp-config-adapters-files.test.d.ts +2 -0
  119. package/dist/__tests__/mcp-config-adapters-files.test.d.ts.map +1 -0
  120. package/dist/__tests__/mcp-config-adapters-files.test.js +486 -0
  121. package/dist/__tests__/mcp-config-adapters-files.test.js.map +1 -0
  122. package/dist/__tests__/mcp-config-adapters.test.d.ts +2 -0
  123. package/dist/__tests__/mcp-config-adapters.test.d.ts.map +1 -0
  124. package/dist/__tests__/mcp-config-adapters.test.js +492 -0
  125. package/dist/__tests__/mcp-config-adapters.test.js.map +1 -0
  126. package/dist/__tests__/mcp-sync.test.d.ts +2 -0
  127. package/dist/__tests__/mcp-sync.test.d.ts.map +1 -0
  128. package/dist/__tests__/mcp-sync.test.js +21 -0
  129. package/dist/__tests__/mcp-sync.test.js.map +1 -0
  130. package/dist/__tests__/model-scan-runner.test.d.ts +2 -0
  131. package/dist/__tests__/model-scan-runner.test.d.ts.map +1 -0
  132. package/dist/__tests__/model-scan-runner.test.js +80 -0
  133. package/dist/__tests__/model-scan-runner.test.js.map +1 -0
  134. package/dist/__tests__/native-hook-command.test.d.ts +2 -0
  135. package/dist/__tests__/native-hook-command.test.d.ts.map +1 -0
  136. package/dist/__tests__/native-hook-command.test.js +386 -0
  137. package/dist/__tests__/native-hook-command.test.js.map +1 -0
  138. package/dist/__tests__/native-hook-config.test.d.ts +2 -0
  139. package/dist/__tests__/native-hook-config.test.d.ts.map +1 -0
  140. package/dist/__tests__/native-hook-config.test.js +374 -0
  141. package/dist/__tests__/native-hook-config.test.js.map +1 -0
  142. package/dist/__tests__/native-hook-drain.test.d.ts +2 -0
  143. package/dist/__tests__/native-hook-drain.test.d.ts.map +1 -0
  144. package/dist/__tests__/native-hook-drain.test.js +197 -0
  145. package/dist/__tests__/native-hook-drain.test.js.map +1 -0
  146. package/dist/__tests__/native-hook-inbox.test.d.ts +2 -0
  147. package/dist/__tests__/native-hook-inbox.test.d.ts.map +1 -0
  148. package/dist/__tests__/native-hook-inbox.test.js +139 -0
  149. package/dist/__tests__/native-hook-inbox.test.js.map +1 -0
  150. package/dist/__tests__/native-session.test.d.ts +2 -0
  151. package/dist/__tests__/native-session.test.d.ts.map +1 -0
  152. package/dist/__tests__/native-session.test.js +41 -0
  153. package/dist/__tests__/native-session.test.js.map +1 -0
  154. package/dist/__tests__/native-stream-outbox.test.d.ts +2 -0
  155. package/dist/__tests__/native-stream-outbox.test.d.ts.map +1 -0
  156. package/dist/__tests__/native-stream-outbox.test.js +231 -0
  157. package/dist/__tests__/native-stream-outbox.test.js.map +1 -0
  158. package/dist/__tests__/native-stream-platform.test.d.ts +2 -0
  159. package/dist/__tests__/native-stream-platform.test.d.ts.map +1 -0
  160. package/dist/__tests__/native-stream-platform.test.js +20 -0
  161. package/dist/__tests__/native-stream-platform.test.js.map +1 -0
  162. package/dist/__tests__/native-transcript-cursor.test.d.ts +2 -0
  163. package/dist/__tests__/native-transcript-cursor.test.d.ts.map +1 -0
  164. package/dist/__tests__/native-transcript-cursor.test.js +60 -0
  165. package/dist/__tests__/native-transcript-cursor.test.js.map +1 -0
  166. package/dist/__tests__/native-transcript-stream.test.d.ts +2 -0
  167. package/dist/__tests__/native-transcript-stream.test.d.ts.map +1 -0
  168. package/dist/__tests__/native-transcript-stream.test.js +378 -0
  169. package/dist/__tests__/native-transcript-stream.test.js.map +1 -0
  170. package/dist/__tests__/network-diagnostics.test.d.ts +2 -0
  171. package/dist/__tests__/network-diagnostics.test.d.ts.map +1 -0
  172. package/dist/__tests__/network-diagnostics.test.js +26 -0
  173. package/dist/__tests__/network-diagnostics.test.js.map +1 -0
  174. package/dist/__tests__/observable-map.test.d.ts +2 -0
  175. package/dist/__tests__/observable-map.test.d.ts.map +1 -0
  176. package/dist/__tests__/observable-map.test.js +54 -0
  177. package/dist/__tests__/observable-map.test.js.map +1 -0
  178. package/dist/__tests__/outbox-baseline.bench.test.d.ts +2 -0
  179. package/dist/__tests__/outbox-baseline.bench.test.d.ts.map +1 -0
  180. package/dist/__tests__/outbox-baseline.bench.test.js +108 -0
  181. package/dist/__tests__/outbox-baseline.bench.test.js.map +1 -0
  182. package/dist/__tests__/provider-auth-preflight.test.d.ts +2 -0
  183. package/dist/__tests__/provider-auth-preflight.test.d.ts.map +1 -0
  184. package/dist/__tests__/provider-auth-preflight.test.js +123 -0
  185. package/dist/__tests__/provider-auth-preflight.test.js.map +1 -0
  186. package/dist/__tests__/provider-model-discovery.test.d.ts +2 -0
  187. package/dist/__tests__/provider-model-discovery.test.d.ts.map +1 -0
  188. package/dist/__tests__/provider-model-discovery.test.js +1071 -0
  189. package/dist/__tests__/provider-model-discovery.test.js.map +1 -0
  190. package/dist/__tests__/resource-diagnostics.test.d.ts +2 -0
  191. package/dist/__tests__/resource-diagnostics.test.d.ts.map +1 -0
  192. package/dist/__tests__/resource-diagnostics.test.js +138 -0
  193. package/dist/__tests__/resource-diagnostics.test.js.map +1 -0
  194. package/dist/__tests__/resume-fallback-env.test.d.ts +2 -0
  195. package/dist/__tests__/resume-fallback-env.test.d.ts.map +1 -0
  196. package/dist/__tests__/resume-fallback-env.test.js +28 -0
  197. package/dist/__tests__/resume-fallback-env.test.js.map +1 -0
  198. package/dist/__tests__/run-journal.test.d.ts +2 -0
  199. package/dist/__tests__/run-journal.test.d.ts.map +1 -0
  200. package/dist/__tests__/run-journal.test.js +121 -0
  201. package/dist/__tests__/run-journal.test.js.map +1 -0
  202. package/dist/__tests__/run-start-gate.test.d.ts +2 -0
  203. package/dist/__tests__/run-start-gate.test.d.ts.map +1 -0
  204. package/dist/__tests__/run-start-gate.test.js +18 -0
  205. package/dist/__tests__/run-start-gate.test.js.map +1 -0
  206. package/dist/__tests__/runtime-capabilities-sync.test.d.ts +2 -0
  207. package/dist/__tests__/runtime-capabilities-sync.test.d.ts.map +1 -0
  208. package/dist/__tests__/runtime-capabilities-sync.test.js +66 -0
  209. package/dist/__tests__/runtime-capabilities-sync.test.js.map +1 -0
  210. package/dist/__tests__/runtime-config.test.d.ts +2 -0
  211. package/dist/__tests__/runtime-config.test.d.ts.map +1 -0
  212. package/dist/__tests__/runtime-config.test.js +137 -0
  213. package/dist/__tests__/runtime-config.test.js.map +1 -0
  214. package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts +2 -0
  215. package/dist/__tests__/runtime-presenter-heartbeat.test.d.ts.map +1 -0
  216. package/dist/__tests__/runtime-presenter-heartbeat.test.js +253 -0
  217. package/dist/__tests__/runtime-presenter-heartbeat.test.js.map +1 -0
  218. package/dist/__tests__/runtime-registration.test.d.ts +2 -0
  219. package/dist/__tests__/runtime-registration.test.d.ts.map +1 -0
  220. package/dist/__tests__/runtime-registration.test.js +109 -0
  221. package/dist/__tests__/runtime-registration.test.js.map +1 -0
  222. package/dist/__tests__/sandbox-outbox-storage.test.d.ts +2 -0
  223. package/dist/__tests__/sandbox-outbox-storage.test.d.ts.map +1 -0
  224. package/dist/__tests__/sandbox-outbox-storage.test.js +81 -0
  225. package/dist/__tests__/sandbox-outbox-storage.test.js.map +1 -0
  226. package/dist/__tests__/sandbox-outbox.test.d.ts +2 -0
  227. package/dist/__tests__/sandbox-outbox.test.d.ts.map +1 -0
  228. package/dist/__tests__/sandbox-outbox.test.js +300 -0
  229. package/dist/__tests__/sandbox-outbox.test.js.map +1 -0
  230. package/dist/__tests__/sandbox-workflow-context.test.d.ts +2 -0
  231. package/dist/__tests__/sandbox-workflow-context.test.d.ts.map +1 -0
  232. package/dist/__tests__/sandbox-workflow-context.test.js +600 -0
  233. package/dist/__tests__/sandbox-workflow-context.test.js.map +1 -0
  234. package/dist/__tests__/service-manager-deadline.test.d.ts +2 -0
  235. package/dist/__tests__/service-manager-deadline.test.d.ts.map +1 -0
  236. package/dist/__tests__/service-manager-deadline.test.js +36 -0
  237. package/dist/__tests__/service-manager-deadline.test.js.map +1 -0
  238. package/dist/__tests__/service-manager.test.d.ts +2 -0
  239. package/dist/__tests__/service-manager.test.d.ts.map +1 -0
  240. package/dist/__tests__/service-manager.test.js +769 -0
  241. package/dist/__tests__/service-manager.test.js.map +1 -0
  242. package/dist/__tests__/service-stop-ownership.test.d.ts +2 -0
  243. package/dist/__tests__/service-stop-ownership.test.d.ts.map +1 -0
  244. package/dist/__tests__/service-stop-ownership.test.js +89 -0
  245. package/dist/__tests__/service-stop-ownership.test.js.map +1 -0
  246. package/dist/__tests__/skill-invocation.test.d.ts +2 -0
  247. package/dist/__tests__/skill-invocation.test.d.ts.map +1 -0
  248. package/dist/__tests__/skill-invocation.test.js +40 -0
  249. package/dist/__tests__/skill-invocation.test.js.map +1 -0
  250. package/dist/__tests__/sleep-inhibitor-real.test.d.ts +2 -0
  251. package/dist/__tests__/sleep-inhibitor-real.test.d.ts.map +1 -0
  252. package/dist/__tests__/sleep-inhibitor-real.test.js +68 -0
  253. package/dist/__tests__/sleep-inhibitor-real.test.js.map +1 -0
  254. package/dist/__tests__/sleep-inhibitor.test.d.ts +2 -0
  255. package/dist/__tests__/sleep-inhibitor.test.d.ts.map +1 -0
  256. package/dist/__tests__/sleep-inhibitor.test.js +236 -0
  257. package/dist/__tests__/sleep-inhibitor.test.js.map +1 -0
  258. package/dist/__tests__/status-local-workspace.test.d.ts +2 -0
  259. package/dist/__tests__/status-local-workspace.test.d.ts.map +1 -0
  260. package/dist/__tests__/status-local-workspace.test.js +121 -0
  261. package/dist/__tests__/status-local-workspace.test.js.map +1 -0
  262. package/dist/__tests__/suspension-detector.test.d.ts +2 -0
  263. package/dist/__tests__/suspension-detector.test.d.ts.map +1 -0
  264. package/dist/__tests__/suspension-detector.test.js +112 -0
  265. package/dist/__tests__/suspension-detector.test.js.map +1 -0
  266. package/dist/__tests__/web-presenter-parent-events.test.d.ts +2 -0
  267. package/dist/__tests__/web-presenter-parent-events.test.d.ts.map +1 -0
  268. package/dist/__tests__/web-presenter-parent-events.test.js +168 -0
  269. package/dist/__tests__/web-presenter-parent-events.test.js.map +1 -0
  270. package/dist/__tests__/workspace-probe-concurrency.test.d.ts +2 -0
  271. package/dist/__tests__/workspace-probe-concurrency.test.d.ts.map +1 -0
  272. package/dist/__tests__/workspace-probe-concurrency.test.js +54 -0
  273. package/dist/__tests__/workspace-probe-concurrency.test.js.map +1 -0
  274. package/dist/__tests__/workspace-relocation.test.d.ts +2 -0
  275. package/dist/__tests__/workspace-relocation.test.d.ts.map +1 -0
  276. package/dist/__tests__/workspace-relocation.test.js +66 -0
  277. package/dist/__tests__/workspace-relocation.test.js.map +1 -0
  278. package/dist/__tests__/workspace-rpc.test.d.ts +2 -0
  279. package/dist/__tests__/workspace-rpc.test.d.ts.map +1 -0
  280. package/dist/__tests__/workspace-rpc.test.js +90 -0
  281. package/dist/__tests__/workspace-rpc.test.js.map +1 -0
  282. package/dist/__tests__/workspace-run-lease.test.d.ts +2 -0
  283. package/dist/__tests__/workspace-run-lease.test.d.ts.map +1 -0
  284. package/dist/__tests__/workspace-run-lease.test.js +331 -0
  285. package/dist/__tests__/workspace-run-lease.test.js.map +1 -0
  286. package/dist/__tests__/ws-client-connection.test.d.ts +2 -0
  287. package/dist/__tests__/ws-client-connection.test.d.ts.map +1 -0
  288. package/dist/__tests__/ws-client-connection.test.js +295 -0
  289. package/dist/__tests__/ws-client-connection.test.js.map +1 -0
  290. package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts +2 -0
  291. package/dist/__tests__/ws-client-heartbeat-volatile.test.d.ts.map +1 -0
  292. package/dist/__tests__/ws-client-heartbeat-volatile.test.js +63 -0
  293. package/dist/__tests__/ws-client-heartbeat-volatile.test.js.map +1 -0
  294. package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts +2 -0
  295. package/dist/__tests__/ws-client-heartbeat.integration.test.d.ts.map +1 -0
  296. package/dist/__tests__/ws-client-heartbeat.integration.test.js +236 -0
  297. package/dist/__tests__/ws-client-heartbeat.integration.test.js.map +1 -0
  298. package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts +2 -0
  299. package/dist/__tests__/ws-client-user-message-ack.integration.test.d.ts.map +1 -0
  300. package/dist/__tests__/ws-client-user-message-ack.integration.test.js +211 -0
  301. package/dist/__tests__/ws-client-user-message-ack.integration.test.js.map +1 -0
  302. package/dist/antigravity-api-key-config.d.ts +2 -0
  303. package/dist/antigravity-api-key-config.d.ts.map +1 -0
  304. package/dist/antigravity-api-key-config.js +79 -0
  305. package/dist/antigravity-api-key-config.js.map +1 -0
  306. package/dist/binding-switch-git.d.ts +26 -0
  307. package/dist/binding-switch-git.d.ts.map +1 -0
  308. package/dist/binding-switch-git.js +871 -0
  309. package/dist/binding-switch-git.js.map +1 -0
  310. package/dist/cli-ensure-install.d.ts +34 -0
  311. package/dist/cli-ensure-install.d.ts.map +1 -0
  312. package/dist/cli-ensure-install.js +154 -0
  313. package/dist/cli-ensure-install.js.map +1 -0
  314. package/dist/cli-executable.d.ts +44 -0
  315. package/dist/cli-executable.d.ts.map +1 -0
  316. package/dist/cli-executable.js +435 -0
  317. package/dist/cli-executable.js.map +1 -0
  318. package/dist/cli-help.d.ts +11 -0
  319. package/dist/cli-help.d.ts.map +1 -0
  320. package/dist/cli-help.js +65 -0
  321. package/dist/cli-help.js.map +1 -0
  322. package/dist/computer-readiness.d.ts +41 -0
  323. package/dist/computer-readiness.d.ts.map +1 -0
  324. package/dist/computer-readiness.js +191 -0
  325. package/dist/computer-readiness.js.map +1 -0
  326. package/dist/core-agent.d.ts +32 -0
  327. package/dist/core-agent.d.ts.map +1 -0
  328. package/dist/core-agent.js +331 -0
  329. package/dist/core-agent.js.map +1 -0
  330. package/dist/daemon-execute.d.ts +42 -0
  331. package/dist/daemon-execute.d.ts.map +1 -0
  332. package/dist/daemon-execute.js +666 -0
  333. package/dist/daemon-execute.js.map +1 -0
  334. package/dist/daemon-helpers.d.ts +150 -0
  335. package/dist/daemon-helpers.d.ts.map +1 -0
  336. package/dist/daemon-helpers.js +157 -0
  337. package/dist/daemon-helpers.js.map +1 -0
  338. package/dist/daemon-local-control.d.ts +208 -0
  339. package/dist/daemon-local-control.d.ts.map +1 -0
  340. package/dist/daemon-local-control.js +826 -0
  341. package/dist/daemon-local-control.js.map +1 -0
  342. package/dist/daemon-local-http.d.ts +57 -0
  343. package/dist/daemon-local-http.d.ts.map +1 -0
  344. package/dist/daemon-local-http.js +375 -0
  345. package/dist/daemon-local-http.js.map +1 -0
  346. package/dist/daemon-native-hooks.d.ts +17 -0
  347. package/dist/daemon-native-hooks.d.ts.map +1 -0
  348. package/dist/daemon-native-hooks.js +54 -0
  349. package/dist/daemon-native-hooks.js.map +1 -0
  350. package/dist/daemon-provider-scan.d.ts +33 -0
  351. package/dist/daemon-provider-scan.d.ts.map +1 -0
  352. package/dist/daemon-provider-scan.js +187 -0
  353. package/dist/daemon-provider-scan.js.map +1 -0
  354. package/dist/daemon-runner-status.d.ts +164 -0
  355. package/dist/daemon-runner-status.d.ts.map +1 -0
  356. package/dist/daemon-runner-status.js +424 -0
  357. package/dist/daemon-runner-status.js.map +1 -0
  358. package/dist/daemon-start.d.ts +5 -0
  359. package/dist/daemon-start.d.ts.map +1 -0
  360. package/dist/daemon-start.js +1313 -0
  361. package/dist/daemon-start.js.map +1 -0
  362. package/dist/daemon-workspace.d.ts +36 -0
  363. package/dist/daemon-workspace.d.ts.map +1 -0
  364. package/dist/daemon-workspace.js +154 -0
  365. package/dist/daemon-workspace.js.map +1 -0
  366. package/dist/daemon.d.ts +59 -0
  367. package/dist/daemon.d.ts.map +1 -0
  368. package/dist/daemon.js +681 -0
  369. package/dist/daemon.js.map +1 -0
  370. package/dist/event-journal-crypto.d.ts +14 -0
  371. package/dist/event-journal-crypto.d.ts.map +1 -0
  372. package/dist/event-journal-crypto.js +89 -0
  373. package/dist/event-journal-crypto.js.map +1 -0
  374. package/dist/event-journal-paths.d.ts +10 -0
  375. package/dist/event-journal-paths.d.ts.map +1 -0
  376. package/dist/event-journal-paths.js +29 -0
  377. package/dist/event-journal-paths.js.map +1 -0
  378. package/dist/event-journal-recovery.d.ts +83 -0
  379. package/dist/event-journal-recovery.d.ts.map +1 -0
  380. package/dist/event-journal-recovery.js +333 -0
  381. package/dist/event-journal-recovery.js.map +1 -0
  382. package/dist/event-journal-types.d.ts +54 -0
  383. package/dist/event-journal-types.d.ts.map +1 -0
  384. package/dist/event-journal-types.js +10 -0
  385. package/dist/event-journal-types.js.map +1 -0
  386. package/dist/event-journal-writer.d.ts +44 -0
  387. package/dist/event-journal-writer.d.ts.map +1 -0
  388. package/dist/event-journal-writer.js +182 -0
  389. package/dist/event-journal-writer.js.map +1 -0
  390. package/dist/event-outbox.d.ts +113 -0
  391. package/dist/event-outbox.d.ts.map +1 -0
  392. package/dist/event-outbox.js +707 -0
  393. package/dist/event-outbox.js.map +1 -0
  394. package/dist/execution-activity-tracker.d.ts +43 -0
  395. package/dist/execution-activity-tracker.d.ts.map +1 -0
  396. package/dist/execution-activity-tracker.js +116 -0
  397. package/dist/execution-activity-tracker.js.map +1 -0
  398. package/dist/execution-lease-client.d.ts +62 -0
  399. package/dist/execution-lease-client.d.ts.map +1 -0
  400. package/dist/execution-lease-client.js +271 -0
  401. package/dist/execution-lease-client.js.map +1 -0
  402. package/dist/fake-provider-cli.d.ts +13 -0
  403. package/dist/fake-provider-cli.d.ts.map +1 -0
  404. package/dist/fake-provider-cli.js +53 -0
  405. package/dist/fake-provider-cli.js.map +1 -0
  406. package/dist/generated-images.d.ts +2 -0
  407. package/dist/generated-images.d.ts.map +1 -0
  408. package/dist/generated-images.js +2 -0
  409. package/dist/generated-images.js.map +1 -0
  410. package/dist/index.cjs +47033 -45514
  411. package/dist/index.d.ts +2 -0
  412. package/dist/index.d.ts.map +1 -0
  413. package/dist/index.js +224 -0
  414. package/dist/index.js.map +1 -0
  415. package/dist/install-command.d.ts +2 -0
  416. package/dist/install-command.d.ts.map +1 -0
  417. package/dist/install-command.js +96 -0
  418. package/dist/install-command.js.map +1 -0
  419. package/dist/integration-cli.d.ts +14 -0
  420. package/dist/integration-cli.d.ts.map +1 -0
  421. package/dist/integration-cli.js +80 -0
  422. package/dist/integration-cli.js.map +1 -0
  423. package/dist/lifecycle-logger.d.ts +25 -0
  424. package/dist/lifecycle-logger.d.ts.map +1 -0
  425. package/dist/lifecycle-logger.js +73 -0
  426. package/dist/lifecycle-logger.js.map +1 -0
  427. package/dist/local-daemon-lifecycle.d.ts +112 -0
  428. package/dist/local-daemon-lifecycle.d.ts.map +1 -0
  429. package/dist/local-daemon-lifecycle.js +433 -0
  430. package/dist/local-daemon-lifecycle.js.map +1 -0
  431. package/dist/local-git-status.d.ts +14 -0
  432. package/dist/local-git-status.d.ts.map +1 -0
  433. package/dist/local-git-status.js +43 -0
  434. package/dist/local-git-status.js.map +1 -0
  435. package/dist/managed-mcp.d.ts +7 -0
  436. package/dist/managed-mcp.d.ts.map +1 -0
  437. package/dist/managed-mcp.js +16 -0
  438. package/dist/managed-mcp.js.map +1 -0
  439. package/dist/mcp-config-adapters.d.ts +57 -0
  440. package/dist/mcp-config-adapters.d.ts.map +1 -0
  441. package/dist/mcp-config-adapters.js +929 -0
  442. package/dist/mcp-config-adapters.js.map +1 -0
  443. package/dist/mcp-sync.d.ts +44 -0
  444. package/dist/mcp-sync.d.ts.map +1 -0
  445. package/dist/mcp-sync.js +68 -0
  446. package/dist/mcp-sync.js.map +1 -0
  447. package/dist/model-scan-runner.d.ts +15 -0
  448. package/dist/model-scan-runner.d.ts.map +1 -0
  449. package/dist/model-scan-runner.js +56 -0
  450. package/dist/model-scan-runner.js.map +1 -0
  451. package/dist/native-hook-command.d.ts +31 -0
  452. package/dist/native-hook-command.d.ts.map +1 -0
  453. package/dist/native-hook-command.js +289 -0
  454. package/dist/native-hook-command.js.map +1 -0
  455. package/dist/native-hook-config.d.ts +43 -0
  456. package/dist/native-hook-config.d.ts.map +1 -0
  457. package/dist/native-hook-config.js +601 -0
  458. package/dist/native-hook-config.js.map +1 -0
  459. package/dist/native-hook-drain.d.ts +34 -0
  460. package/dist/native-hook-drain.d.ts.map +1 -0
  461. package/dist/native-hook-drain.js +83 -0
  462. package/dist/native-hook-drain.js.map +1 -0
  463. package/dist/native-hook-inbox.d.ts +40 -0
  464. package/dist/native-hook-inbox.d.ts.map +1 -0
  465. package/dist/native-hook-inbox.js +217 -0
  466. package/dist/native-hook-inbox.js.map +1 -0
  467. package/dist/native-project-config.d.ts +11 -0
  468. package/dist/native-project-config.d.ts.map +1 -0
  469. package/dist/native-project-config.js +49 -0
  470. package/dist/native-project-config.js.map +1 -0
  471. package/dist/native-session.d.ts +20 -0
  472. package/dist/native-session.d.ts.map +1 -0
  473. package/dist/native-session.js +213 -0
  474. package/dist/native-session.js.map +1 -0
  475. package/dist/native-stream-journal.d.ts +22 -0
  476. package/dist/native-stream-journal.d.ts.map +1 -0
  477. package/dist/native-stream-journal.js +98 -0
  478. package/dist/native-stream-journal.js.map +1 -0
  479. package/dist/native-stream-outbox.d.ts +40 -0
  480. package/dist/native-stream-outbox.d.ts.map +1 -0
  481. package/dist/native-stream-outbox.js +358 -0
  482. package/dist/native-stream-outbox.js.map +1 -0
  483. package/dist/native-stream-platform.d.ts +4 -0
  484. package/dist/native-stream-platform.d.ts.map +1 -0
  485. package/dist/native-stream-platform.js +11 -0
  486. package/dist/native-stream-platform.js.map +1 -0
  487. package/dist/native-transcript-cursor.d.ts +33 -0
  488. package/dist/native-transcript-cursor.d.ts.map +1 -0
  489. package/dist/native-transcript-cursor.js +108 -0
  490. package/dist/native-transcript-cursor.js.map +1 -0
  491. package/dist/native-transcript-stream.d.ts +20 -0
  492. package/dist/native-transcript-stream.d.ts.map +1 -0
  493. package/dist/native-transcript-stream.js +438 -0
  494. package/dist/native-transcript-stream.js.map +1 -0
  495. package/dist/network-diagnostics.d.ts +8 -0
  496. package/dist/network-diagnostics.d.ts.map +1 -0
  497. package/dist/network-diagnostics.js +56 -0
  498. package/dist/network-diagnostics.js.map +1 -0
  499. package/dist/observable-map.d.ts +13 -0
  500. package/dist/observable-map.d.ts.map +1 -0
  501. package/dist/observable-map.js +30 -0
  502. package/dist/observable-map.js.map +1 -0
  503. package/dist/provider-auth-preflight.d.ts +19 -0
  504. package/dist/provider-auth-preflight.d.ts.map +1 -0
  505. package/dist/provider-auth-preflight.js +107 -0
  506. package/dist/provider-auth-preflight.js.map +1 -0
  507. package/dist/provider-model-discovery.d.ts +33 -0
  508. package/dist/provider-model-discovery.d.ts.map +1 -0
  509. package/dist/provider-model-discovery.js +731 -0
  510. package/dist/provider-model-discovery.js.map +1 -0
  511. package/dist/resource-diagnostics.d.ts +21 -0
  512. package/dist/resource-diagnostics.d.ts.map +1 -0
  513. package/dist/resource-diagnostics.js +161 -0
  514. package/dist/resource-diagnostics.js.map +1 -0
  515. package/dist/resume-fallback-env.d.ts +3 -0
  516. package/dist/resume-fallback-env.d.ts.map +1 -0
  517. package/dist/resume-fallback-env.js +14 -0
  518. package/dist/resume-fallback-env.js.map +1 -0
  519. package/dist/run-journal.d.ts +51 -0
  520. package/dist/run-journal.d.ts.map +1 -0
  521. package/dist/run-journal.js +193 -0
  522. package/dist/run-journal.js.map +1 -0
  523. package/dist/runtime-backends.d.ts +2 -0
  524. package/dist/runtime-backends.d.ts.map +1 -0
  525. package/dist/runtime-backends.js +2 -0
  526. package/dist/runtime-backends.js.map +1 -0
  527. package/dist/runtime-capabilities-sync.d.ts +40 -0
  528. package/dist/runtime-capabilities-sync.d.ts.map +1 -0
  529. package/dist/runtime-capabilities-sync.js +56 -0
  530. package/dist/runtime-capabilities-sync.js.map +1 -0
  531. package/dist/runtime-config.d.ts +26 -0
  532. package/dist/runtime-config.d.ts.map +1 -0
  533. package/dist/runtime-config.js +170 -0
  534. package/dist/runtime-config.js.map +1 -0
  535. package/dist/runtime-presenter.d.ts +81 -0
  536. package/dist/runtime-presenter.d.ts.map +1 -0
  537. package/dist/runtime-presenter.js +422 -0
  538. package/dist/runtime-presenter.js.map +1 -0
  539. package/dist/runtime-registration.d.ts +40 -0
  540. package/dist/runtime-registration.d.ts.map +1 -0
  541. package/dist/runtime-registration.js +143 -0
  542. package/dist/runtime-registration.js.map +1 -0
  543. package/dist/sandbox-outbox-storage.d.ts +13 -0
  544. package/dist/sandbox-outbox-storage.d.ts.map +1 -0
  545. package/dist/sandbox-outbox-storage.js +98 -0
  546. package/dist/sandbox-outbox-storage.js.map +1 -0
  547. package/dist/sandbox-outbox.d.ts +115 -0
  548. package/dist/sandbox-outbox.d.ts.map +1 -0
  549. package/dist/sandbox-outbox.js +213 -0
  550. package/dist/sandbox-outbox.js.map +1 -0
  551. package/dist/sandbox.d.ts +34 -0
  552. package/dist/sandbox.d.ts.map +1 -0
  553. package/dist/sandbox.js +469 -0
  554. package/dist/sandbox.js.map +1 -0
  555. package/dist/service-manager.d.ts +113 -0
  556. package/dist/service-manager.d.ts.map +1 -0
  557. package/dist/service-manager.js +1065 -0
  558. package/dist/service-manager.js.map +1 -0
  559. package/dist/skills/__tests__/local-skill-source.test.d.ts +2 -0
  560. package/dist/skills/__tests__/local-skill-source.test.d.ts.map +1 -0
  561. package/dist/skills/__tests__/local-skill-source.test.js +373 -0
  562. package/dist/skills/__tests__/local-skill-source.test.js.map +1 -0
  563. package/dist/skills/__tests__/managed-skill-store.test.d.ts +2 -0
  564. package/dist/skills/__tests__/managed-skill-store.test.d.ts.map +1 -0
  565. package/dist/skills/__tests__/managed-skill-store.test.js +114 -0
  566. package/dist/skills/__tests__/managed-skill-store.test.js.map +1 -0
  567. package/dist/skills/__tests__/runtime-skill-coordinator.test.d.ts +2 -0
  568. package/dist/skills/__tests__/runtime-skill-coordinator.test.d.ts.map +1 -0
  569. package/dist/skills/__tests__/runtime-skill-coordinator.test.js +251 -0
  570. package/dist/skills/__tests__/runtime-skill-coordinator.test.js.map +1 -0
  571. package/dist/skills/__tests__/runtime-skill-manager.test.d.ts +2 -0
  572. package/dist/skills/__tests__/runtime-skill-manager.test.d.ts.map +1 -0
  573. package/dist/skills/__tests__/runtime-skill-manager.test.js +664 -0
  574. package/dist/skills/__tests__/runtime-skill-manager.test.js.map +1 -0
  575. package/dist/skills/__tests__/skill-bundle.test.d.ts +2 -0
  576. package/dist/skills/__tests__/skill-bundle.test.d.ts.map +1 -0
  577. package/dist/skills/__tests__/skill-bundle.test.js +42 -0
  578. package/dist/skills/__tests__/skill-bundle.test.js.map +1 -0
  579. package/dist/skills/__tests__/skill-control-client.test.d.ts +2 -0
  580. package/dist/skills/__tests__/skill-control-client.test.d.ts.map +1 -0
  581. package/dist/skills/__tests__/skill-control-client.test.js +49 -0
  582. package/dist/skills/__tests__/skill-control-client.test.js.map +1 -0
  583. package/dist/skills/__tests__/skill-source-config.test.d.ts +2 -0
  584. package/dist/skills/__tests__/skill-source-config.test.d.ts.map +1 -0
  585. package/dist/skills/__tests__/skill-source-config.test.js +295 -0
  586. package/dist/skills/__tests__/skill-source-config.test.js.map +1 -0
  587. package/dist/skills/local-skill-source.d.ts +77 -0
  588. package/dist/skills/local-skill-source.d.ts.map +1 -0
  589. package/dist/skills/local-skill-source.js +660 -0
  590. package/dist/skills/local-skill-source.js.map +1 -0
  591. package/dist/skills/managed-skill-store.d.ts +44 -0
  592. package/dist/skills/managed-skill-store.d.ts.map +1 -0
  593. package/dist/skills/managed-skill-store.js +160 -0
  594. package/dist/skills/managed-skill-store.js.map +1 -0
  595. package/dist/skills/runtime-skill-coordinator.d.ts +35 -0
  596. package/dist/skills/runtime-skill-coordinator.d.ts.map +1 -0
  597. package/dist/skills/runtime-skill-coordinator.js +166 -0
  598. package/dist/skills/runtime-skill-coordinator.js.map +1 -0
  599. package/dist/skills/runtime-skill-manager.d.ts +89 -0
  600. package/dist/skills/runtime-skill-manager.d.ts.map +1 -0
  601. package/dist/skills/runtime-skill-manager.js +934 -0
  602. package/dist/skills/runtime-skill-manager.js.map +1 -0
  603. package/dist/skills/skill-bundle.d.ts +2 -0
  604. package/dist/skills/skill-bundle.d.ts.map +1 -0
  605. package/dist/skills/skill-bundle.js +2 -0
  606. package/dist/skills/skill-bundle.js.map +1 -0
  607. package/dist/skills/skill-cli.d.ts +2 -0
  608. package/dist/skills/skill-cli.d.ts.map +1 -0
  609. package/dist/skills/skill-cli.js +81 -0
  610. package/dist/skills/skill-cli.js.map +1 -0
  611. package/dist/skills/skill-control-client.d.ts +20 -0
  612. package/dist/skills/skill-control-client.d.ts.map +1 -0
  613. package/dist/skills/skill-control-client.js +56 -0
  614. package/dist/skills/skill-control-client.js.map +1 -0
  615. package/dist/skills/skill-invocation.d.ts +10 -0
  616. package/dist/skills/skill-invocation.d.ts.map +1 -0
  617. package/dist/skills/skill-invocation.js +24 -0
  618. package/dist/skills/skill-invocation.js.map +1 -0
  619. package/dist/sleep-inhibitor.d.ts +32 -0
  620. package/dist/sleep-inhibitor.d.ts.map +1 -0
  621. package/dist/sleep-inhibitor.js +297 -0
  622. package/dist/sleep-inhibitor.js.map +1 -0
  623. package/dist/suspension-detector.d.ts +24 -0
  624. package/dist/suspension-detector.d.ts.map +1 -0
  625. package/dist/suspension-detector.js +59 -0
  626. package/dist/suspension-detector.js.map +1 -0
  627. package/dist/types.d.ts +2 -0
  628. package/dist/types.d.ts.map +1 -0
  629. package/dist/types.js +2 -0
  630. package/dist/types.js.map +1 -0
  631. package/dist/version.d.ts +2 -0
  632. package/dist/version.d.ts.map +1 -0
  633. package/dist/version.js +2 -0
  634. package/dist/version.js.map +1 -0
  635. package/dist/web-presenter.d.ts +52 -0
  636. package/dist/web-presenter.d.ts.map +1 -0
  637. package/dist/web-presenter.js +264 -0
  638. package/dist/web-presenter.js.map +1 -0
  639. package/dist/workspace-relocation.d.ts +22 -0
  640. package/dist/workspace-relocation.d.ts.map +1 -0
  641. package/dist/workspace-relocation.js +90 -0
  642. package/dist/workspace-relocation.js.map +1 -0
  643. package/dist/workspace-rpc.d.ts +2 -0
  644. package/dist/workspace-rpc.d.ts.map +1 -0
  645. package/dist/workspace-rpc.js +15 -0
  646. package/dist/workspace-rpc.js.map +1 -0
  647. package/dist/workspace-run-lease.d.ts +116 -0
  648. package/dist/workspace-run-lease.d.ts.map +1 -0
  649. package/dist/workspace-run-lease.js +320 -0
  650. package/dist/workspace-run-lease.js.map +1 -0
  651. package/dist/ws-client.d.ts +168 -0
  652. package/dist/ws-client.d.ts.map +1 -0
  653. package/dist/ws-client.js +440 -0
  654. package/dist/ws-client.js.map +1 -0
  655. package/package.json +4 -3
package/LICENSE ADDED
@@ -0,0 +1,88 @@
1
+ Alan Code — Proprietary License
2
+
3
+ Copyright (c) 2026 Supatest AI Inc. All rights reserved.
4
+
5
+ This license governs your use of the Alan Code command-line interface and its
6
+ terminal user interface (the "Software"). It does not govern the Alan service
7
+ (the "Service"), which is provided under separate terms.
8
+
9
+ 1. License grant
10
+
11
+ Subject to these terms, Supatest AI Inc. ("we", "us") grants you a
12
+ non-exclusive, non-transferable, non-sublicensable, royalty-free license to
13
+ install and run unmodified copies of the Software, for your internal business
14
+ or personal use, for as long as you comply with this license.
15
+
16
+ 2. Redistribution
17
+
18
+ You may reproduce and redistribute unmodified copies of the Software only if
19
+ all of the following are true:
20
+
21
+ (a) the Software is distributed only in unmodified form;
22
+ (b) it is redistributed solely as part of an application or service that
23
+ provides material functionality beyond the Software itself;
24
+ (c) it is not distributed on a standalone basis or as a primary product;
25
+ (d) you include a copy of this license and retain all copyright, trademark,
26
+ and attribution notices; and
27
+ (e) your application or service is licensed independently of the Software.
28
+
29
+ Nothing in this license restricts your choice of license for your own
30
+ application or service, including distributing it under an open source license.
31
+ This license applies solely to the Software and does not modify or supersede
32
+ the license terms governing your own application.
33
+
34
+ 3. Restrictions
35
+
36
+ This license does not grant you the right to:
37
+
38
+ (a) modify, adapt, translate, or create derivative works of the Software;
39
+ (b) redistribute the Software except as expressly permitted in section 2;
40
+ (c) remove, alter, or obscure any proprietary notices included in the
41
+ Software;
42
+ (d) reverse engineer, decompile, or disassemble the Software, except to the
43
+ extent that restriction is prohibited by applicable law; or
44
+ (e) use our trademarks, logos, or branding except as necessary to identify
45
+ the Software.
46
+
47
+ 4. Reservation of rights
48
+
49
+ We and our licensors retain all right, title, and interest in and to the
50
+ Software. All rights not expressly granted by this license are reserved.
51
+
52
+ 5. The Alan service
53
+
54
+ The Software is a client for the Service and requires a valid Alan account.
55
+ Your use of the Service — including any code, prompts, or other content
56
+ transmitted through it — is governed by the agreement under which you obtained
57
+ that account, not by this license. This license grants no right to access or
58
+ use the Service or any other third-party service.
59
+
60
+ 6. Automatic updates
61
+
62
+ The Software may check for and install updates automatically. By installing and
63
+ running the Software you consent to those updates, which are covered by this
64
+ license. You can turn them off; see the documentation.
65
+
66
+ 7. No warranty
67
+
68
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS,
69
+ IMPLIED, OR STATUTORY, INCLUDING WITHOUT LIMITATION WARRANTIES OF
70
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THE
71
+ ENTIRE RISK ARISING OUT OF USE OF THE SOFTWARE REMAINS WITH YOU.
72
+
73
+ 8. Limitation of liability
74
+
75
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL WE OR OUR LICENSORS
76
+ BE LIABLE FOR ANY DAMAGES ARISING OUT OF OR RELATING TO THIS LICENSE OR THE USE
77
+ OR DISTRIBUTION OF THE SOFTWARE, WHETHER IN CONTRACT, TORT, OR OTHERWISE.
78
+
79
+ 9. Termination
80
+
81
+ This license terminates automatically if you fail to comply with its terms.
82
+ Upon termination you must cease all use and distribution of the Software.
83
+
84
+ 10. Third-party components
85
+
86
+ The Software installs and uses third-party open-source packages, each governed
87
+ by its own license. Those licenses are included with the installed packages and
88
+ are not modified by this license.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=binding-switch-git.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding-switch-git.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/binding-switch-git.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,555 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { chmodSync, existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync, } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { afterEach, describe, expect, it, vi } from "vitest";
6
+ import { executeBindingSwitchGitRpc } from "../binding-switch-git.js";
7
+ const tempDirs = [];
8
+ vi.setConfig({ testTimeout: 20_000 });
9
+ function git(cwd, ...args) {
10
+ return execFileSync("git", args, { cwd, encoding: "utf8" }).trim();
11
+ }
12
+ function makeTempDir() {
13
+ const path = mkdtempSync(join(realpathSync.native(tmpdir()), "alan-binding-switch-git-"));
14
+ tempDirs.push(path);
15
+ return path;
16
+ }
17
+ function configureIdentity(repoPath) {
18
+ git(repoPath, "config", "user.name", "Alan Test");
19
+ git(repoPath, "config", "user.email", "alan-test@example.com");
20
+ }
21
+ function createRepository(root, name) {
22
+ const repoPath = join(root, name);
23
+ mkdirSync(repoPath);
24
+ git(repoPath, "init", "-b", "main");
25
+ configureIdentity(repoPath);
26
+ writeFileSync(join(repoPath, "tracked.txt"), "initial\n");
27
+ git(repoPath, "add", "tracked.txt");
28
+ git(repoPath, "commit", "-m", "Initial commit");
29
+ return repoPath;
30
+ }
31
+ function createRemoteFixture(root) {
32
+ const remotePath = join(root, "remote.git");
33
+ mkdirSync(remotePath);
34
+ git(remotePath, "init", "--bare");
35
+ git(remotePath, "symbolic-ref", "HEAD", "refs/heads/main");
36
+ const seedPath = createRepository(root, "seed");
37
+ git(seedPath, "remote", "add", "origin", remotePath);
38
+ git(seedPath, "push", "-u", "origin", "main");
39
+ const mainSha = git(seedPath, "rev-parse", "HEAD");
40
+ const sourcePath = join(root, "source");
41
+ const targetPath = join(root, "target");
42
+ git(root, "clone", remotePath, sourcePath);
43
+ git(root, "clone", remotePath, targetPath);
44
+ configureIdentity(sourcePath);
45
+ configureIdentity(targetPath);
46
+ return { remotePath, sourcePath, targetPath, mainSha };
47
+ }
48
+ function common(repoPath, suffix = "one") {
49
+ let expectedRemoteUrl;
50
+ try {
51
+ expectedRemoteUrl = git(repoPath, "config", "--get", "remote.origin.url");
52
+ }
53
+ catch {
54
+ expectedRemoteUrl = undefined;
55
+ }
56
+ return {
57
+ switchId: `switch-${suffix}`,
58
+ repoKey: `repo-${suffix}`,
59
+ repoPath,
60
+ projectPath: repoPath,
61
+ expectedRepoRoot: repoPath,
62
+ expectedRemoteUrl,
63
+ expectedBranch: git(repoPath, "branch", "--show-current"),
64
+ };
65
+ }
66
+ async function waitForPath(path, timeoutMs = 5_000) {
67
+ const deadline = Date.now() + timeoutMs;
68
+ while (!existsSync(path)) {
69
+ if (Date.now() >= deadline)
70
+ throw new Error(`Timed out waiting for ${path}`);
71
+ await new Promise((resolvePromise) => setTimeout(resolvePromise, 20));
72
+ }
73
+ }
74
+ afterEach(() => {
75
+ for (const path of tempDirs.splice(0))
76
+ rmSync(path, { recursive: true, force: true });
77
+ });
78
+ describe("binding-switch git RPC", () => {
79
+ it("reports and verifies the repository fetch remote during status inspection", async () => {
80
+ const root = makeTempDir();
81
+ const { remotePath, sourcePath } = createRemoteFixture(root);
82
+ await expect(executeBindingSwitchGitRpc("git.status", common(sourcePath))).resolves.toMatchObject({
83
+ repoRoot: sourcePath,
84
+ remoteUrl: remotePath,
85
+ branch: "main",
86
+ dirty: false,
87
+ });
88
+ });
89
+ it("rejects a mismatched expected remote during status inspection", async () => {
90
+ const root = makeTempDir();
91
+ const { sourcePath } = createRemoteFixture(root);
92
+ const otherRemote = join(root, "other.git");
93
+ mkdirSync(otherRemote);
94
+ git(otherRemote, "init", "--bare");
95
+ await expect(executeBindingSwitchGitRpc("git.status", {
96
+ ...common(sourcePath, "status-remote-mismatch"),
97
+ expectedRemoteUrl: otherRemote,
98
+ })).rejects.toMatchObject({ code: "remote_url_mismatch" });
99
+ });
100
+ it("reports a missing remote without weakening repository path authorization", async () => {
101
+ const root = makeTempDir();
102
+ const repoPath = createRepository(root, "repo-without-remote");
103
+ const { expectedRemoteUrl: _expectedRemoteUrl, ...request } = common(repoPath, "status-no-remote");
104
+ await expect(executeBindingSwitchGitRpc("git.status", request)).resolves.toMatchObject({
105
+ repoRoot: repoPath,
106
+ remoteUrl: null,
107
+ });
108
+ });
109
+ it("rejects credential-bearing remotes during status inspection", async () => {
110
+ const root = makeTempDir();
111
+ const repoPath = createRepository(root, "repo-with-credential-remote");
112
+ git(repoPath, "remote", "add", "origin", "https://user:secret@example.invalid/owner/repo.git");
113
+ const { expectedRemoteUrl: _expectedRemoteUrl, ...request } = common(repoPath, "status-credential-remote");
114
+ await expect(executeBindingSwitchGitRpc("git.status", request)).rejects.toMatchObject({
115
+ code: "remote_url_credentials_rejected",
116
+ });
117
+ });
118
+ it("creates one guarded checkpoint and replays it by switch/repository trailers", async () => {
119
+ const root = makeTempDir();
120
+ const repoPath = createRepository(root, "repo");
121
+ const originalHead = git(repoPath, "rev-parse", "HEAD");
122
+ writeFileSync(join(repoPath, "tracked.txt"), "checkpointed\n");
123
+ writeFileSync(join(repoPath, "untracked.txt"), "new\n");
124
+ const status = (await executeBindingSwitchGitRpc("git.status", common(repoPath)));
125
+ expect(status).toMatchObject({
126
+ headSha: originalHead,
127
+ dirty: true,
128
+ filesChanged: 2,
129
+ });
130
+ expect(status.statusFingerprint).toMatch(/^[0-9a-f]{64}$/);
131
+ const request = {
132
+ ...common(repoPath),
133
+ expectedHeadSha: originalHead,
134
+ expectedStatusFingerprint: status.statusFingerprint,
135
+ expectedProposedTreeSha: status.proposedTreeSha,
136
+ commitMessage: "chore: checkpoint work before environment switch\n\nCo-Authored-By: Alan <agent@tryalan.ai>",
137
+ authorName: "Siddharth Talesara",
138
+ authorEmail: "siddharth@example.com",
139
+ };
140
+ const first = (await executeBindingSwitchGitRpc("git.checkpoint", request));
141
+ expect(first.replayed).toBe(false);
142
+ expect(first.sha).not.toBe(originalHead);
143
+ expect(git(repoPath, "show", "-s", "--format=%B", "HEAD")).toContain("Alan-Switch-Id: switch-one");
144
+ expect(git(repoPath, "show", "-s", "--format=%B", "HEAD")).toContain("Alan-Repository-Id: repo-one");
145
+ expect(git(repoPath, "show", "-s", "--format=%B", "HEAD")).toContain("Co-Authored-By: Alan <agent@tryalan.ai>");
146
+ await expect(executeBindingSwitchGitRpc("git.checkpoint", request)).resolves.toMatchObject({
147
+ sha: first.sha,
148
+ replayed: true,
149
+ });
150
+ writeFileSync(join(repoPath, "tracked.txt"), "changed after checkpoint\n");
151
+ await expect(executeBindingSwitchGitRpc("git.checkpoint", request)).resolves.toMatchObject({
152
+ sha: first.sha,
153
+ replayed: true,
154
+ });
155
+ expect(git(repoPath, "status", "--porcelain")).toContain("tracked.txt");
156
+ });
157
+ it("invalidates approval when bytes change at the same tracked or untracked path", async () => {
158
+ const root = makeTempDir();
159
+ const repoPath = createRepository(root, "repo");
160
+ writeFileSync(join(repoPath, "tracked.txt"), "first tracked bytes\n");
161
+ writeFileSync(join(repoPath, "untracked.txt"), "first untracked bytes\n");
162
+ const first = (await executeBindingSwitchGitRpc("git.status", common(repoPath)));
163
+ writeFileSync(join(repoPath, "tracked.txt"), "second tracked bytes\n");
164
+ writeFileSync(join(repoPath, "untracked.txt"), "second untracked bytes\n");
165
+ const second = (await executeBindingSwitchGitRpc("git.status", common(repoPath)));
166
+ expect(second.statusFingerprint).not.toBe(first.statusFingerprint);
167
+ await expect(executeBindingSwitchGitRpc("git.checkpoint", {
168
+ ...common(repoPath),
169
+ expectedHeadSha: first.headSha,
170
+ expectedStatusFingerprint: first.statusFingerprint,
171
+ expectedProposedTreeSha: first.proposedTreeSha,
172
+ commitMessage: "checkpoint",
173
+ authorName: "Alan",
174
+ authorEmail: "agent@tryalan.ai",
175
+ })).rejects.toMatchObject({ code: "source_changed_since_approval" });
176
+ });
177
+ it("commits only the approved proposed tree when bytes change during preparation", async () => {
178
+ const root = makeTempDir();
179
+ const repoPath = createRepository(root, "checkpoint-race");
180
+ writeFileSync(join(repoPath, "tracked.txt"), "approved checkpoint bytes\n");
181
+ const inspected = (await executeBindingSwitchGitRpc("git.status", common(repoPath, "checkpoint-race")));
182
+ const barrierDir = join(root, "checkpoint-barrier");
183
+ const previousBarrier = process.env.ALAN_TEST_GIT_CHECKPOINT_BARRIER_DIR;
184
+ process.env.ALAN_TEST_GIT_CHECKPOINT_BARRIER_DIR = barrierDir;
185
+ try {
186
+ const checkpointPromise = executeBindingSwitchGitRpc("git.checkpoint", {
187
+ ...common(repoPath, "checkpoint-race"),
188
+ expectedHeadSha: inspected.headSha,
189
+ expectedStatusFingerprint: inspected.statusFingerprint,
190
+ expectedProposedTreeSha: inspected.proposedTreeSha,
191
+ commitMessage: "approved checkpoint",
192
+ authorName: "Alan",
193
+ authorEmail: "agent@tryalan.ai",
194
+ });
195
+ await waitForPath(join(barrierDir, "ready"));
196
+ writeFileSync(join(repoPath, "tracked.txt"), "post-approval bytes\n");
197
+ writeFileSync(join(barrierDir, "release"), "release\n");
198
+ const result = (await checkpointPromise);
199
+ expect(result.replayed).toBe(false);
200
+ expect(git(repoPath, "rev-parse", `${result.sha}^{tree}`)).toBe(inspected.proposedTreeSha);
201
+ expect(git(repoPath, "show", `${result.sha}:tracked.txt`)).toBe("approved checkpoint bytes");
202
+ expect(git(repoPath, "status", "--porcelain")).toContain("tracked.txt");
203
+ }
204
+ finally {
205
+ mkdirSync(barrierDir, { recursive: true });
206
+ writeFileSync(join(barrierDir, "release"), "release\n");
207
+ if (previousBarrier === undefined) {
208
+ delete process.env.ALAN_TEST_GIT_CHECKPOINT_BARRIER_DIR;
209
+ }
210
+ else {
211
+ process.env.ALAN_TEST_GIT_CHECKPOINT_BARRIER_DIR = previousBarrier;
212
+ }
213
+ }
214
+ });
215
+ it("leaves both branches and the new branch index intact when HEAD changes during finalization", async () => {
216
+ const root = makeTempDir();
217
+ const repoPath = createRepository(root, "checkpoint-branch-race");
218
+ const originalHead = git(repoPath, "rev-parse", "HEAD");
219
+ git(repoPath, "branch", "other-checkpoint", originalHead);
220
+ writeFileSync(join(repoPath, "tracked.txt"), "approved checkpoint bytes\n");
221
+ const inspected = (await executeBindingSwitchGitRpc("git.status", common(repoPath, "checkpoint-branch-race")));
222
+ const barrierDir = join(root, "checkpoint-finalize-barrier");
223
+ const previousBarrier = process.env.ALAN_TEST_GIT_CHECKPOINT_FINALIZE_BARRIER_DIR;
224
+ process.env.ALAN_TEST_GIT_CHECKPOINT_FINALIZE_BARRIER_DIR = barrierDir;
225
+ try {
226
+ const checkpointPromise = executeBindingSwitchGitRpc("git.checkpoint", {
227
+ ...common(repoPath, "checkpoint-branch-race"),
228
+ expectedHeadSha: inspected.headSha,
229
+ expectedStatusFingerprint: inspected.statusFingerprint,
230
+ expectedProposedTreeSha: inspected.proposedTreeSha,
231
+ commitMessage: "approved checkpoint",
232
+ authorName: "Alan",
233
+ authorEmail: "agent@tryalan.ai",
234
+ });
235
+ await waitForPath(join(barrierDir, "ready"));
236
+ git(repoPath, "switch", "other-checkpoint");
237
+ writeFileSync(join(barrierDir, "release"), "release\n");
238
+ await expect(checkpointPromise).rejects.toMatchObject({
239
+ code: "source_changed_since_approval",
240
+ });
241
+ expect(git(repoPath, "rev-parse", "refs/heads/main")).toBe(originalHead);
242
+ expect(git(repoPath, "rev-parse", "refs/heads/other-checkpoint")).toBe(originalHead);
243
+ expect(git(repoPath, "branch", "--show-current")).toBe("other-checkpoint");
244
+ expect(git(repoPath, "rev-parse", "HEAD")).toBe(originalHead);
245
+ expect(git(repoPath, "diff", "--cached", "--name-only")).toBe("");
246
+ expect(git(repoPath, "status", "--porcelain")).toBe("M tracked.txt");
247
+ expect(readFileSync(join(repoPath, "tracked.txt"), "utf8")).toBe("approved checkpoint bytes\n");
248
+ }
249
+ finally {
250
+ mkdirSync(barrierDir, { recursive: true });
251
+ writeFileSync(join(barrierDir, "release"), "release\n");
252
+ if (previousBarrier === undefined) {
253
+ delete process.env.ALAN_TEST_GIT_CHECKPOINT_FINALIZE_BARRIER_DIR;
254
+ }
255
+ else {
256
+ process.env.ALAN_TEST_GIT_CHECKPOINT_FINALIZE_BARRIER_DIR = previousBarrier;
257
+ }
258
+ }
259
+ });
260
+ it("rejects checkpoint and push when the branch changes at the same HEAD", async () => {
261
+ const root = makeTempDir();
262
+ const checkpointRepo = createRepository(root, "checkpoint");
263
+ writeFileSync(join(checkpointRepo, "tracked.txt"), "dirty on main\n");
264
+ const inspected = (await executeBindingSwitchGitRpc("git.status", common(checkpointRepo, "same-sha-checkpoint")));
265
+ git(checkpointRepo, "switch", "-c", "other-checkpoint");
266
+ expect(git(checkpointRepo, "rev-parse", "HEAD")).toBe(inspected.headSha);
267
+ await expect(executeBindingSwitchGitRpc("git.checkpoint", {
268
+ ...common(checkpointRepo, "same-sha-checkpoint"),
269
+ expectedBranch: "main",
270
+ expectedHeadSha: inspected.headSha,
271
+ expectedStatusFingerprint: inspected.statusFingerprint,
272
+ expectedProposedTreeSha: inspected.proposedTreeSha,
273
+ commitMessage: "must not commit another branch",
274
+ authorName: "Alan",
275
+ authorEmail: "agent@tryalan.ai",
276
+ })).rejects.toMatchObject({ code: "source_changed_since_approval" });
277
+ const { sourcePath } = createRemoteFixture(root);
278
+ const approvedHead = git(sourcePath, "rev-parse", "HEAD");
279
+ git(sourcePath, "switch", "-c", "other-push");
280
+ expect(git(sourcePath, "rev-parse", "HEAD")).toBe(approvedHead);
281
+ await expect(executeBindingSwitchGitRpc("git.push", {
282
+ ...common(sourcePath, "same-sha-push"),
283
+ expectedBranch: "main",
284
+ expectedHeadSha: approvedHead,
285
+ branch: "main",
286
+ })).rejects.toMatchObject({ code: "source_changed_since_approval" });
287
+ });
288
+ it("publishes the source branch and lands a different bootstrap checkout at the exact SHA", async () => {
289
+ const root = makeTempDir();
290
+ const { remotePath, sourcePath, targetPath } = createRemoteFixture(root);
291
+ git(sourcePath, "switch", "-c", "task/migrate");
292
+ writeFileSync(join(sourcePath, "tracked.txt"), "source task work\n");
293
+ git(sourcePath, "commit", "-am", "Task work");
294
+ const pushedSha = git(sourcePath, "rev-parse", "HEAD");
295
+ expect(await executeBindingSwitchGitRpc("git.push", {
296
+ ...common(sourcePath),
297
+ expectedHeadSha: pushedSha,
298
+ branch: "task/migrate",
299
+ expectedRemoteUrl: `file://${remotePath}`,
300
+ })).toMatchObject({
301
+ pushedSha,
302
+ branch: "task/migrate",
303
+ replayed: false,
304
+ });
305
+ expect(git(targetPath, "branch", "--show-current")).toBe("main");
306
+ const prepared = await executeBindingSwitchGitRpc("git.prepare_checkout", {
307
+ ...common(targetPath),
308
+ branch: "task/migrate",
309
+ targetSha: pushedSha,
310
+ });
311
+ expect(prepared).toMatchObject({
312
+ path: targetPath,
313
+ branch: "task/migrate",
314
+ headSha: pushedSha,
315
+ replayed: false,
316
+ });
317
+ expect(git(targetPath, "branch", "--show-current")).toBe("task/migrate");
318
+ expect(git(targetPath, "rev-parse", "HEAD")).toBe(pushedSha);
319
+ expect(await executeBindingSwitchGitRpc("git.prepare_checkout", {
320
+ ...common(targetPath),
321
+ branch: "task/migrate",
322
+ targetSha: pushedSha,
323
+ })).toMatchObject({ headSha: pushedSha, replayed: true });
324
+ expect(await executeBindingSwitchGitRpc("git.verify_head", {
325
+ ...common(targetPath),
326
+ expectedSha: pushedSha,
327
+ })).toMatchObject({ headSha: pushedSha, verified: true });
328
+ });
329
+ it("rejects verification of a dirty target even when HEAD is exact", async () => {
330
+ const root = makeTempDir();
331
+ const repoPath = createRepository(root, "dirty-verify");
332
+ const expectedSha = git(repoPath, "rev-parse", "HEAD");
333
+ writeFileSync(join(repoPath, "late-target-edit.txt"), "must block verification\n");
334
+ await expect(executeBindingSwitchGitRpc("git.verify_head", {
335
+ ...common(repoPath, "dirty-verify"),
336
+ expectedSha,
337
+ })).rejects.toMatchObject({ code: "target_checkout_dirty" });
338
+ }, 60_000);
339
+ it("inspects an existing external linked checkout without managing its lifecycle", async () => {
340
+ const root = makeTempDir();
341
+ const projectPath = createRepository(root, "project");
342
+ const linkedPath = join(root, "external-checkout");
343
+ git(projectPath, "worktree", "add", "-b", "feature/external", linkedPath);
344
+ writeFileSync(join(linkedPath, "preserve.txt"), "user work\n");
345
+ await expect(executeBindingSwitchGitRpc("git.status", {
346
+ ...common(linkedPath),
347
+ projectPath,
348
+ })).resolves.toMatchObject({ repoRoot: linkedPath, branch: "feature/external", dirty: true });
349
+ expect(readFileSync(join(linkedPath, "preserve.txt"), "utf8")).toBe("user work\n");
350
+ });
351
+ it("rejects an arbitrary repository root even when its path is otherwise valid", async () => {
352
+ const root = makeTempDir();
353
+ const trustedProject = createRepository(root, "trusted");
354
+ const arbitraryRepo = createRepository(root, "arbitrary");
355
+ writeFileSync(join(arbitraryRepo, "tracked.txt"), "arbitrary dirt\n");
356
+ const status = (await executeBindingSwitchGitRpc("git.status", common(arbitraryRepo, "arbitrary")));
357
+ await expect(executeBindingSwitchGitRpc("git.checkpoint", {
358
+ ...common(arbitraryRepo, "arbitrary"),
359
+ projectPath: trustedProject,
360
+ expectedRepoRoot: arbitraryRepo,
361
+ expectedHeadSha: status.headSha,
362
+ expectedStatusFingerprint: status.statusFingerprint,
363
+ expectedProposedTreeSha: status.proposedTreeSha,
364
+ commitMessage: "must not commit",
365
+ authorName: "Alan",
366
+ authorEmail: "agent@tryalan.ai",
367
+ })).rejects.toMatchObject({ code: "repository_path_not_authorized" });
368
+ expect(git(arbitraryRepo, "status", "--porcelain")).not.toBe("");
369
+ });
370
+ it("rejects a mismatched remote before contacting either repository", async () => {
371
+ const root = makeTempDir();
372
+ const { sourcePath, remotePath } = createRemoteFixture(root);
373
+ const otherRemote = join(root, "other.git");
374
+ mkdirSync(otherRemote);
375
+ git(otherRemote, "init", "--bare");
376
+ git(sourcePath, "switch", "-c", "task/remote-guard");
377
+ writeFileSync(join(sourcePath, "tracked.txt"), "guarded work\n");
378
+ git(sourcePath, "commit", "-am", "Guarded work");
379
+ const expectedHeadSha = git(sourcePath, "rev-parse", "HEAD");
380
+ await expect(executeBindingSwitchGitRpc("git.push", {
381
+ ...common(sourcePath, "remote-guard"),
382
+ expectedHeadSha,
383
+ branch: "task/remote-guard",
384
+ expectedRemoteUrl: otherRemote,
385
+ })).rejects.toMatchObject({ code: "remote_url_mismatch" });
386
+ expect(git(remotePath, "for-each-ref", "--format=%(refname)", "refs/heads/task/remote-guard")).toBe("");
387
+ expect(git(otherRemote, "for-each-ref", "--format=%(refname)", "refs/heads/task/remote-guard")).toBe("");
388
+ });
389
+ it("cancels a hung network operation without letting its child finish later", async () => {
390
+ const root = makeTempDir();
391
+ const repoPath = createRepository(root, "repo");
392
+ git(repoPath, "switch", "-c", "task/timeout");
393
+ const markerPath = join(root, "network-finished");
394
+ const fakeBin = join(root, "fake-bin");
395
+ mkdirSync(fakeBin);
396
+ const sshScript = join(fakeBin, "ssh");
397
+ writeFileSync(sshScript, `#!/bin/sh\nsleep 0.3\nprintf finished > '${markerPath}'\nexit 1\n`);
398
+ chmodSync(sshScript, 0o755);
399
+ const remoteUrl = "ssh://git@example.invalid/owner/repo.git";
400
+ git(repoPath, "remote", "add", "origin", remoteUrl);
401
+ const previousSshCommand = process.env.ALAN_TEST_GIT_SSH_COMMAND;
402
+ const previousTimeout = process.env.ALAN_TEST_GIT_NETWORK_TIMEOUT_MS;
403
+ process.env.ALAN_TEST_GIT_SSH_COMMAND = sshScript;
404
+ process.env.ALAN_TEST_GIT_NETWORK_TIMEOUT_MS = "100";
405
+ try {
406
+ await expect(executeBindingSwitchGitRpc("git.push", {
407
+ ...common(repoPath, "timeout"),
408
+ expectedHeadSha: git(repoPath, "rev-parse", "HEAD"),
409
+ branch: "task/timeout",
410
+ expectedRemoteUrl: "https://example.invalid/owner/repo.git",
411
+ })).rejects.toMatchObject({ code: "git_network_timeout" });
412
+ await new Promise((resolvePromise) => setTimeout(resolvePromise, 50));
413
+ expect(existsSync(markerPath)).toBe(false);
414
+ }
415
+ finally {
416
+ if (previousSshCommand === undefined)
417
+ delete process.env.ALAN_TEST_GIT_SSH_COMMAND;
418
+ else
419
+ process.env.ALAN_TEST_GIT_SSH_COMMAND = previousSshCommand;
420
+ if (previousTimeout === undefined)
421
+ delete process.env.ALAN_TEST_GIT_NETWORK_TIMEOUT_MS;
422
+ else
423
+ process.env.ALAN_TEST_GIT_NETWORK_TIMEOUT_MS = previousTimeout;
424
+ }
425
+ });
426
+ it("preserves published SHA evidence when the source changes during push", async () => {
427
+ const root = makeTempDir();
428
+ const { remotePath, sourcePath } = createRemoteFixture(root);
429
+ git(sourcePath, "switch", "-c", "task/push-race");
430
+ writeFileSync(join(sourcePath, "tracked.txt"), "approved work\n");
431
+ git(sourcePath, "commit", "-am", "Approved work");
432
+ const approvedSha = git(sourcePath, "rev-parse", "HEAD");
433
+ const readyPath = join(root, "push-ready");
434
+ const releasePath = join(root, "push-release");
435
+ const sshScript = join(root, "blocking-ssh.sh");
436
+ writeFileSync(sshScript, [
437
+ "#!/bin/sh",
438
+ 'if [ "$1" = "-G" ]; then exit 0; fi',
439
+ 'command=""',
440
+ 'for argument in "$@"; do command="$argument"; done',
441
+ `case "$command" in *git-receive-pack*) touch '${readyPath}'; while [ ! -f '${releasePath}' ]; do sleep 0.02; done ;; esac`,
442
+ 'exec /bin/sh -c "$command"',
443
+ "",
444
+ ].join("\n"));
445
+ chmodSync(sshScript, 0o755);
446
+ const remoteUrl = `ssh://git@localhost${remotePath}`;
447
+ git(sourcePath, "remote", "set-url", "origin", remoteUrl);
448
+ const previousSshCommand = process.env.ALAN_TEST_GIT_SSH_COMMAND;
449
+ process.env.ALAN_TEST_GIT_SSH_COMMAND = sshScript;
450
+ try {
451
+ const pushPromise = executeBindingSwitchGitRpc("git.push", {
452
+ ...common(sourcePath, "push-race"),
453
+ expectedHeadSha: approvedSha,
454
+ expectedBranch: "task/push-race",
455
+ branch: "task/push-race",
456
+ expectedRemoteUrl: remoteUrl,
457
+ });
458
+ await waitForPath(readyPath);
459
+ writeFileSync(join(sourcePath, "tracked.txt"), "committed work changed during push\n");
460
+ git(sourcePath, "commit", "-am", "Late local commit");
461
+ const lateSha = git(sourcePath, "rev-parse", "HEAD");
462
+ expect(lateSha).not.toBe(approvedSha);
463
+ writeFileSync(releasePath, "release\n");
464
+ await expect(pushPromise).rejects.toMatchObject({
465
+ code: "source_changed_since_approval",
466
+ details: {
467
+ published: {
468
+ pushedSha: approvedSha,
469
+ branch: "task/push-race",
470
+ remote: "origin",
471
+ replayed: false,
472
+ },
473
+ },
474
+ });
475
+ expect(git(remotePath, "rev-parse", "refs/heads/task/push-race")).toBe(approvedSha);
476
+ expect(git(sourcePath, "rev-parse", "HEAD")).toBe(lateSha);
477
+ expect(git(sourcePath, "status", "--porcelain")).toBe("");
478
+ }
479
+ finally {
480
+ writeFileSync(releasePath, "release\n");
481
+ if (previousSshCommand === undefined)
482
+ delete process.env.ALAN_TEST_GIT_SSH_COMMAND;
483
+ else
484
+ process.env.ALAN_TEST_GIT_SSH_COMMAND = previousSshCommand;
485
+ }
486
+ });
487
+ it("rejects stale status approval and a fetched branch at the wrong SHA", async () => {
488
+ const root = makeTempDir();
489
+ const { sourcePath, targetPath, mainSha } = createRemoteFixture(root);
490
+ git(sourcePath, "switch", "-c", "task/stale");
491
+ writeFileSync(join(sourcePath, "tracked.txt"), "dirty\n");
492
+ const status = (await executeBindingSwitchGitRpc("git.status", common(sourcePath, "stale")));
493
+ writeFileSync(join(sourcePath, "another.txt"), "raced\n");
494
+ await expect(executeBindingSwitchGitRpc("git.checkpoint", {
495
+ ...common(sourcePath, "stale"),
496
+ expectedHeadSha: status.headSha,
497
+ expectedStatusFingerprint: status.statusFingerprint,
498
+ expectedProposedTreeSha: status.proposedTreeSha,
499
+ commitMessage: "checkpoint",
500
+ authorName: "Alan",
501
+ authorEmail: "agent@tryalan.ai",
502
+ })).rejects.toThrowError(expect.objectContaining({
503
+ code: "source_changed_since_approval",
504
+ }));
505
+ git(sourcePath, "add", "--all");
506
+ git(sourcePath, "commit", "-m", "Published task work");
507
+ const taskSha = git(sourcePath, "rev-parse", "HEAD");
508
+ await executeBindingSwitchGitRpc("git.push", {
509
+ ...common(sourcePath, "stale"),
510
+ expectedHeadSha: taskSha,
511
+ branch: "task/stale",
512
+ });
513
+ await expect(executeBindingSwitchGitRpc("git.fetch", {
514
+ ...common(targetPath, "stale"),
515
+ branch: "task/stale",
516
+ expectedSha: mainSha,
517
+ })).rejects.toThrowError(expect.objectContaining({
518
+ code: "target_sha_mismatch",
519
+ }));
520
+ });
521
+ it("never fast-forwards a dirty or divergent shared checkout", async () => {
522
+ const root = makeTempDir();
523
+ const { sourcePath, targetPath } = createRemoteFixture(root);
524
+ git(sourcePath, "switch", "-c", "task/safe");
525
+ writeFileSync(join(sourcePath, "tracked.txt"), "remote task work\n");
526
+ git(sourcePath, "commit", "-am", "Remote task work");
527
+ const pushedSha = git(sourcePath, "rev-parse", "HEAD");
528
+ await executeBindingSwitchGitRpc("git.push", {
529
+ ...common(sourcePath, "safe"),
530
+ expectedHeadSha: pushedSha,
531
+ branch: "task/safe",
532
+ });
533
+ writeFileSync(join(targetPath, "dirty.txt"), "local dirt\n");
534
+ await expect(executeBindingSwitchGitRpc("git.prepare_checkout", {
535
+ ...common(targetPath, "safe"),
536
+ branch: "task/safe",
537
+ targetSha: pushedSha,
538
+ })).rejects.toThrowError(expect.objectContaining({
539
+ code: "target_checkout_dirty",
540
+ }));
541
+ rmSync(join(targetPath, "dirty.txt"));
542
+ git(targetPath, "switch", "-c", "task/safe");
543
+ writeFileSync(join(targetPath, "local.txt"), "divergent\n");
544
+ git(targetPath, "add", "local.txt");
545
+ git(targetPath, "commit", "-m", "Local divergent work");
546
+ await expect(executeBindingSwitchGitRpc("git.prepare_checkout", {
547
+ ...common(targetPath, "safe"),
548
+ branch: "task/safe",
549
+ targetSha: pushedSha,
550
+ })).rejects.toThrowError(expect.objectContaining({
551
+ code: "target_branch_diverged",
552
+ }));
553
+ });
554
+ });
555
+ //# sourceMappingURL=binding-switch-git.test.js.map