@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
@@ -0,0 +1,826 @@
1
+ // AL-2472: local daemon control plane (probe, config, leases).
2
+ import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
3
+ import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from "node:fs";
4
+ import { basename, dirname, join } from "node:path";
5
+ import { isProviderProcessAlive, PENDING_RUN_START_TTL_MS } from "./daemon-runner-status.js";
6
+ import { bindAgentConfigPathFromArgs, resolveAgentConfigPath, sanitizeAgentConfig, } from "./runtime-config.js";
7
+ export function isNativeTaskLinkingEnabled(config) {
8
+ return config.nativeTaskLinkingEnabled === true;
9
+ }
10
+ export const LOCAL_SERVICE_OWNER_VERSION = 1;
11
+ export const LOCAL_SERVICE_CHALLENGE_TTL_MS = 5_000;
12
+ export function localServiceOwnerPayload(owner) {
13
+ return [
14
+ owner.version,
15
+ owner.serviceId,
16
+ owner.installationId,
17
+ owner.runtimeId,
18
+ owner.port,
19
+ owner.pid,
20
+ owner.startedAtMs,
21
+ owner.challenge,
22
+ ].join("\0");
23
+ }
24
+ export function signLocalServiceOwner(secret, owner) {
25
+ return createHmac("sha256", secret).update(localServiceOwnerPayload(owner)).digest("hex");
26
+ }
27
+ export function signLocalServiceAdoption(secret, serviceId, challenge) {
28
+ return createHmac("sha256", secret)
29
+ .update(["adopt", serviceId, challenge].join("\0"))
30
+ .digest("hex");
31
+ }
32
+ export function equalHexDigest(actual, expected) {
33
+ if (!/^[a-f0-9]{64}$/i.test(actual) || !/^[a-f0-9]{64}$/i.test(expected))
34
+ return false;
35
+ return timingSafeEqual(Buffer.from(actual, "hex"), Buffer.from(expected, "hex"));
36
+ }
37
+ export function parseLocalServiceOwner(value) {
38
+ if (!value || typeof value !== "object")
39
+ return null;
40
+ const owner = value;
41
+ if (owner.version !== LOCAL_SERVICE_OWNER_VERSION ||
42
+ typeof owner.serviceId !== "string" ||
43
+ typeof owner.installationId !== "string" ||
44
+ typeof owner.runtimeId !== "string" ||
45
+ typeof owner.port !== "number" ||
46
+ typeof owner.pid !== "number" ||
47
+ typeof owner.startedAtMs !== "number" ||
48
+ typeof owner.challenge !== "string" ||
49
+ typeof owner.signature !== "string") {
50
+ return null;
51
+ }
52
+ return owner;
53
+ }
54
+ export async function observeLocalDaemonEndpoint(port, token, timeoutMs = 750) {
55
+ const observedAtMs = Date.now();
56
+ try {
57
+ const headers = {};
58
+ if (token)
59
+ headers.authorization = `Bearer ${token}`;
60
+ const response = await fetch(`http://127.0.0.1:${port}/status`, {
61
+ headers,
62
+ signal: AbortSignal.timeout(timeoutMs),
63
+ });
64
+ if (response.status === 401) {
65
+ return { kind: "unauthorized", observedAtMs, httpStatus: 401 };
66
+ }
67
+ if (!response.ok) {
68
+ return {
69
+ kind: "unreachable",
70
+ reason: "http_error",
71
+ observedAtMs,
72
+ httpStatus: response.status,
73
+ detail: `HTTP ${response.status}`,
74
+ };
75
+ }
76
+ const body = (await response.json());
77
+ if (!body.runtimeId) {
78
+ return {
79
+ kind: "unreachable",
80
+ reason: "invalid_response",
81
+ observedAtMs,
82
+ detail: "status response missing runtimeId",
83
+ };
84
+ }
85
+ return { kind: "ready", status: body, observedAtMs };
86
+ }
87
+ catch (error) {
88
+ const detail = error instanceof Error ? error.message : String(error);
89
+ const lowered = detail.toLowerCase();
90
+ if (lowered.includes("timeout") ||
91
+ lowered.includes("aborted") ||
92
+ lowered.includes("timed out")) {
93
+ return { kind: "unreachable", reason: "timeout", observedAtMs, detail };
94
+ }
95
+ if (lowered.includes("econnrefused") ||
96
+ lowered.includes("connection refused") ||
97
+ lowered.includes("fetch failed")) {
98
+ return { kind: "unreachable", reason: "connection_refused", observedAtMs, detail };
99
+ }
100
+ return { kind: "unreachable", reason: "network_error", observedAtMs, detail };
101
+ }
102
+ }
103
+ export async function probeLocalDaemonEndpoint(port, token, timeoutMs = 750) {
104
+ const observation = await observeLocalDaemonEndpoint(port, token, timeoutMs);
105
+ if (observation.kind === "ready") {
106
+ return { state: "running", status: observation.status };
107
+ }
108
+ if (observation.kind === "unauthorized") {
109
+ return { state: "listening_unauthorized" };
110
+ }
111
+ // Compatibility: legacy callers treated every failure as absent. Prefer
112
+ // observeLocalDaemonEndpoint for truthful degraded/unreachable semantics.
113
+ return { state: "absent" };
114
+ }
115
+ export async function probeLocalDaemon(port, token, timeoutMs = 750) {
116
+ const probe = await probeLocalDaemonEndpoint(port, token, timeoutMs);
117
+ return probe.state === "running" ? probe.status : null;
118
+ }
119
+ export function requestLocalDaemonShutdown(port, token) {
120
+ return fetch(`http://127.0.0.1:${port}/shutdown?force=1`, {
121
+ method: "POST",
122
+ headers: {
123
+ authorization: `Bearer ${token}`,
124
+ "x-alan-shutdown-reason": "runtime_shutdown",
125
+ },
126
+ signal: AbortSignal.timeout(5_000),
127
+ });
128
+ }
129
+ export async function adoptLocalDaemonControl(input) {
130
+ const timeoutMs = input.timeoutMs ?? 750;
131
+ try {
132
+ const ownerResponse = await fetch(`http://127.0.0.1:${input.port}/owner`, {
133
+ headers: { accept: "application/json" },
134
+ signal: AbortSignal.timeout(timeoutMs),
135
+ });
136
+ if (!ownerResponse.ok)
137
+ return null;
138
+ const owner = parseLocalServiceOwner(await ownerResponse.json());
139
+ if (!owner ||
140
+ owner.serviceId !== input.serviceId ||
141
+ owner.port !== input.port ||
142
+ (input.installationId && owner.installationId !== input.installationId)) {
143
+ return null;
144
+ }
145
+ const { signature, ...unsignedOwner } = owner;
146
+ const expectedSignature = signLocalServiceOwner(input.serviceSecret, unsignedOwner);
147
+ if (!equalHexDigest(signature, expectedSignature))
148
+ return null;
149
+ const proof = signLocalServiceAdoption(input.serviceSecret, input.serviceId, owner.challenge);
150
+ const adoptionResponse = await fetch(`http://127.0.0.1:${input.port}/adopt`, {
151
+ method: "POST",
152
+ headers: {
153
+ accept: "application/json",
154
+ "x-alan-service-id": input.serviceId,
155
+ "x-alan-adoption-challenge": owner.challenge,
156
+ "x-alan-adoption-proof": proof,
157
+ },
158
+ signal: AbortSignal.timeout(timeoutMs),
159
+ });
160
+ if (!adoptionResponse.ok)
161
+ return null;
162
+ const adopted = (await adoptionResponse.json());
163
+ if (typeof adopted.localApiToken !== "string" || adopted.localApiToken.length < 32)
164
+ return null;
165
+ const status = await probeLocalDaemon(input.port, adopted.localApiToken, timeoutMs);
166
+ if (!status || status.runtimeId !== owner.runtimeId)
167
+ return null;
168
+ return { localApiToken: adopted.localApiToken, status };
169
+ }
170
+ catch {
171
+ return null;
172
+ }
173
+ }
174
+ /**
175
+ * Reclaims local control only when this config proves it owns the incumbent
176
+ * daemon. A process that merely occupies the port cannot trigger replacement
177
+ * or learn the bearer token.
178
+ */
179
+ function argValueLocal(args, name) {
180
+ const idx = args.indexOf(name);
181
+ if (idx >= 0 && args[idx + 1])
182
+ return args[idx + 1];
183
+ const prefix = `${name}=`;
184
+ const matched = args.find((arg) => arg.startsWith(prefix));
185
+ return matched ? matched.slice(prefix.length) : undefined;
186
+ }
187
+ export function getLocalApiPort(args, stored) {
188
+ const raw = argValueLocal(args, "--local-api-port") ?? process.env.ALAN_AGENT_LOCAL_API_PORT;
189
+ if (raw)
190
+ return Number.parseInt(raw, 10);
191
+ const storedPort = stored.localApiPort;
192
+ if (storedPort && storedPort > 0)
193
+ return storedPort;
194
+ return 47831;
195
+ }
196
+ export async function adoptConfiguredLocalDaemon(args = []) {
197
+ bindConfigPath(args);
198
+ const stored = readConfig();
199
+ const port = getLocalApiPort(args, stored);
200
+ if (stored.localApiToken) {
201
+ const existing = await probeLocalDaemon(port, stored.localApiToken);
202
+ if (existing)
203
+ return existing;
204
+ }
205
+ if (!stored.localServiceId || !stored.localServiceSecret)
206
+ return null;
207
+ const adopted = await adoptLocalDaemonControl({
208
+ port,
209
+ serviceId: stored.localServiceId,
210
+ serviceSecret: stored.localServiceSecret,
211
+ installationId: stored.installationId,
212
+ });
213
+ if (!adopted)
214
+ return null;
215
+ // Do not overwrite credentials that may have changed while the handshake
216
+ // was in flight. The owner identity itself must still match.
217
+ const latest = readConfig();
218
+ if (latest.localServiceId !== stored.localServiceId ||
219
+ latest.localServiceSecret !== stored.localServiceSecret) {
220
+ return null;
221
+ }
222
+ writeConfig({ ...latest, localApiPort: port, localApiToken: adopted.localApiToken });
223
+ return adopted.status;
224
+ }
225
+ export async function isLocalDaemonListening(port, token) {
226
+ const probe = await probeLocalDaemonEndpoint(port, token);
227
+ return probe.state !== "absent";
228
+ }
229
+ export function describeOccupiedLocalDaemon(port) {
230
+ return (`local daemon API port ${port} is already in use. ` +
231
+ "If Alan desktop is open, it manages the daemon automatically. " +
232
+ "Quit Alan desktop or stop the existing daemon before starting another.");
233
+ }
234
+ /**
235
+ * Last config path bound via bindAgentConfigPathFromArgs. Keeps late/async
236
+ * daemon code on the active profile's config even if the supervisor restores
237
+ * ALAN_AGENT_CONFIG_PATH after startup (the desktop supervisor does).
238
+ */
239
+ let boundAgentConfigPath = null;
240
+ export function bindConfigPath(args) {
241
+ boundAgentConfigPath = bindAgentConfigPathFromArgs(args);
242
+ return boundAgentConfigPath;
243
+ }
244
+ export function getConfigPath() {
245
+ return (boundAgentConfigPath ??
246
+ process.env.ALAN_AGENT_CONFIG_PATH ??
247
+ resolveAgentConfigPath({ profile: "production" }));
248
+ }
249
+ export function getEndpointDefaultsPath() {
250
+ return process.env.ALAN_AGENT_ENDPOINTS_PATH ?? join(dirname(getConfigPath()), "endpoints.json");
251
+ }
252
+ export function readConfig() {
253
+ const configPath = getConfigPath();
254
+ if (!existsSync(configPath))
255
+ return {};
256
+ const parsed = JSON.parse(readFileSync(configPath, "utf8"));
257
+ const sanitized = sanitizeAgentConfig(parsed);
258
+ if (Object.keys(parsed).some((key) => !Object.hasOwn(sanitized, key))) {
259
+ writeConfig(sanitized);
260
+ }
261
+ return sanitized;
262
+ }
263
+ export function readConfigForRegistration() {
264
+ try {
265
+ return readConfig();
266
+ }
267
+ catch {
268
+ // Registration is also the repair path for malformed/unreadable config.
269
+ return {};
270
+ }
271
+ }
272
+ export function readEndpointDefaults() {
273
+ const endpointsPath = getEndpointDefaultsPath();
274
+ if (!existsSync(endpointsPath))
275
+ return {};
276
+ try {
277
+ return JSON.parse(readFileSync(endpointsPath, "utf8"));
278
+ }
279
+ catch {
280
+ return {};
281
+ }
282
+ }
283
+ export function writeConfig(config) {
284
+ const configPath = getConfigPath();
285
+ mkdirSync(dirname(configPath), { recursive: true, mode: 0o700 });
286
+ const pendingPath = `${configPath}.pending-${process.pid}-${randomBytes(6).toString("hex")}`;
287
+ try {
288
+ writeFileSync(pendingPath, JSON.stringify(sanitizeAgentConfig(config), null, 2), { mode: 0o600 });
289
+ chmodSync(pendingPath, 0o600);
290
+ renameSync(pendingPath, configPath);
291
+ }
292
+ finally {
293
+ rmSync(pendingPath, { force: true });
294
+ }
295
+ }
296
+ export function maintenanceLeasePath(configPath) {
297
+ return `${configPath}.maintenance-lease.json`;
298
+ }
299
+ export function readLocalDaemonMaintenanceLease(configPath, nowMs = Date.now()) {
300
+ const path = maintenanceLeasePath(configPath);
301
+ if (!existsSync(path))
302
+ return null;
303
+ try {
304
+ const lease = JSON.parse(readFileSync(path, "utf8"));
305
+ if (lease.version !== 1 ||
306
+ typeof lease.id !== "string" ||
307
+ (lease.reason !== "credential_cleanup" &&
308
+ lease.reason !== "credential_swap" &&
309
+ lease.reason !== "daemon_startup" &&
310
+ lease.reason !== "watchdog") ||
311
+ !((lease.reason === "credential_cleanup" && lease.expiresAtMs === null) ||
312
+ (typeof lease.expiresAtMs === "number" && Number.isFinite(lease.expiresAtMs)))) {
313
+ throw new Error("invalid maintenance lease");
314
+ }
315
+ // Credential cleanup is a durable drain intent, not a watchdog timeout. Old
316
+ // versions wrote a finite expiry, so ignore it for this reason during
317
+ // rolling upgrades as well as writing null for all new cleanup leases.
318
+ if (lease.reason !== "credential_cleanup" && lease.expiresAtMs <= nowMs) {
319
+ releaseOwnedJsonFile(path, lease.id);
320
+ return null;
321
+ }
322
+ return lease;
323
+ }
324
+ catch {
325
+ // A partial/corrupt lease must fail closed for one short watchdog window,
326
+ // not fence dispatch forever.
327
+ const fallback = {
328
+ version: 1,
329
+ id: "invalid",
330
+ reason: "watchdog",
331
+ expiresAtMs: nowMs + 5_000,
332
+ };
333
+ try {
334
+ writeFileSync(path, JSON.stringify(fallback), { mode: 0o600 });
335
+ chmodSync(path, 0o600);
336
+ }
337
+ catch {
338
+ // The in-memory fallback still fences this decision safely.
339
+ }
340
+ return fallback;
341
+ }
342
+ }
343
+ export function acquireLocalDaemonMaintenanceLease(configPath, reason, ttlMs = 5_000) {
344
+ const existing = readLocalDaemonMaintenanceLease(configPath);
345
+ if (existing)
346
+ return { acquired: false, lease: existing };
347
+ const lease = {
348
+ version: 1,
349
+ id: randomUUID(),
350
+ reason,
351
+ expiresAtMs: reason === "credential_cleanup"
352
+ ? null
353
+ : Date.now() + Math.max(1_000, Math.min(ttlMs, 60_000)),
354
+ };
355
+ const path = maintenanceLeasePath(configPath);
356
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
357
+ try {
358
+ writeFileSync(path, JSON.stringify(lease), { mode: 0o600, flag: "wx" });
359
+ chmodSync(path, 0o600);
360
+ return { acquired: true, lease };
361
+ }
362
+ catch (error) {
363
+ const raced = readLocalDaemonMaintenanceLease(configPath);
364
+ if (raced)
365
+ return { acquired: false, lease: raced };
366
+ throw error;
367
+ }
368
+ }
369
+ export function releaseLocalDaemonMaintenanceLease(configPath, leaseId) {
370
+ releaseOwnedJsonFile(maintenanceLeasePath(configPath), leaseId);
371
+ }
372
+ export function daemonOwnerLeasePath(configPath) {
373
+ return `${configPath}.daemon-owner.json`;
374
+ }
375
+ export function readLocalDaemonOwnerLease(configPath) {
376
+ const path = daemonOwnerLeasePath(configPath);
377
+ if (!existsSync(path))
378
+ return null;
379
+ try {
380
+ const lease = JSON.parse(readFileSync(path, "utf8"));
381
+ if (lease.version !== 1 ||
382
+ typeof lease.id !== "string" ||
383
+ typeof lease.daemonSessionId !== "string" ||
384
+ !Number.isSafeInteger(lease.pid) ||
385
+ lease.pid <= 0 ||
386
+ typeof lease.startedAtMs !== "number" ||
387
+ !Number.isFinite(lease.startedAtMs) ||
388
+ typeof lease.runtimeId !== "string" ||
389
+ typeof lease.localServiceId !== "string" ||
390
+ !Number.isSafeInteger(lease.localApiPort) ||
391
+ lease.localApiPort < 0 ||
392
+ lease.localApiPort > 65_535 ||
393
+ typeof lease.localApiToken !== "string" ||
394
+ lease.localApiToken.length === 0) {
395
+ throw new Error("invalid daemon owner lease");
396
+ }
397
+ return lease;
398
+ }
399
+ catch (error) {
400
+ throw new Error(`Cannot safely read daemon owner lease: ${error instanceof Error ? error.message : String(error)}`);
401
+ }
402
+ }
403
+ export async function acquireLocalDaemonOwnerLease(input) {
404
+ const existing = readLocalDaemonOwnerLease(input.configPath);
405
+ if (existing) {
406
+ const endpoint = existing.localApiPort > 0
407
+ ? await probeLocalDaemonEndpoint(existing.localApiPort, existing.localApiToken)
408
+ : { state: "absent" };
409
+ if (endpoint.state === "running") {
410
+ const matchesOwner = endpoint.status.runtimeId === existing.runtimeId &&
411
+ endpoint.status.localServiceId === existing.localServiceId &&
412
+ endpoint.status.daemonSessionId === existing.daemonSessionId;
413
+ if (!matchesOwner) {
414
+ throw new Error("Daemon owner lease does not match the authenticated local endpoint");
415
+ }
416
+ return { acquired: false, lease: existing };
417
+ }
418
+ if (endpoint.state === "listening_unauthorized") {
419
+ return { acquired: false, lease: existing };
420
+ }
421
+ // PID existence alone is not proof of daemon ownership: after a crash or
422
+ // reboot the OS can reuse the recorded PID for an unrelated process. The
423
+ // authenticated endpoint is authoritative. If it is absent, an apparently
424
+ // live owner only blocks takeover while accepted or pending work still
425
+ // needs protection. The startup maintenance lease already serializes this
426
+ // decision against another daemon that is concurrently starting.
427
+ const journal = inspectLocalDaemonRunJournal(input.configPath);
428
+ if (isProviderProcessAlive(existing.pid) && !journal.safeToRestart) {
429
+ return { acquired: false, lease: existing };
430
+ }
431
+ // The authenticated endpoint is absent and no live work prevents recovery.
432
+ // Replace the stale owner; the new owner confirms recovery only after bind.
433
+ releaseOwnedJsonFile(daemonOwnerLeasePath(input.configPath), existing.id);
434
+ }
435
+ if (!existing && input.storedLocalApiPort && input.storedLocalApiToken) {
436
+ const storedEndpoint = await probeLocalDaemonEndpoint(input.storedLocalApiPort, input.storedLocalApiToken);
437
+ if (storedEndpoint.state === "running") {
438
+ throw new Error("The stored local endpoint already owns this daemon config");
439
+ }
440
+ if (storedEndpoint.state === "listening_unauthorized") {
441
+ throw new Error("The stored local endpoint rejected this daemon config token");
442
+ }
443
+ }
444
+ const lease = {
445
+ version: 1,
446
+ id: randomUUID(),
447
+ daemonSessionId: input.daemonSessionId,
448
+ pid: process.pid,
449
+ startedAtMs: Date.now(),
450
+ runtimeId: input.runtimeId,
451
+ localServiceId: input.localServiceId,
452
+ localApiPort: input.localApiPort,
453
+ localApiToken: input.localApiToken,
454
+ };
455
+ const path = daemonOwnerLeasePath(input.configPath);
456
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
457
+ try {
458
+ writeFileSync(path, JSON.stringify(lease), { mode: 0o600, flag: "wx" });
459
+ chmodSync(path, 0o600);
460
+ return { acquired: true, lease };
461
+ }
462
+ catch (error) {
463
+ const raced = readLocalDaemonOwnerLease(input.configPath);
464
+ if (raced)
465
+ return { acquired: false, lease: raced };
466
+ throw error;
467
+ }
468
+ }
469
+ export function updateLocalDaemonOwnerEndpoint(configPath, lease, localApiPort) {
470
+ const current = readLocalDaemonOwnerLease(configPath);
471
+ if (current?.id !== lease.id)
472
+ throw new Error("Daemon ownership changed before local API bind");
473
+ const updated = { ...lease, localApiPort };
474
+ const path = daemonOwnerLeasePath(configPath);
475
+ const pendingPath = `${path}.pending-${lease.id}`;
476
+ try {
477
+ writeFileSync(pendingPath, JSON.stringify(updated), { mode: 0o600 });
478
+ chmodSync(pendingPath, 0o600);
479
+ renameSync(pendingPath, path);
480
+ return updated;
481
+ }
482
+ finally {
483
+ rmSync(pendingPath, { force: true });
484
+ }
485
+ }
486
+ export function releaseLocalDaemonOwnerLease(configPath, leaseId) {
487
+ releaseOwnedJsonFile(daemonOwnerLeasePath(configPath), leaseId);
488
+ }
489
+ /**
490
+ * Atomically take the current pathname before inspecting ownership. A newer
491
+ * replacement can therefore never be removed by an older owner's release.
492
+ */
493
+ export function releaseOwnedJsonFile(path, ownerId, ownerField = "id") {
494
+ const releasePath = `${path}.release-${process.pid}-${randomBytes(6).toString("hex")}`;
495
+ try {
496
+ renameSync(path, releasePath);
497
+ }
498
+ catch (error) {
499
+ if (error.code === "ENOENT")
500
+ return;
501
+ throw error;
502
+ }
503
+ try {
504
+ const content = readFileSync(releasePath, "utf8");
505
+ let capturedOwnerId = null;
506
+ try {
507
+ const captured = JSON.parse(content);
508
+ capturedOwnerId = typeof captured[ownerField] === "string" ? captured[ownerField] : null;
509
+ }
510
+ catch {
511
+ // Preserve an invalid replacement too; readers deliberately fail closed.
512
+ }
513
+ if (capturedOwnerId === ownerId)
514
+ return;
515
+ // Restore only if nobody acquired a still-newer lease in the short rename
516
+ // window. `wx` prevents this older release from overwriting that owner.
517
+ try {
518
+ writeFileSync(path, content, { mode: 0o600, flag: "wx" });
519
+ chmodSync(path, 0o600);
520
+ }
521
+ catch (error) {
522
+ if (error.code !== "EEXIST")
523
+ throw error;
524
+ }
525
+ }
526
+ finally {
527
+ rmSync(releasePath, { force: true });
528
+ }
529
+ }
530
+ export function inspectLocalDaemonRunJournal(configPath) {
531
+ const nowMs = Date.now();
532
+ const path = `${configPath}.run-journal.json`;
533
+ const pendingPath = `${configPath}.pending-runs.json`;
534
+ try {
535
+ let activeRunCount = 0;
536
+ for (const artifact of [path, pendingPath]) {
537
+ if (!existsSync(artifact))
538
+ continue;
539
+ const parsed = JSON.parse(readFileSync(artifact, "utf8"));
540
+ if (parsed.version !== 1 || !Array.isArray(parsed.entries))
541
+ throw new Error("invalid journal");
542
+ if (artifact === path) {
543
+ activeRunCount += parsed.entries.filter((entry) => {
544
+ if (!entry || typeof entry !== "object")
545
+ throw new Error("invalid run journal entry");
546
+ const journalEntry = entry;
547
+ if (typeof journalEntry.runId !== "string" ||
548
+ journalEntry.runId.length === 0 ||
549
+ typeof journalEntry.conversationId !== "string" ||
550
+ journalEntry.conversationId.length === 0 ||
551
+ typeof journalEntry.acceptedAtMs !== "number" ||
552
+ !Number.isFinite(journalEntry.acceptedAtMs)) {
553
+ throw new Error("invalid run journal identity");
554
+ }
555
+ const interruptedAtMs = journalEntry.interruptedAtMs;
556
+ if (interruptedAtMs === undefined)
557
+ return true;
558
+ if (typeof interruptedAtMs !== "number" || !Number.isFinite(interruptedAtMs)) {
559
+ throw new Error("invalid interrupted journal marker");
560
+ }
561
+ return false;
562
+ }).length;
563
+ continue;
564
+ }
565
+ const legacyStartedAtMs = statSync(pendingPath).mtimeMs;
566
+ activeRunCount += parsed.entries.filter((entry) => {
567
+ if (!entry || typeof entry !== "object")
568
+ throw new Error("invalid pending run entry");
569
+ const startedAtMs = entry.startedAtMs;
570
+ if (startedAtMs === undefined) {
571
+ return nowMs - legacyStartedAtMs <= PENDING_RUN_START_TTL_MS;
572
+ }
573
+ if (typeof startedAtMs !== "number" || !Number.isFinite(startedAtMs)) {
574
+ throw new Error("invalid pending run timestamp");
575
+ }
576
+ return nowMs - startedAtMs <= PENDING_RUN_START_TTL_MS;
577
+ }).length;
578
+ }
579
+ return { safeToRestart: activeRunCount === 0, activeRunCount };
580
+ }
581
+ catch {
582
+ return { safeToRestart: false, activeRunCount: 1 };
583
+ }
584
+ }
585
+ export function pendingSetupIntentPath() {
586
+ return `${getConfigPath()}.setup-pending`;
587
+ }
588
+ export function setupTokenHash(setupToken) {
589
+ return createHash("sha256").update(setupToken).digest("hex");
590
+ }
591
+ export function getOrCreateSetupAttemptId(setupToken) {
592
+ const intentPath = pendingSetupIntentPath();
593
+ const tokenHash = setupTokenHash(setupToken);
594
+ if (existsSync(intentPath)) {
595
+ try {
596
+ const stored = JSON.parse(readFileSync(intentPath, "utf8"));
597
+ if (stored.setupTokenHash === tokenHash &&
598
+ typeof stored.registrationAttemptId === "string" &&
599
+ stored.registrationAttemptId.length > 0) {
600
+ return stored.registrationAttemptId;
601
+ }
602
+ }
603
+ catch {
604
+ // Replace malformed or stale setup intent below without touching active config.
605
+ }
606
+ }
607
+ const registrationAttemptId = randomUUID();
608
+ mkdirSync(dirname(intentPath), { recursive: true, mode: 0o700 });
609
+ const writePath = `${intentPath}.pending-${process.pid}-${randomBytes(6).toString("hex")}`;
610
+ try {
611
+ writeFileSync(writePath, JSON.stringify({ setupTokenHash: tokenHash, registrationAttemptId }, null, 2), { mode: 0o600 });
612
+ chmodSync(writePath, 0o600);
613
+ renameSync(writePath, intentPath);
614
+ }
615
+ finally {
616
+ rmSync(writePath, { force: true });
617
+ }
618
+ return registrationAttemptId;
619
+ }
620
+ export function clearPendingSetupIntent() {
621
+ rmSync(pendingSetupIntentPath(), { force: true });
622
+ }
623
+ export function pendingDeviceAuthorizationPath() {
624
+ return `${getConfigPath()}.device-auth-pending`;
625
+ }
626
+ export function deviceAuthorizationOperationPath() {
627
+ return `${getConfigPath()}.device-auth-operation.json`;
628
+ }
629
+ export function parseDeviceAuthorizationOperationContent(content) {
630
+ try {
631
+ const lease = JSON.parse(content);
632
+ if (lease.version !== 1 ||
633
+ typeof lease.id !== "string" ||
634
+ typeof lease.expiresAtMs !== "number" ||
635
+ !Number.isFinite(lease.expiresAtMs)) {
636
+ return null;
637
+ }
638
+ return lease;
639
+ }
640
+ catch {
641
+ return null;
642
+ }
643
+ }
644
+ export function restoreCapturedFileUnlessReplaced(path, content) {
645
+ try {
646
+ writeFileSync(path, content, { mode: 0o600, flag: "wx" });
647
+ chmodSync(path, 0o600);
648
+ }
649
+ catch (error) {
650
+ if (error.code !== "EEXIST")
651
+ throw error;
652
+ }
653
+ }
654
+ export function quarantineCorruptDeviceAuthorizationOperation(path) {
655
+ const quarantinePath = `${path}.corrupt-${process.pid}-${randomBytes(6).toString("hex")}`;
656
+ try {
657
+ renameSync(path, quarantinePath);
658
+ }
659
+ catch (error) {
660
+ if (error.code === "ENOENT")
661
+ return null;
662
+ throw error;
663
+ }
664
+ try {
665
+ const capturedContent = readFileSync(quarantinePath, "utf8");
666
+ // The pathname may have been replaced after the failed parse but before
667
+ // this atomic capture. Preserve it if what we actually captured is valid.
668
+ if (parseDeviceAuthorizationOperationContent(capturedContent)) {
669
+ restoreCapturedFileUnlessReplaced(path, capturedContent);
670
+ }
671
+ }
672
+ finally {
673
+ rmSync(quarantinePath, { force: true });
674
+ }
675
+ if (!existsSync(path))
676
+ return null;
677
+ return parseDeviceAuthorizationOperationContent(readFileSync(path, "utf8"));
678
+ }
679
+ export function readDeviceAuthorizationOperation() {
680
+ const path = deviceAuthorizationOperationPath();
681
+ if (!existsSync(path))
682
+ return null;
683
+ const parsed = parseDeviceAuthorizationOperationContent(readFileSync(path, "utf8"));
684
+ const lease = parsed ?? quarantineCorruptDeviceAuthorizationOperation(path);
685
+ if (!lease)
686
+ return null;
687
+ if (lease.expiresAtMs <= Date.now()) {
688
+ releaseOwnedJsonFile(path, lease.id);
689
+ return null;
690
+ }
691
+ return lease;
692
+ }
693
+ export function acquireDeviceAuthorizationOperation() {
694
+ const existing = readDeviceAuthorizationOperation();
695
+ if (existing)
696
+ return null;
697
+ const lease = {
698
+ version: 1,
699
+ id: randomUUID(),
700
+ expiresAtMs: Date.now() + 60_000,
701
+ };
702
+ const path = deviceAuthorizationOperationPath();
703
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
704
+ try {
705
+ writeFileSync(path, JSON.stringify(lease), { mode: 0o600, flag: "wx" });
706
+ chmodSync(path, 0o600);
707
+ return lease;
708
+ }
709
+ catch (error) {
710
+ if (error.code === "EEXIST")
711
+ return null;
712
+ throw error;
713
+ }
714
+ }
715
+ export function extendDeviceAuthorizationOperation(operationId, expiresAtMs) {
716
+ const current = readDeviceAuthorizationOperation();
717
+ if (current?.id !== operationId) {
718
+ throw new Error("browser authorization operation ownership was lost");
719
+ }
720
+ const path = deviceAuthorizationOperationPath();
721
+ const pendingPath = `${path}.pending-${process.pid}-${randomBytes(6).toString("hex")}`;
722
+ try {
723
+ writeFileSync(pendingPath, JSON.stringify({ ...current, expiresAtMs: Math.max(expiresAtMs, Date.now() + 60_000) }), { mode: 0o600 });
724
+ chmodSync(pendingPath, 0o600);
725
+ // The current operation is still unexpired, so a compliant peer cannot
726
+ // replace it between the owner check and this atomic renewal.
727
+ renameSync(pendingPath, path);
728
+ }
729
+ finally {
730
+ rmSync(pendingPath, { force: true });
731
+ }
732
+ }
733
+ export function assertDeviceAuthorizationOperationOwner(operationId) {
734
+ if (readDeviceAuthorizationOperation()?.id !== operationId) {
735
+ throw new Error("browser authorization operation ownership was lost");
736
+ }
737
+ }
738
+ export function clearPendingDeviceAuthorization(operationId) {
739
+ const path = pendingDeviceAuthorizationPath();
740
+ if (!operationId) {
741
+ rmSync(path, { force: true });
742
+ return;
743
+ }
744
+ if (!existsSync(path))
745
+ return;
746
+ try {
747
+ const pending = JSON.parse(readFileSync(path, "utf8"));
748
+ if (pending.operationId !== operationId)
749
+ return;
750
+ }
751
+ catch {
752
+ return;
753
+ }
754
+ releaseOwnedJsonFile(path, operationId, "operationId");
755
+ }
756
+ export function readPendingDeviceAuthorization(apiUrl) {
757
+ const path = pendingDeviceAuthorizationPath();
758
+ if (!existsSync(path))
759
+ return null;
760
+ try {
761
+ const pending = JSON.parse(readFileSync(path, "utf8"));
762
+ const expiresAtMs = Date.parse(pending.expiresAt ?? "");
763
+ if (pending.apiUrl !== apiUrl ||
764
+ typeof pending.deviceCode !== "string" ||
765
+ typeof pending.userCode !== "string" ||
766
+ typeof pending.verificationUri !== "string" ||
767
+ typeof pending.installationId !== "string" ||
768
+ (pending.operationId !== undefined && typeof pending.operationId !== "string") ||
769
+ !Number.isFinite(pending.intervalSeconds) ||
770
+ !Number.isFinite(expiresAtMs) ||
771
+ expiresAtMs <= Date.now()) {
772
+ return null;
773
+ }
774
+ return pending;
775
+ }
776
+ catch {
777
+ return null;
778
+ }
779
+ }
780
+ export function writePendingDeviceAuthorization(pending) {
781
+ const path = pendingDeviceAuthorizationPath();
782
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
783
+ const writePath = `${path}.pending-${process.pid}-${randomBytes(6).toString("hex")}`;
784
+ try {
785
+ writeFileSync(writePath, JSON.stringify(pending, null, 2), { mode: 0o600 });
786
+ chmodSync(writePath, 0o600);
787
+ renameSync(writePath, path);
788
+ }
789
+ finally {
790
+ rmSync(writePath, { force: true });
791
+ }
792
+ }
793
+ export function removeAlanOwnedLocalArtifacts() {
794
+ const configPath = getConfigPath();
795
+ const directory = dirname(configPath);
796
+ const configName = basename(configPath).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
797
+ const alanAtomicSidecarPattern = new RegExp(`^${configName}(?:|\\.setup-pending|\\.device-auth-pending|\\.device-auth-operation\\.json|\\.maintenance-lease\\.json|\\.event-outbox\\.enc)\\.(?:pending|release|corrupt)-\\d+-[a-f0-9]{12}$`);
798
+ // This is the complete Alan-owned local credential/state inventory. Keep
799
+ // third-party provider and MCP config outside this list: logout must never
800
+ // delete user-owned tool configuration.
801
+ const artifacts = new Set([
802
+ `${configPath}.pending`,
803
+ `${configPath}.last-known-good`,
804
+ pendingSetupIntentPath(),
805
+ pendingDeviceAuthorizationPath(),
806
+ deviceAuthorizationOperationPath(),
807
+ `${configPath}.event-outbox.enc`,
808
+ `${configPath}.run-journal.json`,
809
+ `${configPath}.run-journal.json.pending`,
810
+ `${configPath}.pending-runs.json`,
811
+ `${configPath}.pending-runs.json.pending`,
812
+ maintenanceLeasePath(configPath),
813
+ ]);
814
+ if (existsSync(directory)) {
815
+ for (const entry of readdirSync(directory)) {
816
+ if (alanAtomicSidecarPattern.test(entry))
817
+ artifacts.add(join(directory, entry));
818
+ }
819
+ }
820
+ for (const artifact of artifacts)
821
+ rmSync(artifact, { force: true });
822
+ // Remove the durable credential file last so a partial cleanup never leaves
823
+ // hidden credential sidecars behind while claiming logout succeeded.
824
+ rmSync(configPath, { force: true });
825
+ }
826
+ //# sourceMappingURL=daemon-local-control.js.map