@multiplayer-app/agent 0.1.19 → 0.1.21

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 (308) hide show
  1. package/README.md +14 -7
  2. package/dist/agent/definition.d.ts +13 -0
  3. package/dist/agent/definition.d.ts.map +1 -1
  4. package/dist/agent/definition.test.js +8 -3
  5. package/dist/agent/definition.test.js.map +1 -1
  6. package/dist/agent/profiles/coding.d.ts +1 -1
  7. package/dist/agent/profiles/coding.d.ts.map +1 -1
  8. package/dist/agent/profiles/coding.js +21 -4
  9. package/dist/agent/profiles/coding.js.map +1 -1
  10. package/dist/agent/profiles/index.js +1 -1
  11. package/dist/agent/profiles/index.js.map +1 -1
  12. package/dist/agent/profiles/research.d.ts.map +1 -1
  13. package/dist/agent/profiles/research.js +23 -1
  14. package/dist/agent/profiles/research.js.map +1 -1
  15. package/dist/agent/turn-history.d.ts +40 -0
  16. package/dist/agent/turn-history.d.ts.map +1 -0
  17. package/dist/agent/turn-history.js +167 -0
  18. package/dist/agent/turn-history.js.map +1 -0
  19. package/dist/agent/turn-runner.d.ts +22 -1
  20. package/dist/agent/turn-runner.d.ts.map +1 -1
  21. package/dist/agent/turn-runner.js +162 -79
  22. package/dist/agent/turn-runner.js.map +1 -1
  23. package/dist/app/app-host.d.ts +57 -0
  24. package/dist/app/app-host.d.ts.map +1 -0
  25. package/dist/app/app-host.js +252 -0
  26. package/dist/app/app-host.js.map +1 -0
  27. package/dist/app/app-host.test.d.ts +2 -0
  28. package/dist/app/app-host.test.d.ts.map +1 -0
  29. package/dist/app/app-host.test.js +639 -0
  30. package/dist/app/app-host.test.js.map +1 -0
  31. package/dist/app/config.d.ts +196 -0
  32. package/dist/app/config.d.ts.map +1 -0
  33. package/dist/app/config.js +362 -0
  34. package/dist/app/config.js.map +1 -0
  35. package/dist/app/config.test.d.ts +2 -0
  36. package/dist/app/config.test.d.ts.map +1 -0
  37. package/dist/app/config.test.js +224 -0
  38. package/dist/app/config.test.js.map +1 -0
  39. package/dist/app/detect.d.ts +68 -0
  40. package/dist/app/detect.d.ts.map +1 -0
  41. package/dist/app/detect.js +449 -0
  42. package/dist/app/detect.js.map +1 -0
  43. package/dist/app/detect.test.d.ts +2 -0
  44. package/dist/app/detect.test.d.ts.map +1 -0
  45. package/dist/app/detect.test.js +267 -0
  46. package/dist/app/detect.test.js.map +1 -0
  47. package/dist/app/env.d.ts +5 -0
  48. package/dist/app/env.d.ts.map +1 -0
  49. package/dist/app/env.js +22 -0
  50. package/dist/app/env.js.map +1 -0
  51. package/dist/app/functions-cli.d.ts +3 -0
  52. package/dist/app/functions-cli.d.ts.map +1 -0
  53. package/dist/app/functions-cli.js +27 -0
  54. package/dist/app/functions-cli.js.map +1 -0
  55. package/dist/app/functions-host.d.ts +15 -0
  56. package/dist/app/functions-host.d.ts.map +1 -0
  57. package/dist/app/functions-host.js +276 -0
  58. package/dist/app/functions-host.js.map +1 -0
  59. package/dist/app/functions-host.test.d.ts +2 -0
  60. package/dist/app/functions-host.test.d.ts.map +1 -0
  61. package/dist/app/functions-host.test.js +117 -0
  62. package/dist/app/functions-host.test.js.map +1 -0
  63. package/dist/app/functions-routes.d.ts +23 -0
  64. package/dist/app/functions-routes.d.ts.map +1 -0
  65. package/dist/app/functions-routes.js +85 -0
  66. package/dist/app/functions-routes.js.map +1 -0
  67. package/dist/app/functions-routes.test.d.ts +2 -0
  68. package/dist/app/functions-routes.test.d.ts.map +1 -0
  69. package/dist/app/functions-routes.test.js +40 -0
  70. package/dist/app/functions-routes.test.js.map +1 -0
  71. package/dist/app/manifest.d.ts +17 -0
  72. package/dist/app/manifest.d.ts.map +1 -0
  73. package/dist/app/manifest.js +64 -0
  74. package/dist/app/manifest.js.map +1 -0
  75. package/dist/app/manifest.test.d.ts +2 -0
  76. package/dist/app/manifest.test.d.ts.map +1 -0
  77. package/dist/app/manifest.test.js +173 -0
  78. package/dist/app/manifest.test.js.map +1 -0
  79. package/dist/app/release-artifacts.d.ts +39 -0
  80. package/dist/app/release-artifacts.d.ts.map +1 -0
  81. package/dist/app/release-artifacts.js +229 -0
  82. package/dist/app/release-artifacts.js.map +1 -0
  83. package/dist/app/release-artifacts.test.d.ts +2 -0
  84. package/dist/app/release-artifacts.test.d.ts.map +1 -0
  85. package/dist/app/release-artifacts.test.js +295 -0
  86. package/dist/app/release-artifacts.test.js.map +1 -0
  87. package/dist/app/route-pattern.d.ts +23 -0
  88. package/dist/app/route-pattern.d.ts.map +1 -0
  89. package/dist/app/route-pattern.js +339 -0
  90. package/dist/app/route-pattern.js.map +1 -0
  91. package/dist/app/route-pattern.test.d.ts +2 -0
  92. package/dist/app/route-pattern.test.d.ts.map +1 -0
  93. package/dist/app/route-pattern.test.js +187 -0
  94. package/dist/app/route-pattern.test.js.map +1 -0
  95. package/dist/app/rules.d.ts +61 -0
  96. package/dist/app/rules.d.ts.map +1 -0
  97. package/dist/app/rules.js +90 -0
  98. package/dist/app/rules.js.map +1 -0
  99. package/dist/app/rules.test.d.ts +2 -0
  100. package/dist/app/rules.test.d.ts.map +1 -0
  101. package/dist/app/rules.test.js +69 -0
  102. package/dist/app/rules.test.js.map +1 -0
  103. package/dist/app/runner.d.ts +109 -0
  104. package/dist/app/runner.d.ts.map +1 -0
  105. package/dist/app/runner.js +429 -0
  106. package/dist/app/runner.js.map +1 -0
  107. package/dist/app/site.d.ts +73 -0
  108. package/dist/app/site.d.ts.map +1 -0
  109. package/dist/app/site.js +161 -0
  110. package/dist/app/site.js.map +1 -0
  111. package/dist/app/site.test.d.ts +2 -0
  112. package/dist/app/site.test.d.ts.map +1 -0
  113. package/dist/app/site.test.js +291 -0
  114. package/dist/app/site.test.js.map +1 -0
  115. package/dist/app/static-server.d.ts +20 -0
  116. package/dist/app/static-server.d.ts.map +1 -0
  117. package/dist/app/static-server.js +145 -0
  118. package/dist/app/static-server.js.map +1 -0
  119. package/dist/context-pruning.d.ts +2 -0
  120. package/dist/context-pruning.d.ts.map +1 -1
  121. package/dist/context-pruning.js +3 -2
  122. package/dist/context-pruning.js.map +1 -1
  123. package/dist/models/usage.d.ts +6 -0
  124. package/dist/models/usage.d.ts.map +1 -1
  125. package/dist/models/usage.js +13 -0
  126. package/dist/models/usage.js.map +1 -1
  127. package/dist/persistence/conversation-store.d.ts +21 -0
  128. package/dist/persistence/conversation-store.d.ts.map +1 -0
  129. package/dist/persistence/conversation-store.js +59 -0
  130. package/dist/persistence/conversation-store.js.map +1 -0
  131. package/dist/persistence/conversation-store.test.d.ts +2 -0
  132. package/dist/persistence/conversation-store.test.d.ts.map +1 -0
  133. package/dist/persistence/conversation-store.test.js +98 -0
  134. package/dist/persistence/conversation-store.test.js.map +1 -0
  135. package/dist/persistence/git-sync.d.ts +14 -1
  136. package/dist/persistence/git-sync.d.ts.map +1 -1
  137. package/dist/persistence/git-sync.js +73 -17
  138. package/dist/persistence/git-sync.js.map +1 -1
  139. package/dist/persistence/git-sync.test.js +155 -6
  140. package/dist/persistence/git-sync.test.js.map +1 -1
  141. package/dist/persistence/snapshot-sync.d.ts +19 -2
  142. package/dist/persistence/snapshot-sync.d.ts.map +1 -1
  143. package/dist/persistence/snapshot-sync.js +194 -83
  144. package/dist/persistence/snapshot-sync.js.map +1 -1
  145. package/dist/persistence/snapshot-sync.test.js +145 -27
  146. package/dist/persistence/snapshot-sync.test.js.map +1 -1
  147. package/dist/persistence/workspace.d.ts +3 -0
  148. package/dist/persistence/workspace.d.ts.map +1 -1
  149. package/dist/persistence/workspace.js +1 -0
  150. package/dist/persistence/workspace.js.map +1 -1
  151. package/dist/research/extract-texts.d.ts.map +1 -1
  152. package/dist/research/extract-texts.js +34 -16
  153. package/dist/research/extract-texts.js.map +1 -1
  154. package/dist/research/filingramp/attachment-tools.d.ts.map +1 -1
  155. package/dist/research/filingramp/attachment-tools.js +7 -4
  156. package/dist/research/filingramp/attachment-tools.js.map +1 -1
  157. package/dist/research/filingramp/shared.d.ts.map +1 -1
  158. package/dist/research/filingramp/shared.js +5 -5
  159. package/dist/research/filingramp/shared.js.map +1 -1
  160. package/dist/research/prompt.d.ts.map +1 -1
  161. package/dist/research/prompt.js +2 -1
  162. package/dist/research/prompt.js.map +1 -1
  163. package/dist/runtime/app-mode.d.ts +10 -0
  164. package/dist/runtime/app-mode.d.ts.map +1 -0
  165. package/dist/runtime/app-mode.js +172 -0
  166. package/dist/runtime/app-mode.js.map +1 -0
  167. package/dist/runtime/app-mode.test.d.ts +2 -0
  168. package/dist/runtime/app-mode.test.d.ts.map +1 -0
  169. package/dist/runtime/app-mode.test.js +130 -0
  170. package/dist/runtime/app-mode.test.js.map +1 -0
  171. package/dist/runtime/app-rehearsal.d.ts +2 -0
  172. package/dist/runtime/app-rehearsal.d.ts.map +1 -0
  173. package/dist/runtime/app-rehearsal.js +56 -0
  174. package/dist/runtime/app-rehearsal.js.map +1 -0
  175. package/dist/runtime/build-mode.d.ts +12 -0
  176. package/dist/runtime/build-mode.d.ts.map +1 -0
  177. package/dist/runtime/build-mode.js +116 -0
  178. package/dist/runtime/build-mode.js.map +1 -0
  179. package/dist/runtime/build-mode.test.d.ts +2 -0
  180. package/dist/runtime/build-mode.test.d.ts.map +1 -0
  181. package/dist/runtime/build-mode.test.js +121 -0
  182. package/dist/runtime/build-mode.test.js.map +1 -0
  183. package/dist/runtime/cli.js +7 -2
  184. package/dist/runtime/cli.js.map +1 -1
  185. package/dist/runtime/config.d.ts +4 -0
  186. package/dist/runtime/config.d.ts.map +1 -1
  187. package/dist/runtime/config.js +13 -2
  188. package/dist/runtime/config.js.map +1 -1
  189. package/dist/runtime/guest-server.d.ts +3 -0
  190. package/dist/runtime/guest-server.d.ts.map +1 -0
  191. package/dist/runtime/{lambda-microvm.js → guest-server.js} +49 -18
  192. package/dist/runtime/guest-server.js.map +1 -0
  193. package/dist/runtime/image-hooks.d.ts +5 -0
  194. package/dist/runtime/image-hooks.d.ts.map +1 -0
  195. package/dist/runtime/image-hooks.js +68 -0
  196. package/dist/runtime/image-hooks.js.map +1 -0
  197. package/dist/runtime/image-hooks.test.d.ts +2 -0
  198. package/dist/runtime/image-hooks.test.d.ts.map +1 -0
  199. package/dist/runtime/image-hooks.test.js +74 -0
  200. package/dist/runtime/image-hooks.test.js.map +1 -0
  201. package/dist/runtime/index.d.ts +8 -3
  202. package/dist/runtime/index.d.ts.map +1 -1
  203. package/dist/runtime/index.js +53 -35
  204. package/dist/runtime/index.js.map +1 -1
  205. package/dist/runtime/listening-ports.d.ts +13 -0
  206. package/dist/runtime/listening-ports.d.ts.map +1 -0
  207. package/dist/runtime/listening-ports.js +78 -0
  208. package/dist/runtime/listening-ports.js.map +1 -0
  209. package/dist/runtime/listening-ports.test.d.ts +2 -0
  210. package/dist/runtime/listening-ports.test.d.ts.map +1 -0
  211. package/dist/runtime/listening-ports.test.js +39 -0
  212. package/dist/runtime/listening-ports.test.js.map +1 -0
  213. package/dist/runtime/preview-proxy.d.ts +56 -0
  214. package/dist/runtime/preview-proxy.d.ts.map +1 -0
  215. package/dist/runtime/preview-proxy.js +302 -0
  216. package/dist/runtime/preview-proxy.js.map +1 -0
  217. package/dist/runtime/preview-proxy.test.d.ts +2 -0
  218. package/dist/runtime/preview-proxy.test.d.ts.map +1 -0
  219. package/dist/runtime/preview-proxy.test.js +122 -0
  220. package/dist/runtime/preview-proxy.test.js.map +1 -0
  221. package/dist/runtime/session-mode.d.ts +3 -0
  222. package/dist/runtime/session-mode.d.ts.map +1 -0
  223. package/dist/runtime/session-mode.js +60 -0
  224. package/dist/runtime/session-mode.js.map +1 -0
  225. package/dist/runtime/workload.d.ts +44 -0
  226. package/dist/runtime/workload.d.ts.map +1 -0
  227. package/dist/runtime/workload.js +222 -0
  228. package/dist/runtime/workload.js.map +1 -0
  229. package/dist/runtime/workload.test.d.ts +2 -0
  230. package/dist/runtime/workload.test.d.ts.map +1 -0
  231. package/dist/runtime/workload.test.js +235 -0
  232. package/dist/runtime/workload.test.js.map +1 -0
  233. package/dist/session/conversation.d.ts +10 -2
  234. package/dist/session/conversation.d.ts.map +1 -1
  235. package/dist/session/conversation.js +40 -12
  236. package/dist/session/conversation.js.map +1 -1
  237. package/dist/session/conversation.test.js +2 -3
  238. package/dist/session/conversation.test.js.map +1 -1
  239. package/dist/session/index.d.ts +1 -1
  240. package/dist/session/index.d.ts.map +1 -1
  241. package/dist/session/index.js +2 -1
  242. package/dist/session/index.js.map +1 -1
  243. package/dist/session/runtime.d.ts +20 -3
  244. package/dist/session/runtime.d.ts.map +1 -1
  245. package/dist/session/runtime.js +97 -16
  246. package/dist/session/runtime.js.map +1 -1
  247. package/dist/session/runtime.test.js +18 -7
  248. package/dist/session/runtime.test.js.map +1 -1
  249. package/dist/session/tools.d.ts.map +1 -1
  250. package/dist/session/tools.js +5 -4
  251. package/dist/session/tools.js.map +1 -1
  252. package/dist/task/loop.d.ts.map +1 -1
  253. package/dist/task/loop.js +6 -4
  254. package/dist/task/loop.js.map +1 -1
  255. package/dist/tools/exec-tools.d.ts +12 -0
  256. package/dist/tools/exec-tools.d.ts.map +1 -1
  257. package/dist/tools/exec-tools.js +46 -3
  258. package/dist/tools/exec-tools.js.map +1 -1
  259. package/dist/tools/exec-tools.test.d.ts +2 -0
  260. package/dist/tools/exec-tools.test.d.ts.map +1 -0
  261. package/dist/tools/exec-tools.test.js +48 -0
  262. package/dist/tools/exec-tools.test.js.map +1 -0
  263. package/dist/tools/fs-tools.d.ts.map +1 -1
  264. package/dist/tools/fs-tools.js +5 -5
  265. package/dist/tools/fs-tools.js.map +1 -1
  266. package/dist/transport/link.d.ts.map +1 -1
  267. package/dist/transport/link.js +16 -5
  268. package/dist/transport/link.js.map +1 -1
  269. package/dist/transport/link.test.js +24 -0
  270. package/dist/transport/link.test.js.map +1 -1
  271. package/dist/transport/protocol.d.ts +190 -3
  272. package/dist/transport/protocol.d.ts.map +1 -1
  273. package/dist/transport/protocol.js +147 -7
  274. package/dist/transport/protocol.js.map +1 -1
  275. package/dist/transport/protocol.test.js +41 -0
  276. package/dist/transport/protocol.test.js.map +1 -1
  277. package/dist/workspace-sync/eligibility.d.ts +14 -0
  278. package/dist/workspace-sync/eligibility.d.ts.map +1 -0
  279. package/dist/workspace-sync/eligibility.js +53 -0
  280. package/dist/workspace-sync/eligibility.js.map +1 -0
  281. package/dist/workspace-sync/merge.d.ts +15 -0
  282. package/dist/workspace-sync/merge.d.ts.map +1 -0
  283. package/dist/workspace-sync/merge.js +66 -0
  284. package/dist/workspace-sync/merge.js.map +1 -0
  285. package/dist/workspace-sync/merge.test.d.ts +2 -0
  286. package/dist/workspace-sync/merge.test.d.ts.map +1 -0
  287. package/dist/workspace-sync/merge.test.js +28 -0
  288. package/dist/workspace-sync/merge.test.js.map +1 -0
  289. package/dist/workspace-sync/workspace-sync.d.ts +48 -0
  290. package/dist/workspace-sync/workspace-sync.d.ts.map +1 -0
  291. package/dist/workspace-sync/workspace-sync.js +308 -0
  292. package/dist/workspace-sync/workspace-sync.js.map +1 -0
  293. package/dist/workspace-sync/workspace-sync.test.d.ts +2 -0
  294. package/dist/workspace-sync/workspace-sync.test.d.ts.map +1 -0
  295. package/dist/workspace-sync/workspace-sync.test.js +111 -0
  296. package/dist/workspace-sync/workspace-sync.test.js.map +1 -0
  297. package/dist/workspace-sync/write-drafts.d.ts +24 -0
  298. package/dist/workspace-sync/write-drafts.d.ts.map +1 -0
  299. package/dist/workspace-sync/write-drafts.js +87 -0
  300. package/dist/workspace-sync/write-drafts.js.map +1 -0
  301. package/dist/workspace-sync/write-drafts.test.d.ts +2 -0
  302. package/dist/workspace-sync/write-drafts.test.d.ts.map +1 -0
  303. package/dist/workspace-sync/write-drafts.test.js +36 -0
  304. package/dist/workspace-sync/write-drafts.test.js.map +1 -0
  305. package/package.json +12 -2
  306. package/dist/runtime/lambda-microvm.d.ts +0 -3
  307. package/dist/runtime/lambda-microvm.d.ts.map +0 -1
  308. package/dist/runtime/lambda-microvm.js.map +0 -1
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fetchRelease = fetchRelease;
7
+ exports.startDeployedApp = startDeployedApp;
8
+ // AGENT_MODE=app: a deployment of an app (detected, or as builder.json says) on the app image, with
9
+ // no agent in it. A release built ahead of time (AGENT_MODE=build) arrives as its archive, dependencies
10
+ // and all, and is only started. An older one arrives as a standalone session's saved workspace and is
11
+ // installed and built here. The guest's port 8080 serves it (preview-proxy.ts serveAppUnaddressed).
12
+ const node_child_process_1 = require("node:child_process");
13
+ const node_fs_1 = require("node:fs");
14
+ const node_path_1 = __importDefault(require("node:path"));
15
+ const node_stream_1 = require("node:stream");
16
+ const node_util_1 = require("node:util");
17
+ const protocol_1 = require("../transport/protocol");
18
+ const workload_1 = require("./workload");
19
+ const app_host_1 = require("../app/app-host");
20
+ const env_1 = require("../app/env");
21
+ const snapshot_sync_1 = require("../persistence/snapshot-sync");
22
+ const preview_proxy_1 = require("./preview-proxy");
23
+ const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
24
+ const DEFAULT_RELEASE_DIR = '/workspace/release';
25
+ const GIT_TIMEOUT_MS = 120000;
26
+ const RESTORE_ATTEMPTS = 3;
27
+ const RESTORE_TIMEOUT_MS = 5 * 60000;
28
+ const RESTORE_RETRY_MS = 1000;
29
+ /** A release that can't be restored however many times it's asked for. */
30
+ class ReleaseNotRestorable extends Error {
31
+ }
32
+ async function exists(target) {
33
+ return node_fs_1.promises.access(target).then(() => true, () => false);
34
+ }
35
+ /** `relative` inside `root`, or an error: an app's directory must not escape its repository. */
36
+ function insideDir(root, relative) {
37
+ const dir = node_path_1.default.resolve(root, relative || '.');
38
+ if (!(0, workload_1.isInsideDir)(root, dir))
39
+ throw new Error('The app directory is outside the release');
40
+ return dir;
41
+ }
42
+ /** Clones the release's repository at its pinned commit (once: a restarted VM keeps its disk). */
43
+ async function cloneRelease(env) {
44
+ const serverUrl = env[protocol_1.AGENT_ENV.GIT_SERVER_URL];
45
+ const repository = env[protocol_1.AGENT_ENV.GIT_REPOSITORY];
46
+ const commit = env[protocol_1.AGENT_ENV.GIT_COMMIT];
47
+ const token = env[protocol_1.AGENT_ENV.ACCESS_TOKEN];
48
+ if (!serverUrl || !repository || !commit || !token)
49
+ throw new Error('The release settings are incomplete (Git server, repository, commit or token)');
50
+ const target = node_path_1.default.resolve(env[protocol_1.AGENT_ENV.GIT_REPOSITORY_DIR] || DEFAULT_RELEASE_DIR);
51
+ if (!(await exists(target))) {
52
+ // The token rides a per-process header, never the remote URL or .git/config.
53
+ const gitEnv = { ...process.env, GIT_TERMINAL_PROMPT: '0', GIT_CONFIG_COUNT: '1', GIT_CONFIG_KEY_0: 'http.extraheader', GIT_CONFIG_VALUE_0: `Authorization: Bearer ${token}` };
54
+ const staging = `${target}.partial`;
55
+ await node_fs_1.promises.rm(staging, { recursive: true, force: true });
56
+ await node_fs_1.promises.mkdir(node_path_1.default.dirname(target), { recursive: true });
57
+ await execFileAsync('git', ['clone', '--quiet', `${serverUrl.replace(/\/+$/, '')}/git/${repository}.git`, staging], { env: gitEnv, timeout: GIT_TIMEOUT_MS });
58
+ await execFileAsync('git', ['-C', staging, 'checkout', '--quiet', '--detach', commit], { env: gitEnv, timeout: GIT_TIMEOUT_MS });
59
+ // A deployment only needs its pinned files, as on QEMU/Firecracker (microvm/init).
60
+ await node_fs_1.promises.rm(node_path_1.default.join(staging, '.git'), { recursive: true, force: true });
61
+ await node_fs_1.promises.rename(staging, target);
62
+ }
63
+ await (0, workload_1.handOverToWorkload)(target);
64
+ return insideDir(target, env[protocol_1.AGENT_ENV.APP_ROOT_DIR]);
65
+ }
66
+ /** Restores the workspace a standalone session's release was cut with. */
67
+ async function restoreSavedWorkspace(url, env) {
68
+ const token = env[protocol_1.AGENT_ENV.ACCESS_TOKEN];
69
+ if (!token)
70
+ throw new Error('The release settings are incomplete (token)');
71
+ const dir = node_path_1.default.resolve(env[protocol_1.AGENT_ENV.AGENT_WORKSPACE_DIR] || DEFAULT_RELEASE_DIR);
72
+ if (!(await new snapshot_sync_1.SessionStorageSync({ url, token, dir }).restore()))
73
+ throw new Error('The release has no saved files');
74
+ await (0, workload_1.handOverToWorkload)(dir);
75
+ return dir;
76
+ }
77
+ /**
78
+ * Restores a built release: its archive, streamed straight into tar, then its config. That goes last,
79
+ * so a folder that has it is complete, and a restarted VM, which keeps its disk, has nothing to do.
80
+ * It lands where it was built (DEFAULT_RELEASE_DIR on both), as a virtualenv or a package manager's
81
+ * links can hold absolute paths.
82
+ */
83
+ async function restoreBuiltRelease(url, env) {
84
+ const token = env[protocol_1.AGENT_ENV.ACCESS_TOKEN];
85
+ if (!token)
86
+ throw new Error('The release settings are incomplete (token)');
87
+ const dir = node_path_1.default.resolve(env[protocol_1.AGENT_ENV.AGENT_WORKSPACE_DIR] || DEFAULT_RELEASE_DIR);
88
+ const config = node_path_1.default.join(dir, protocol_1.APP_CONFIG_FILE);
89
+ if (await exists(config))
90
+ return dir;
91
+ await node_fs_1.promises.mkdir(dir, { recursive: true });
92
+ await (0, workload_1.handOverToWorkload)(dir);
93
+ const get = async (route) => {
94
+ const response = await fetch(`${url.replace(/\/+$/, '')}${route}`, {
95
+ headers: { Authorization: `Bearer ${token}` },
96
+ signal: AbortSignal.timeout(RESTORE_TIMEOUT_MS),
97
+ });
98
+ if (response.status === 404) {
99
+ throw new ReleaseNotRestorable('This release was built before releases carried their dependencies: make a new release to deploy it');
100
+ }
101
+ if (response.status < 500 && !response.ok)
102
+ throw new ReleaseNotRestorable(`Reading ${route} was refused: ${response.status}`);
103
+ if (!response.ok)
104
+ throw new Error(`Reading ${route} failed: ${response.status}`);
105
+ return response;
106
+ };
107
+ for (let attempt = 1;; attempt += 1) {
108
+ try {
109
+ const settings = Buffer.from(await (await get((0, snapshot_sync_1.fileRoute)(protocol_1.APP_CONFIG_FILE))).arrayBuffer());
110
+ const archive = await get(`/${protocol_1.RELEASE_ARCHIVE_FILE}`);
111
+ if (!archive.body)
112
+ throw new Error('The release archive is empty');
113
+ await (0, workload_1.unpackAsWorkload)(dir, node_stream_1.Readable.fromWeb(archive.body));
114
+ await (0, workload_1.writeWorkloadFile)(config, settings);
115
+ return dir;
116
+ }
117
+ catch (error) {
118
+ if (error instanceof ReleaseNotRestorable || attempt >= RESTORE_ATTEMPTS)
119
+ throw error;
120
+ console.error(`[app] restoring the release failed, trying again: ${error instanceof Error ? error.message : String(error)}`);
121
+ await new Promise((resolve) => setTimeout(resolve, RESTORE_RETRY_MS * attempt));
122
+ }
123
+ }
124
+ }
125
+ /** The released app's directory, fetched if this VM doesn't have it yet. */
126
+ async function fetchRelease(env) {
127
+ // QEMU/Firecracker's init already checked the commit out (and removed .git).
128
+ if (env.APP_WORK_DIR && (await exists(env.APP_WORK_DIR))) {
129
+ await (0, workload_1.handOverToWorkload)(env.APP_WORK_DIR);
130
+ return env.APP_WORK_DIR;
131
+ }
132
+ const built = env[protocol_1.AGENT_ENV.RELEASE_ARTIFACTS_URL];
133
+ if (built)
134
+ return restoreBuiltRelease(built, env);
135
+ const saved = env[protocol_1.AGENT_ENV.SESSION_STORAGE_URL];
136
+ if (saved)
137
+ return restoreSavedWorkspace(saved, env);
138
+ return cloneRelease(env);
139
+ }
140
+ /** Serves the deployment's app on the guest's port 8080: "starting" pages until it runs. */
141
+ async function startDeployedApp(env = process.env) {
142
+ (0, preview_proxy_1.serveAppUnaddressed)();
143
+ let dir;
144
+ try {
145
+ dir = await fetchRelease(env);
146
+ }
147
+ catch (error) {
148
+ const message = error instanceof Error ? error.message : String(error);
149
+ console.error('[app] release fetch failed:', message);
150
+ // Report it through the status route (the gateway's start check) and the app's own page.
151
+ const failed = new app_host_1.AppHost({ dir: '/nonexistent', mode: 'production', env: {} });
152
+ failed.fail(`The release could not be fetched: ${message}`);
153
+ (0, preview_proxy_1.setAppHandler)(failed);
154
+ return { host: failed, async close() { } };
155
+ }
156
+ const host = new app_host_1.AppHost({
157
+ dir,
158
+ mode: 'production',
159
+ env: (0, env_1.deployedAppEnv)(env),
160
+ echoOutput: true,
161
+ buildId: env[protocol_1.AGENT_ENV.APP_RELEASE_ID] || env[protocol_1.AGENT_ENV.GIT_COMMIT],
162
+ prebuilt: Boolean(env[protocol_1.AGENT_ENV.RELEASE_ARTIFACTS_URL]),
163
+ });
164
+ (0, preview_proxy_1.setAppHandler)(host);
165
+ host.onStatus((status) => console.log(`[app] ${status ? status.phase : 'no app'}${(status === null || status === void 0 ? void 0 : status.error) ? `: ${status.error}` : ''}`));
166
+ void host.start().then((status) => {
167
+ if (!status)
168
+ host.fail('No app found in the release: no framework, package.json scripts, Python app or index.html, and no builder.json');
169
+ }, (error) => host.fail(`The app could not start: ${error instanceof Error ? error.message : String(error)}`));
170
+ return { host, close: () => host.stop() };
171
+ }
172
+ //# sourceMappingURL=app-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-mode.js","sourceRoot":"","sources":["../../src/runtime/app-mode.ts"],"names":[],"mappings":";;;;;AAkHA,oCAWC;AAQD,4CA4BC;AAjKD,oGAAoG;AACpG,wGAAwG;AACxG,sGAAsG;AACtG,oGAAoG;AACpG,2DAA6C;AAC7C,qCAAwC;AACxC,0DAA4B;AAC5B,6CAAsC;AACtC,yCAAqC;AACrC,oDAAwF;AACxF,yCAAiG;AACjG,8CAAyC;AACzC,oCAA2C;AAC3C,gEAA4E;AAC5E,mDAAoE;AAEpE,MAAM,aAAa,GAAG,IAAA,qBAAS,EAAC,6BAAQ,CAAC,CAAA;AACzC,MAAM,mBAAmB,GAAG,oBAAoB,CAAA;AAChD,MAAM,cAAc,GAAG,MAAO,CAAA;AAC9B,MAAM,gBAAgB,GAAG,CAAC,CAAA;AAC1B,MAAM,kBAAkB,GAAG,CAAC,GAAG,KAAM,CAAA;AACrC,MAAM,gBAAgB,GAAG,IAAK,CAAA;AAE9B,0EAA0E;AAC1E,MAAM,oBAAqB,SAAQ,KAAK;CAAG;AAE3C,KAAK,UAAU,MAAM,CAAC,MAAc;IAClC,OAAO,kBAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAA;AACxD,CAAC;AAED,gGAAgG;AAChG,SAAS,SAAS,CAAC,IAAY,EAAE,QAA4B;IAC3D,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,IAAI,GAAG,CAAC,CAAA;IAC/C,IAAI,CAAC,IAAA,sBAAW,EAAC,IAAI,EAAE,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAA;IACxF,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,kGAAkG;AAClG,KAAK,UAAU,YAAY,CAAC,GAAsB;IAChD,MAAM,SAAS,GAAG,GAAG,CAAC,oBAAS,CAAC,cAAc,CAAC,CAAA;IAC/C,MAAM,UAAU,GAAG,GAAG,CAAC,oBAAS,CAAC,cAAc,CAAC,CAAA;IAChD,MAAM,MAAM,GAAG,GAAG,CAAC,oBAAS,CAAC,UAAU,CAAC,CAAA;IACxC,MAAM,KAAK,GAAG,GAAG,CAAC,oBAAS,CAAC,YAAY,CAAC,CAAA;IACzC,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAA;IACpJ,MAAM,MAAM,GAAG,mBAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAS,CAAC,kBAAkB,CAAC,IAAI,mBAAmB,CAAC,CAAA;IACrF,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAC5B,6EAA6E;QAC7E,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,mBAAmB,EAAE,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,yBAAyB,KAAK,EAAE,EAAE,CAAA;QAC9K,MAAM,OAAO,GAAG,GAAG,MAAM,UAAU,CAAA;QACnC,MAAM,kBAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACtD,MAAM,kBAAE,CAAC,KAAK,CAAC,mBAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QACzD,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,UAAU,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAA;QAC7J,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAA;QAChI,mFAAmF;QACnF,MAAM,kBAAE,CAAC,EAAE,CAAC,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACzE,MAAM,kBAAE,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAClC,CAAC;IACD,MAAM,IAAA,6BAAkB,EAAC,MAAM,CAAC,CAAA;IAChC,OAAO,SAAS,CAAC,MAAM,EAAE,GAAG,CAAC,oBAAS,CAAC,YAAY,CAAC,CAAC,CAAA;AACvD,CAAC;AAED,0EAA0E;AAC1E,KAAK,UAAU,qBAAqB,CAAC,GAAW,EAAE,GAAsB;IACtE,MAAM,KAAK,GAAG,GAAG,CAAC,oBAAS,CAAC,YAAY,CAAC,CAAA;IACzC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAC1E,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAS,CAAC,mBAAmB,CAAC,IAAI,mBAAmB,CAAC,CAAA;IACnF,IAAI,CAAC,CAAC,MAAM,IAAI,kCAAkB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACrH,MAAM,IAAA,6BAAkB,EAAC,GAAG,CAAC,CAAA;IAC7B,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,mBAAmB,CAAC,GAAW,EAAE,GAAsB;IACpE,MAAM,KAAK,GAAG,GAAG,CAAC,oBAAS,CAAC,YAAY,CAAC,CAAA;IACzC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAA;IAC1E,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAS,CAAC,mBAAmB,CAAC,IAAI,mBAAmB,CAAC,CAAA;IACnF,MAAM,MAAM,GAAG,mBAAI,CAAC,IAAI,CAAC,GAAG,EAAE,0BAAe,CAAC,CAAA;IAC9C,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,GAAG,CAAA;IACpC,MAAM,kBAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxC,MAAM,IAAA,6BAAkB,EAAC,GAAG,CAAC,CAAA;IAC7B,MAAM,GAAG,GAAG,KAAK,EAAE,KAAa,EAAqB,EAAE;QACrD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE;YACjE,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;YAC7C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;SAChD,CAAC,CAAA;QACF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,oBAAoB,CAAC,oGAAoG,CAAC,CAAA;QACtI,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,oBAAoB,CAAC,WAAW,KAAK,iBAAiB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QAC7H,IAAI,CAAC,QAAQ,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,YAAY,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;QAChF,OAAO,QAAQ,CAAA;IACjB,CAAC,CAAA;IACD,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAA,yBAAS,EAAC,0BAAe,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAA;YACzF,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,IAAI,+BAAoB,EAAE,CAAC,CAAA;YACrD,IAAI,CAAC,OAAO,CAAC,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;YAClE,MAAM,IAAA,2BAAgB,EAAC,GAAG,EAAE,sBAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAA8C,CAAC,CAAC,CAAA;YACrG,MAAM,IAAA,4BAAiB,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;YACzC,OAAO,GAAG,CAAA;QACZ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,oBAAoB,IAAI,OAAO,IAAI,gBAAgB;gBAAE,MAAM,KAAK,CAAA;YACrF,OAAO,CAAC,KAAK,CAAC,qDAAqD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YAC5H,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,CAAA;QACjF,CAAC;IACH,CAAC;AACH,CAAC;AAED,4EAA4E;AACrE,KAAK,UAAU,YAAY,CAAC,GAAsB;IACvD,6EAA6E;IAC7E,IAAI,GAAG,CAAC,YAAY,IAAI,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;QACzD,MAAM,IAAA,6BAAkB,EAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAC1C,OAAO,GAAG,CAAC,YAAY,CAAA;IACzB,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,oBAAS,CAAC,qBAAqB,CAAC,CAAA;IAClD,IAAI,KAAK;QAAE,OAAO,mBAAmB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,GAAG,CAAC,oBAAS,CAAC,mBAAmB,CAAC,CAAA;IAChD,IAAI,KAAK;QAAE,OAAO,qBAAqB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACnD,OAAO,YAAY,CAAC,GAAG,CAAC,CAAA;AAC1B,CAAC;AAOD,4FAA4F;AACrF,KAAK,UAAU,gBAAgB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACzE,IAAA,mCAAmB,GAAE,CAAA;IACrB,IAAI,GAAW,CAAA;IACf,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAA;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACtE,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,OAAO,CAAC,CAAA;QACrD,yFAAyF;QACzF,MAAM,MAAM,GAAG,IAAI,kBAAO,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAA;QAChF,MAAM,CAAC,IAAI,CAAC,qCAAqC,OAAO,EAAE,CAAC,CAAA;QAC3D,IAAA,6BAAa,EAAC,MAAM,CAAC,CAAA;QACrB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,KAAI,CAAC,EAAE,CAAA;IAC3C,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,kBAAO,CAAC;QACvB,GAAG;QACH,IAAI,EAAE,YAAY;QAClB,GAAG,EAAE,IAAA,oBAAc,EAAC,GAAG,CAAC;QACxB,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,GAAG,CAAC,oBAAS,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,oBAAS,CAAC,UAAU,CAAC;QACnE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAS,CAAC,qBAAqB,CAAC,CAAC;KACxD,CAAC,CAAA;IACF,IAAA,6BAAa,EAAC,IAAI,CAAC,CAAA;IACnB,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,KAAK,EAAC,CAAC,CAAC,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;IAC9H,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QAChC,IAAI,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,gHAAgH,CAAC,CAAA;IAC1I,CAAC,EAAE,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,4BAA4B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;IACvH,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAA;AAC3C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=app-mode.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-mode.test.d.ts","sourceRoot":"","sources":["../../src/runtime/app-mode.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const strict_1 = __importDefault(require("node:assert/strict"));
7
+ const node_fs_1 = require("node:fs");
8
+ const node_http_1 = __importDefault(require("node:http"));
9
+ const node_os_1 = __importDefault(require("node:os"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const node_stream_1 = require("node:stream");
12
+ const node_test_1 = require("node:test");
13
+ const app_mode_1 = require("./app-mode");
14
+ const workload_1 = require("./workload");
15
+ const CONFIG = JSON.stringify({ services: { api: { startCommand: 'node server.js' } } });
16
+ (0, node_test_1.describe)('restoring a built release', () => {
17
+ let server;
18
+ let url;
19
+ let dir;
20
+ let archive;
21
+ let requests;
22
+ let answer;
23
+ let env;
24
+ (0, node_test_1.before)(async () => {
25
+ const source = await node_fs_1.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), 'builder-built-'));
26
+ await node_fs_1.promises.mkdir(node_path_1.default.join(source, 'node_modules/x'), { recursive: true });
27
+ await node_fs_1.promises.writeFile(node_path_1.default.join(source, 'server.js'), 'server');
28
+ await node_fs_1.promises.writeFile(node_path_1.default.join(source, 'node_modules/x/index.js'), 'dep');
29
+ await node_fs_1.promises.chmod(source, 0o755);
30
+ await (0, workload_1.handOverToWorkload)(source);
31
+ const chunks = [];
32
+ const sink = new node_stream_1.PassThrough();
33
+ sink.on('data', (chunk) => chunks.push(chunk));
34
+ await (0, workload_1.packAsWorkload)(source, ['.'], [], sink);
35
+ archive = Buffer.concat(chunks);
36
+ await node_fs_1.promises.rm(source, { recursive: true, force: true });
37
+ server = node_http_1.default.createServer((req, res) => {
38
+ requests.push({ url: req.url, authorization: req.headers.authorization });
39
+ const attempt = requests.filter((item) => item.url === req.url).length;
40
+ const status = answer(req.url, attempt);
41
+ if (status !== 200)
42
+ return void res.writeHead(status).end();
43
+ res.writeHead(200).end(req.url.endsWith('/run.tar.zst') ? archive : CONFIG);
44
+ });
45
+ await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve));
46
+ url = `http://127.0.0.1:${server.address().port}/release-artifacts/a/r`;
47
+ });
48
+ (0, node_test_1.after)(() => {
49
+ server.closeAllConnections();
50
+ server.close();
51
+ });
52
+ (0, node_test_1.beforeEach)(async () => {
53
+ requests = [];
54
+ answer = () => 200;
55
+ dir = node_path_1.default.join(await node_fs_1.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), 'builder-restore-')), 'release');
56
+ await node_fs_1.promises.chmod(node_path_1.default.dirname(dir), 0o755);
57
+ env = { RELEASE_ARTIFACTS_URL: url, ACCESS_TOKEN: 'tok', AGENT_WORKSPACE_DIR: dir };
58
+ });
59
+ (0, node_test_1.afterEach)(() => node_fs_1.promises.rm(node_path_1.default.dirname(dir), { recursive: true, force: true }));
60
+ const archiveAsked = () => requests.filter((request) => { var _a; return (_a = request.url) === null || _a === void 0 ? void 0 : _a.endsWith('/run.tar.zst'); }).length;
61
+ (0, node_test_1.it)('unpacks what the build left, dependencies too, with its config, using the VM\'s token', async () => {
62
+ strict_1.default.equal(await (0, app_mode_1.fetchRelease)(env), dir);
63
+ strict_1.default.equal(await node_fs_1.promises.readFile(node_path_1.default.join(dir, 'node_modules/x/index.js'), 'utf8'), 'dep');
64
+ strict_1.default.equal(await node_fs_1.promises.readFile(node_path_1.default.join(dir, 'server.js'), 'utf8'), 'server');
65
+ strict_1.default.equal(await node_fs_1.promises.readFile(node_path_1.default.join(dir, '.builder/builder.json'), 'utf8'), CONFIG);
66
+ strict_1.default.ok(requests.every((request) => request.authorization === 'Bearer tok'));
67
+ });
68
+ (0, node_test_1.it)('has nothing to do on a VM that kept its disk', async () => {
69
+ await (0, app_mode_1.fetchRelease)(env);
70
+ requests = [];
71
+ await node_fs_1.promises.writeFile(node_path_1.default.join(dir, 'written-since'), 'kept');
72
+ strict_1.default.equal(await (0, app_mode_1.fetchRelease)(env), dir);
73
+ strict_1.default.deepEqual(requests, []);
74
+ strict_1.default.equal(await node_fs_1.promises.readFile(node_path_1.default.join(dir, 'written-since'), 'utf8'), 'kept');
75
+ });
76
+ (0, node_test_1.it)('tells someone with a release from before this what to do, without asking again', async () => {
77
+ answer = (route) => (route.endsWith('/run.tar.zst') ? 404 : 200);
78
+ await strict_1.default.rejects((0, app_mode_1.fetchRelease)(env), /make a new release/);
79
+ strict_1.default.equal(archiveAsked(), 1);
80
+ await strict_1.default.rejects(node_fs_1.promises.access(node_path_1.default.join(dir, '.builder/builder.json')));
81
+ });
82
+ (0, node_test_1.it)('doesn\'t ask again when it\'s refused', async () => {
83
+ answer = (route) => (route.endsWith('/run.tar.zst') ? 403 : 200);
84
+ await strict_1.default.rejects((0, app_mode_1.fetchRelease)(env), /refused: 403/);
85
+ strict_1.default.equal(archiveAsked(), 1);
86
+ });
87
+ (0, node_test_1.it)('tries again when storage stumbles, and finishes', async () => {
88
+ answer = (route, attempt) => (route.endsWith('/run.tar.zst') && attempt === 1 ? 503 : 200);
89
+ strict_1.default.equal(await (0, app_mode_1.fetchRelease)(env), dir);
90
+ strict_1.default.equal(archiveAsked(), 2);
91
+ strict_1.default.equal(await node_fs_1.promises.readFile(node_path_1.default.join(dir, 'server.js'), 'utf8'), 'server');
92
+ });
93
+ (0, node_test_1.it)('starts over when the connection drops halfway, and has no config until it\'s whole', async () => {
94
+ let cut = 0;
95
+ const whole = server.listeners('request')[0];
96
+ server.removeAllListeners('request');
97
+ server.on('request', (req, res) => {
98
+ if (!req.url.endsWith('/run.tar.zst') || cut++ > 0)
99
+ return whole(req, res);
100
+ requests.push({ url: req.url, authorization: req.headers.authorization });
101
+ res.writeHead(200, { 'Content-Length': archive.length });
102
+ res.write(archive.subarray(0, archive.length / 2), () => res.destroy());
103
+ });
104
+ try {
105
+ strict_1.default.equal(await (0, app_mode_1.fetchRelease)(env), dir);
106
+ }
107
+ finally {
108
+ server.removeAllListeners('request');
109
+ server.on('request', whole);
110
+ }
111
+ strict_1.default.equal(archiveAsked(), 2);
112
+ strict_1.default.equal(await node_fs_1.promises.readFile(node_path_1.default.join(dir, 'node_modules/x/index.js'), 'utf8'), 'dep');
113
+ strict_1.default.equal(await node_fs_1.promises.readFile(node_path_1.default.join(dir, '.builder/builder.json'), 'utf8'), CONFIG);
114
+ });
115
+ (0, node_test_1.it)('never takes what isn\'t an archive, and leaves no config', async () => {
116
+ const whole = archive;
117
+ archive = Buffer.from('not an archive');
118
+ try {
119
+ await strict_1.default.rejects((0, app_mode_1.fetchRelease)(env));
120
+ await strict_1.default.rejects(node_fs_1.promises.access(node_path_1.default.join(dir, '.builder/builder.json')));
121
+ }
122
+ finally {
123
+ archive = whole;
124
+ }
125
+ });
126
+ (0, node_test_1.it)('needs a token', async () => {
127
+ await strict_1.default.rejects((0, app_mode_1.fetchRelease)({ ...env, ACCESS_TOKEN: '' }), /incomplete/);
128
+ });
129
+ });
130
+ //# sourceMappingURL=app-mode.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-mode.test.js","sourceRoot":"","sources":["../../src/runtime/app-mode.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function rehearseColdStart(): Promise<void>;
2
+ //# sourceMappingURL=app-rehearsal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-rehearsal.d.ts","sourceRoot":"","sources":["../../src/runtime/app-rehearsal.ts"],"names":[],"mappings":"AAcA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAoCvD"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.rehearseColdStart = rehearseColdStart;
7
+ // A cold start of an app, rehearsed on a VM from a new image: a release unpacked, and a server started
8
+ // and asked for something, the way a deployment's are. Whether the image can do that is what its
9
+ // /validate hook answers, and doing it shows Lambda which parts of the snapshot a start touches.
10
+ const node_fs_1 = require("node:fs");
11
+ const node_os_1 = __importDefault(require("node:os"));
12
+ const node_path_1 = __importDefault(require("node:path"));
13
+ const node_stream_1 = require("node:stream");
14
+ const runner_1 = require("../app/runner");
15
+ const workload_1 = require("./workload");
16
+ const SERVER = "require('http').createServer((_req, res) => res.end('ok')).listen(process.env.PORT, '127.0.0.1')\n";
17
+ const START_TIMEOUT_MS = 30000;
18
+ const POLL_MS = 50;
19
+ async function rehearseColdStart() {
20
+ var _a, _b;
21
+ const root = await node_fs_1.promises.mkdtemp(node_path_1.default.join(node_os_1.default.tmpdir(), 'builder-rehearsal-'));
22
+ try {
23
+ const built = node_path_1.default.join(root, 'built');
24
+ const dir = node_path_1.default.join(root, 'release');
25
+ await node_fs_1.promises.mkdir(built);
26
+ await node_fs_1.promises.mkdir(dir);
27
+ await node_fs_1.promises.writeFile(node_path_1.default.join(built, 'server.js'), SERVER);
28
+ await node_fs_1.promises.chmod(root, 0o755);
29
+ await (0, workload_1.handOverToWorkload)(root);
30
+ const chunks = [];
31
+ const archive = new node_stream_1.PassThrough();
32
+ archive.on('data', (chunk) => chunks.push(chunk));
33
+ await (0, workload_1.packAsWorkload)(built, ['.'], [], archive);
34
+ await (0, workload_1.unpackAsWorkload)(dir, node_stream_1.Readable.from([Buffer.concat(chunks)]));
35
+ const runner = new runner_1.AppRunner({ services: { app: { root: '.', startCommand: 'node server.js' } } }, { dir, mode: 'production', env: { PATH: process.env.PATH }, prebuilt: true, readyPollMs: POLL_MS });
36
+ try {
37
+ await runner.start();
38
+ const deadline = Date.now() + START_TIMEOUT_MS;
39
+ while (runner.status().phase !== 'running') {
40
+ if (runner.status().error || Date.now() > deadline)
41
+ throw new Error((_a = runner.status().error) !== null && _a !== void 0 ? _a : 'The rehearsed app did not start');
42
+ await new Promise((resolve) => setTimeout(resolve, POLL_MS));
43
+ }
44
+ const response = await fetch(`http://127.0.0.1:${(_b = runner.status().processes[0]) === null || _b === void 0 ? void 0 : _b.port}/`);
45
+ if (!response.ok)
46
+ throw new Error(`The rehearsed app answered ${response.status}`);
47
+ }
48
+ finally {
49
+ await runner.stop();
50
+ }
51
+ }
52
+ finally {
53
+ await node_fs_1.promises.rm(root, { recursive: true, force: true });
54
+ }
55
+ }
56
+ //# sourceMappingURL=app-rehearsal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-rehearsal.js","sourceRoot":"","sources":["../../src/runtime/app-rehearsal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type AgentBuildStatus } from '../transport/protocol';
2
+ export interface ReleaseBuild {
3
+ status(): AgentBuildStatus;
4
+ /** Resolves when the build is over, however it went. */
5
+ finished: Promise<AgentBuildStatus>;
6
+ close(): Promise<void>;
7
+ }
8
+ /** Runs the build this VM is for. Never rejects: a failure is its status. */
9
+ export declare function runReleaseBuild(env: NodeJS.ProcessEnv): ReleaseBuild;
10
+ /** Starts the build, and answers on the guest's port 8080 how it's going. */
11
+ export declare function startReleaseBuild(env?: NodeJS.ProcessEnv): ReleaseBuild;
12
+ //# sourceMappingURL=build-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-mode.d.ts","sourceRoot":"","sources":["../../src/runtime/build-mode.ts"],"names":[],"mappings":"AAOA,OAAO,EAA8B,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAqBzF,MAAM,WAAW,YAAY;IAC3B,MAAM,IAAI,gBAAgB,CAAA;IAC1B,wDAAwD;IACxD,QAAQ,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,YAAY,CA8DpE;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,YAAY,CAcpF"}
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runReleaseBuild = runReleaseBuild;
7
+ exports.startReleaseBuild = startReleaseBuild;
8
+ // AGENT_MODE=build: one release's build, on a VM of its own with no agent in it. It fetches the
9
+ // source a deployment would, installs and builds it, and uploads the output as the release's
10
+ // artifacts (app/release-artifacts.ts). It reports on APP_STATUS_PATH and stays up: the gateway
11
+ // follows it from there and removes the VM when it's over.
12
+ const node_fs_1 = require("node:fs");
13
+ const node_path_1 = __importDefault(require("node:path"));
14
+ const protocol_1 = require("../transport/protocol");
15
+ const config_1 = require("../app/config");
16
+ const env_1 = require("../app/env");
17
+ const release_artifacts_1 = require("../app/release-artifacts");
18
+ const runner_1 = require("../app/runner");
19
+ const app_mode_1 = require("./app-mode");
20
+ const preview_proxy_1 = require("./preview-proxy");
21
+ /** How often a running build's log is read again for its status. */
22
+ const LOG_REFRESH_MS = 2000;
23
+ const LOG_LINES = 200;
24
+ /** The end of whichever log was written last: the step running, or the one that failed. */
25
+ async function latestLogTail(dir) {
26
+ const logs = node_path_1.default.join(dir, runner_1.APP_LOG_DIR);
27
+ const names = await node_fs_1.promises.readdir(logs).catch(() => []);
28
+ const dated = await Promise.all(names.map(async (name) => ({ name, at: (await node_fs_1.promises.stat(node_path_1.default.join(logs, name))).mtimeMs })));
29
+ const latest = dated.sort((a, b) => b.at - a.at)[0];
30
+ return latest && ((await (0, runner_1.logTail)(dir, `${runner_1.APP_LOG_DIR}/${latest.name}`, LOG_LINES)) || undefined);
31
+ }
32
+ /** Runs the build this VM is for. Never rejects: a failure is its status. */
33
+ function runReleaseBuild(env) {
34
+ var _a, _b;
35
+ let status = { phase: 'fetching' };
36
+ let runner;
37
+ let dir;
38
+ let serves;
39
+ const upload = { url: (_a = env[protocol_1.AGENT_ENV.RELEASE_UPLOAD_URL]) !== null && _a !== void 0 ? _a : '', token: (_b = env[protocol_1.AGENT_ENV.RELEASE_UPLOAD_TOKEN]) !== null && _b !== void 0 ? _b : '' };
40
+ const build = async () => {
41
+ var _a;
42
+ if (!upload.url || !upload.token)
43
+ return 'The build settings are incomplete (upload URL or token)';
44
+ dir = await (0, app_mode_1.fetchRelease)(env);
45
+ const resolved = await (0, config_1.resolveApp)((0, config_1.directoryReader)(dir), 'production');
46
+ if (!resolved)
47
+ return 'No app found in the release: no framework, package.json scripts, Python app or index.html, and no builder.json';
48
+ if (!resolved.ok)
49
+ return resolved.error;
50
+ runner = new runner_1.AppRunner(resolved.config, {
51
+ dir,
52
+ mode: 'production',
53
+ env: (0, env_1.deployedAppEnv)(env),
54
+ echoOutput: true,
55
+ onStatus: ({ phase }) => {
56
+ if (phase === 'installing' || phase === 'building')
57
+ status = { ...status, phase };
58
+ },
59
+ });
60
+ if (!(await runner.prepare()))
61
+ return (_a = runner.status().error) !== null && _a !== void 0 ? _a : 'The build was stopped';
62
+ status = { ...status, phase: 'uploading' };
63
+ const manifest = await (0, release_artifacts_1.uploadRelease)(upload, resolved.config, dir);
64
+ serves = !manifest.site.length ? 'processes' : (0, config_1.appRunsProcesses)(resolved.config, 'production') ? 'both' : 'files';
65
+ return undefined;
66
+ };
67
+ const isOver = () => status.phase === 'done' || status.phase === 'failed';
68
+ // Read here rather than when asked, since a status has to answer right away. A file can go while it's read: the next try will do.
69
+ const refreshLog = setInterval(() => {
70
+ if (!dir)
71
+ return;
72
+ void latestLogTail(dir).then((log) => {
73
+ if (log && !isOver())
74
+ status = { ...status, log };
75
+ }, () => undefined);
76
+ }, LOG_REFRESH_MS);
77
+ refreshLog.unref();
78
+ const finished = build().catch((error) => {
79
+ if (error instanceof release_artifacts_1.ReleaseOutputError)
80
+ return error.message;
81
+ return `The build could not finish: ${error instanceof Error ? error.message : String(error)}`;
82
+ }).then(async (error) => {
83
+ clearInterval(refreshLog);
84
+ // A failed build's logs are how to find out why; losing them doesn't change how it went. One
85
+ // that succeeded uploaded its own, before its manifest.
86
+ if (error && dir)
87
+ await (0, release_artifacts_1.uploadReleaseLogs)(upload, node_path_1.default.join(dir, runner_1.APP_LOG_DIR)).catch((failure) => console.error('[build] logs not uploaded:', failure));
88
+ status = error ? { phase: 'failed', error, ...(dir ? { log: await latestLogTail(dir) } : {}) } : { phase: 'done', serves };
89
+ console.log(`[build] ${status.phase}${status.error ? `: ${status.error}` : ''}`);
90
+ return status;
91
+ });
92
+ return {
93
+ status: () => status,
94
+ finished,
95
+ async close() {
96
+ await (runner === null || runner === void 0 ? void 0 : runner.stop());
97
+ },
98
+ };
99
+ }
100
+ /** Starts the build, and answers on the guest's port 8080 how it's going. */
101
+ function startReleaseBuild(env = process.env) {
102
+ const build = runReleaseBuild(env);
103
+ (0, preview_proxy_1.serveAppUnaddressed)();
104
+ (0, preview_proxy_1.setAppHandler)({
105
+ handleRequest(req, res) {
106
+ const known = req.url === protocol_1.APP_STATUS_PATH;
107
+ const body = known ? JSON.stringify({ build: build.status() }) : '';
108
+ res.writeHead(known ? 200 : 404, { 'Content-Type': 'application/json', 'Cache-Control': 'no-store', 'Content-Length': Buffer.byteLength(body) });
109
+ res.end(body);
110
+ return true;
111
+ },
112
+ handleUpgrade: () => false,
113
+ });
114
+ return build;
115
+ }
116
+ //# sourceMappingURL=build-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-mode.js","sourceRoot":"","sources":["../../src/runtime/build-mode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=build-mode.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-mode.test.d.ts","sourceRoot":"","sources":["../../src/runtime/build-mode.test.ts"],"names":[],"mappings":""}