summer-engine 4.3.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +3 -1
  3. package/.codex-plugin/plugin.json +5 -3
  4. package/.cursor-plugin/plugin.json +4 -2
  5. package/.factory-plugin/plugin.json +4 -2
  6. package/AGENTS.md +2 -2
  7. package/CHANGELOG.md +87 -0
  8. package/README.md +67 -27
  9. package/commands/start.md +19 -15
  10. package/commands/summer.md +1 -0
  11. package/dist/cli/command-usage.d.ts +3 -1
  12. package/dist/cli/command-usage.js +10 -4
  13. package/dist/cli/commands/create.d.ts +1 -25
  14. package/dist/cli/commands/create.js +10 -138
  15. package/dist/cli/commands/dev.d.ts +66 -0
  16. package/dist/cli/commands/dev.js +234 -0
  17. package/dist/cli/commands/install.d.ts +15 -58
  18. package/dist/cli/commands/install.js +31 -481
  19. package/dist/cli/commands/login.js +1 -1
  20. package/dist/cli/commands/ops.d.ts +17 -1
  21. package/dist/cli/commands/ops.js +97 -9
  22. package/dist/cli/commands/preview.d.ts +58 -0
  23. package/dist/cli/commands/preview.js +181 -0
  24. package/dist/cli/commands/run.d.ts +1 -17
  25. package/dist/cli/commands/run.js +17 -206
  26. package/dist/cli/index.js +5 -0
  27. package/dist/core/agent-host.d.ts +3 -0
  28. package/dist/core/agent-host.js +1 -1
  29. package/dist/core/api-client.d.ts +10 -2
  30. package/dist/core/api-client.js +13 -8
  31. package/dist/core/capabilities/agent-playbook.js +1 -0
  32. package/dist/core/capabilities/apps.d.ts +9 -9
  33. package/dist/core/capabilities/asset-import.d.ts +4 -1
  34. package/dist/core/capabilities/asset-import.js +15 -6
  35. package/dist/core/capabilities/capture-gameplay.js +1 -1
  36. package/dist/core/capabilities/connect-signal.d.ts +2 -2
  37. package/dist/core/capabilities/content-make/index.d.ts +81 -0
  38. package/dist/core/capabilities/content-make/index.js +706 -0
  39. package/dist/core/capabilities/content-make/media.d.ts +57 -0
  40. package/dist/core/capabilities/content-make/media.js +172 -0
  41. package/dist/core/capabilities/content-make/plan.d.ts +130 -0
  42. package/dist/core/capabilities/content-make/plan.js +433 -0
  43. package/dist/core/capabilities/content-make/render.d.ts +64 -0
  44. package/dist/core/capabilities/content-make/render.js +370 -0
  45. package/dist/core/capabilities/content-make/study.d.ts +13 -0
  46. package/dist/core/capabilities/content-make/study.js +165 -0
  47. package/dist/core/capabilities/content-make/types.d.ts +173 -0
  48. package/dist/core/capabilities/content-make/types.js +6 -0
  49. package/dist/core/capabilities/content-make/voice.d.ts +7 -0
  50. package/dist/core/capabilities/content-make/voice.js +27 -0
  51. package/dist/core/capabilities/events.d.ts +2 -2
  52. package/dist/core/capabilities/export-game.d.ts +4 -1
  53. package/dist/core/capabilities/export-game.js +4 -3
  54. package/dist/core/capabilities/export-presets.d.ts +2 -1
  55. package/dist/core/capabilities/export-presets.js +2 -1
  56. package/dist/core/capabilities/go-live.d.ts +14 -0
  57. package/dist/core/capabilities/go-live.js +408 -0
  58. package/dist/core/capabilities/image-generation.d.ts +6 -6
  59. package/dist/core/capabilities/item-manifest.d.ts +92 -0
  60. package/dist/core/capabilities/item-manifest.js +247 -0
  61. package/dist/core/capabilities/placement.d.ts +7 -7
  62. package/dist/core/capabilities/projects-local.d.ts +68 -0
  63. package/dist/core/capabilities/projects-local.js +172 -0
  64. package/dist/core/capabilities/publish-build.d.ts +13 -2
  65. package/dist/core/capabilities/publish-build.js +87 -21
  66. package/dist/core/capabilities/publish-download.js +1 -1
  67. package/dist/core/capabilities/runtime-control.d.ts +7 -2
  68. package/dist/core/capabilities/runtime-control.js +27 -1
  69. package/dist/core/capabilities/seeing/args.d.ts +2 -2
  70. package/dist/core/capabilities/store-checks.d.ts +45 -0
  71. package/dist/core/capabilities/store-checks.js +85 -0
  72. package/dist/core/capabilities/store-details.d.ts +37 -0
  73. package/dist/core/capabilities/store-details.js +94 -0
  74. package/dist/core/capabilities/summer-bundle.d.ts +21 -2
  75. package/dist/core/capabilities/summer-bundle.js +54 -7
  76. package/dist/core/capabilities/sync-items.d.ts +89 -0
  77. package/dist/core/capabilities/sync-items.js +352 -0
  78. package/dist/core/capabilities/tool-dispatch.js +66 -6
  79. package/dist/core/capabilities/video-ogv.d.ts +49 -0
  80. package/dist/core/capabilities/video-ogv.js +260 -0
  81. package/dist/core/capability-skew.js +2 -2
  82. package/dist/core/cli-usage-beacon.js +26 -2
  83. package/dist/core/cli-usage.d.ts +5 -2
  84. package/dist/core/cli-usage.js +8 -2
  85. package/dist/core/engine-install.d.ts +53 -0
  86. package/dist/core/engine-install.js +93 -0
  87. package/dist/core/engine-installer.d.ts +134 -0
  88. package/dist/core/engine-installer.js +760 -0
  89. package/dist/core/engine-launch.d.ts +126 -0
  90. package/dist/core/engine-launch.js +398 -0
  91. package/dist/core/engine-self-start.d.ts +63 -0
  92. package/dist/core/engine-self-start.js +282 -0
  93. package/dist/core/engine.d.ts +7 -1
  94. package/dist/core/engine.js +9 -2
  95. package/dist/core/error-codes.d.ts +4 -1
  96. package/dist/core/error-codes.js +7 -3
  97. package/dist/core/library-read.d.ts +2 -2
  98. package/dist/core/library-search.d.ts +2 -2
  99. package/dist/core/local-project.d.ts +50 -0
  100. package/dist/core/local-project.js +234 -0
  101. package/dist/core/ops/areas.js +9 -3
  102. package/dist/core/ops/catalog.d.ts +9 -0
  103. package/dist/core/ops/catalog.js +56 -4
  104. package/dist/core/ops/engine-answer.d.ts +4 -1
  105. package/dist/core/ops/engine-answer.js +16 -3
  106. package/dist/core/ops/engine.js +4 -4
  107. package/dist/core/ops/save-files.d.ts +6 -1
  108. package/dist/core/ops/save-files.js +67 -50
  109. package/dist/core/ops/search.js +9 -2
  110. package/dist/core/preview/input.d.ts +35 -0
  111. package/dist/core/preview/input.js +105 -0
  112. package/dist/core/preview/launch-config.d.ts +52 -0
  113. package/dist/core/preview/launch-config.js +137 -0
  114. package/dist/core/preview/page.d.ts +22 -0
  115. package/dist/core/preview/page.js +232 -0
  116. package/dist/core/preview/preview-source.d.ts +179 -0
  117. package/dist/core/preview/preview-source.js +350 -0
  118. package/dist/core/preview/server.d.ts +26 -0
  119. package/dist/core/preview/server.js +218 -0
  120. package/dist/core/telemetry.d.ts +20 -16
  121. package/dist/core/telemetry.js +92 -16
  122. package/dist/core/templates.d.ts +20 -0
  123. package/dist/core/templates.js +300 -3
  124. package/dist/core/tool-profiles.d.ts +2 -2
  125. package/dist/core/tool-profiles.js +1 -0
  126. package/dist/core/usage-fields.d.ts +41 -0
  127. package/dist/core/usage-fields.js +150 -0
  128. package/dist/core/util/sleep.d.ts +3 -0
  129. package/dist/core/util/sleep.js +12 -0
  130. package/dist/mcp/ops-surface.js +28 -2
  131. package/dist/mcp/server.d.ts +14 -4
  132. package/dist/mcp/server.js +42 -8
  133. package/dist/mcp/tool-surface.d.ts +8 -0
  134. package/dist/mcp/tool-surface.js +19 -2
  135. package/dist/mcp/tools/creator-tools.js +92 -14
  136. package/dist/mcp/tools/debug-tools.js +2 -0
  137. package/dist/mcp/tools/local-project-tools.d.ts +6 -0
  138. package/dist/mcp/tools/local-project-tools.js +33 -0
  139. package/dist/mcp/tools/navigation-tools.js +2 -1
  140. package/dist/mcp/tools/project-tools.js +5 -8
  141. package/dist/mcp/tools/seeing-tools.js +1 -1
  142. package/dist/mcp/tools/visual-tools.js +1 -1
  143. package/dist/mcp/tools/with-engine.js +1 -1
  144. package/gemini-extension.json +3 -1
  145. package/library/references/mcp-tools-reference/mcp-tools-reference.md +18 -5
  146. package/library/skills/README.md +12 -8
  147. package/library/skills/animated-loop/SKILL.md +10 -16
  148. package/library/skills/cinematic-cutscene/SKILL.md +7 -18
  149. package/library/skills/headless-scripting/SKILL.md +7 -4
  150. package/library/skills/in-game-purchases/SKILL.md +25 -8
  151. package/library/skills/in-game-purchases/resource.yaml +2 -1
  152. package/library/skills/launch-ready/SKILL.md +351 -0
  153. package/library/skills/launch-ready/resource.yaml +45 -0
  154. package/library/skills/make-content/SKILL.md +202 -0
  155. package/library/skills/make-content/resource.yaml +32 -0
  156. package/library/skills/make-game/SKILL.md +2 -0
  157. package/library/skills/make-game/resource.yaml +2 -1
  158. package/library/skills/navigate-summer/SKILL.md +4 -2
  159. package/library/skills/new-project/SKILL.md +15 -22
  160. package/library/skills/new-project/resource.yaml +2 -1
  161. package/library/skills/painted-25d-world/SKILL.md +366 -0
  162. package/library/skills/painted-25d-world/_building-blocks/blender-route.md +33 -0
  163. package/library/skills/painted-25d-world/_building-blocks/blockout_builder.gd +149 -0
  164. package/library/skills/painted-25d-world/_building-blocks/capture_paint_view.gd +32 -0
  165. package/library/skills/painted-25d-world/_building-blocks/paint_projection.gdshader +23 -0
  166. package/library/skills/painted-25d-world/_building-blocks/paintcam_check.gd +25 -0
  167. package/library/skills/painted-25d-world/_building-blocks/painted_door.gd +17 -0
  168. package/library/skills/painted-25d-world/_building-blocks/painted_location.gd +56 -0
  169. package/library/skills/painted-25d-world/_building-blocks/painted_player.gd +125 -0
  170. package/library/skills/painted-25d-world/_building-blocks/painted_world.gd +111 -0
  171. package/library/skills/painted-25d-world/_building-blocks/tools/cam.py +57 -0
  172. package/library/skills/painted-25d-world/_building-blocks/tools/detail4k.py +81 -0
  173. package/library/skills/painted-25d-world/_building-blocks/tools/overlay.py +17 -0
  174. package/library/skills/painted-25d-world/_building-blocks/tools/preview.py +60 -0
  175. package/library/skills/painted-25d-world/resource.yaml +39 -0
  176. package/library/skills/publish-your-game/SKILL.md +13 -14
  177. package/library/skills/publish-your-game/resource.yaml +4 -3
  178. package/library/skills/release-checklist/SKILL.md +188 -0
  179. package/library/skills/release-checklist/resource.yaml +40 -0
  180. package/library/skills/release-readiness/SKILL.md +1 -1
  181. package/library/skills/release-readiness/resource.yaml +1 -1
  182. package/library/skills/store-art/SKILL.md +1 -1
  183. package/library/skills/store-art/resource.yaml +1 -1
  184. package/library/skills/store-listing/SKILL.md +1 -1
  185. package/library/skills/store-listing/resource.yaml +1 -1
  186. package/library/skills/summer-cli/SKILL.md +2 -0
  187. package/library/skills/summer-store/SKILL.md +295 -39
  188. package/library/skills/summer-store/resource.yaml +9 -3
  189. package/library/skills/trailer-shot/SKILL.md +3 -3
  190. package/library/templates/README.md +5 -0
  191. package/library/tools/content-make/resource.yaml +132 -0
  192. package/library/tools/frame-shot/GUIDE.md +1 -1
  193. package/library/tools/go-live/resource.yaml +67 -0
  194. package/library/tools/import-from-url/GUIDE.md +1 -0
  195. package/library/tools/import-from-url-batch/GUIDE.md +1 -1
  196. package/library/tools/play/GUIDE.md +2 -0
  197. package/library/tools/projects-create-local/resource.yaml +55 -0
  198. package/library/tools/projects-open-local/resource.yaml +51 -0
  199. package/library/tools/publish-build/resource.yaml +3 -3
  200. package/library/tools/screenshot/GUIDE.md +1 -1
  201. package/library/tools/store-set-details/resource.yaml +114 -0
  202. package/library/tools/sync-items/resource.yaml +72 -0
  203. package/package.json +1 -1
  204. package/registry/generated/aliases.json +6 -0
  205. package/registry/generated/counts.json +3 -3
  206. package/registry/generated/gemini-extension.json +3 -1
  207. package/registry/generated/index.json +463 -37
  208. package/registry/generated/marketplace.claude.json +1 -1
  209. package/registry/generated/plugin.claude-directory.json +4 -2
  210. package/registry/generated/plugin.claude.json +3 -1
  211. package/registry/generated/plugin.codex.json +5 -3
  212. package/registry/generated/plugin.cursor.json +4 -2
  213. package/registry/generated/plugin.factory.json +4 -2
  214. package/registry/generated/server.json +2 -2
  215. package/registry/generated/skills-index.md +12 -8
  216. package/registry/generated/skills-registry.json +62 -5
  217. package/registry/operations/legacy-names.json +40 -0
  218. package/registry/operations/public-catalog.json +10144 -387
@@ -218,3 +218,96 @@ export function findExtractedEngineBinary(files) {
218
218
  return (files.find((f) => /godot\.linuxbsd\..*editor|summer.*linux/i.test(basename(f))) ??
219
219
  null);
220
220
  }
221
+ /** An install failure with its reason; the message ends in one next step. */
222
+ export class EngineInstallError extends Error {
223
+ reason;
224
+ constructor(reason, message) {
225
+ super(message);
226
+ this.name = "EngineInstallError";
227
+ this.reason = reason;
228
+ }
229
+ }
230
+ /** The command every "try again" next step names. */
231
+ export const INSTALL_RETRY = "npx -y summer-engine@latest install";
232
+ /** The useful line of an error: for a failed shell command the last line of
233
+ * its stderr ("cp: ...: Permission denied"), not "Command failed: ...". */
234
+ export function errorDetail(err) {
235
+ const text = err instanceof Error ? err.message : String(err);
236
+ const lines = text.split("\n").map((line) => line.trim()).filter(Boolean);
237
+ return (lines.at(-1) ?? "unknown error").slice(0, 200);
238
+ }
239
+ /** A full disk and a refused write have their own reasons wherever they
240
+ * happen; anything else is `fallback`. */
241
+ export function installFailureReason(err, fallback) {
242
+ if (err instanceof EngineInstallError)
243
+ return err.reason;
244
+ const code = err?.code;
245
+ const text = err instanceof Error ? err.message : String(err);
246
+ if (code === "ENOSPC" || /no space left on device/i.test(text))
247
+ return "disk_space";
248
+ if (code === "EACCES" || code === "EPERM" || /permission denied|operation not permitted/i.test(text)) {
249
+ return "permission";
250
+ }
251
+ return fallback;
252
+ }
253
+ /** Turn an unexpected error into an EngineInstallError: disk_space and
254
+ * permission get their own message, anything else `message(detail)`. */
255
+ export function asInstallError(err, fallback, message) {
256
+ if (err instanceof EngineInstallError)
257
+ return err;
258
+ const reason = installFailureReason(err, fallback);
259
+ const detail = errorDetail(err);
260
+ if (reason === "disk_space") {
261
+ return new EngineInstallError(reason, `The disk ran out of space during the install (${detail}). Free up space, then run: ${INSTALL_RETRY}`);
262
+ }
263
+ if (reason === "permission") {
264
+ return new EngineInstallError(reason, `The install was not allowed to write a file (${detail}). Install into a folder you own: ${INSTALL_RETRY} --path <folder>`);
265
+ }
266
+ return new EngineInstallError(reason, message(detail));
267
+ }
268
+ /** The engine download when the server sends no content-length (the macOS DMG is about 660 MB). */
269
+ export const DEFAULT_DOWNLOAD_BYTES = 700 * 1024 * 1024;
270
+ /** The install folder needs about this many times the download: the unpacked
271
+ * app plus the staged copy that replaces an existing one. */
272
+ export const INSTALL_SPACE_FACTOR = 2.5;
273
+ export function formatSize(bytes) {
274
+ return bytes >= 1024 ** 3 ? `${(bytes / 1024 ** 3).toFixed(1)} GB` : `${Math.round(bytes / 1024 ** 2)} MB`;
275
+ }
276
+ /**
277
+ * Refuse before the download fills the disk. Each need is a folder and the
278
+ * bytes it takes; needs on one volume add up (the default macOS temp folder
279
+ * and /Applications share the system volume). A volume whose free space
280
+ * cannot be read is skipped: the install tries, and ENOSPC still maps to
281
+ * disk_space.
282
+ */
283
+ export function checkDiskSpace(needs, freeSpace) {
284
+ const volumes = new Map();
285
+ for (const need of needs) {
286
+ let space;
287
+ try {
288
+ space = freeSpace(need.path);
289
+ }
290
+ catch {
291
+ continue;
292
+ }
293
+ const entry = volumes.get(space.volume) ?? { path: need.path, bytes: 0, free: space.bytes };
294
+ entry.bytes += need.bytes;
295
+ volumes.set(space.volume, entry);
296
+ }
297
+ for (const volume of volumes.values()) {
298
+ if (volume.free < volume.bytes) {
299
+ throw new EngineInstallError("disk_space", `Not enough disk space on the volume with ${volume.path}: ${formatSize(volume.free)} free, ` +
300
+ `about ${formatSize(volume.bytes)} needed. Free up space, then run: ${INSTALL_RETRY}`);
301
+ }
302
+ }
303
+ }
304
+ /** Where the macOS engine goes: --path wins; otherwise /Applications/Summer.app,
305
+ * or ~/Applications/Summer.app when this user cannot replace it there (a
306
+ * standard, non-admin account). macEnginePaths looks there too, and the
307
+ * install record puts it first. */
308
+ export function chooseMacDestination(input) {
309
+ const destApp = macInstallDestination(input.customPath);
310
+ if (input.customPath?.trim() || input.canReplace(destApp))
311
+ return { destApp, fallback: false };
312
+ return { destApp: join(input.home, "Applications", "Summer.app"), fallback: true };
313
+ }
@@ -0,0 +1,134 @@
1
+ import { EngineInstallError, type FreeSpace, type InstallFailureReason } from "./engine-install.js";
2
+ export { EngineInstallError, type InstallFailureReason };
3
+ /** Guard a download URL from the releases endpoint. A missing/empty URL (an
4
+ * outdated or misconfigured endpoint) otherwise becomes a cryptic
5
+ * fetch(undefined) failure — surface it clearly with a manual fallback. */
6
+ export declare function requireDownloadUrl(value: string | undefined, label: string): string;
7
+ /** Verify a downloaded file's sha256 against the expected hash from the releases
8
+ * endpoint. Skipped when no expected hash is published. Catches a truncated or
9
+ * corrupted download (a ~700 MB install over a flaky network) before it becomes a
10
+ * confusing DMG-mount / installer failure downstream. */
11
+ export declare function verifyChecksum(actual: string, expected: string | undefined, label: string): void;
12
+ import { parseMacBundleVersion, readMacBundleVersion } from "./launch-posture.js";
13
+ export { parseMacBundleVersion, readMacBundleVersion };
14
+ export declare function isSameVersion(installed: string | null, latest: string): boolean;
15
+ export type MacInstallPlan = {
16
+ action: "install";
17
+ } | {
18
+ action: "up-to-date";
19
+ version: string;
20
+ } | {
21
+ action: "needs-confirmation";
22
+ installed: string | null;
23
+ } | {
24
+ action: "refuse";
25
+ reason: string;
26
+ };
27
+ /** Decide what `summer install` may do about an existing /Applications/Summer.app.
28
+ * Replacing an installed engine is destructive, so it needs --yes or a TTY
29
+ * prompt; an equal version is a no-op success. */
30
+ export declare function planMacInstall(input: {
31
+ exists: boolean;
32
+ installedVersion: string | null;
33
+ latestVersion: string;
34
+ yes: boolean;
35
+ isTTY: boolean;
36
+ /** The command that repeats this install (with its --path), for the refusal. */
37
+ retry?: string;
38
+ }): MacInstallPlan;
39
+ export type ShellExec = (command: string) => void;
40
+ /** Replace destApp with the bundle on the mounted DMG WITHOUT a window where
41
+ * no engine exists: copy to <destApp>.new first, and only after that
42
+ * succeeds remove the old bundle and rename the staged copy into place. A
43
+ * failed copy leaves the existing install untouched. */
44
+ export declare function replaceMacApp(mountPoint: string, destApp: string, exec: ShellExec, staged?: string): void;
45
+ /** The mount point hdiutil attach printed (the /Volumes/... column), or null. */
46
+ export declare function parseMountPoint(hdiutilOutput: string): string | null;
47
+ /** Mount the DMG and return its mount point; any failure is `mount`. */
48
+ export declare function attachDmg(dmgPath: string, exec: (command: string) => string): string;
49
+ /** Eject the DMG, best effort: a busy volume ("resource busy") gets one retry
50
+ * with -force, and a failure here never fails an install that already
51
+ * succeeded. Returns whether it ejected. */
52
+ export declare function detachDmg(mountPoint: string, exec: (command: string) => unknown): boolean;
53
+ /** Whether the engine executable at this path is running: pgrep on a pattern
54
+ * anchored to the start of the command line, so a process that only mentions
55
+ * the path in its arguments does not count. pgrep exits 1 on no match. */
56
+ export declare function isEngineRunning(binary: string, execFile: (file: string, args: string[]) => string): boolean;
57
+ /** Velopack Setup.exe install args. Velopack is NOT NSIS: silent install is
58
+ * `--silent` and a custom directory is `--installto <dir>` (per Velopack's
59
+ * setup.exe CLI). The old NSIS flags (/S, /D=) are rejected by the Velopack
60
+ * installer with "unexpected argument '/S' found" — this is the wizard bug. */
61
+ export declare function windowsInstallerArgs(customPath?: string): string;
62
+ /** Printed after an install: the first start of a new engine is slow and silent. */
63
+ export declare const FIRST_START_NOTE: string;
64
+ /** Where the Velopack installer put Summer.exe: <dir>/current/Summer.exe for --path, else the default locations. */
65
+ export declare function windowsInstalledBinary(customPath?: string, exists?: (path: string) => boolean): string | null;
66
+ /**
67
+ * Download progress: rewrites one line on a terminal; elsewhere (an agent,
68
+ * a log file) one line per 10%, so a 700 MB download is about ten lines
69
+ * instead of hundreds of kilobytes.
70
+ */
71
+ export declare function createProgressReporter(isTTY: boolean, write: (text: string) => void): (downloaded: number, total: number) => void;
72
+ export interface InstallEngineOptions {
73
+ /** Custom install directory (macOS: <path>/Summer.app). */
74
+ path?: string;
75
+ /** Replace an older installed engine without asking. */
76
+ yes?: boolean;
77
+ /** Progress and result lines; console.log when not given. */
78
+ log?: (line: string) => void;
79
+ /** Whether a person can answer a prompt on stdin; no prompt unless true. */
80
+ isTTY?: boolean;
81
+ }
82
+ export interface InstallEngineResult {
83
+ /** The engine executable, or null when the Windows installer put it somewhere unknown. */
84
+ binary: string | null;
85
+ version: string | null;
86
+ /** The bundle (macOS) or folder the engine is in. */
87
+ destination: string;
88
+ /** Nothing was replaced: already up to date, an existing binary registered, or the update was declined. */
89
+ alreadyInstalled: boolean;
90
+ }
91
+ /** The machine around an install; tests replace any of it. */
92
+ export interface InstallDeps {
93
+ platform: NodeJS.Platform;
94
+ arch: string;
95
+ /** Run a shell command and return stdout; throws with stderr in the message.
96
+ * `inherit` hands the terminal to the command (the Windows installer). */
97
+ exec: (command: string, inherit?: boolean) => string;
98
+ /** Run a program without a shell (pgrep); throws on a non-zero exit. */
99
+ execFile: (file: string, args: string[]) => string;
100
+ fetch: typeof fetch;
101
+ freeSpace: FreeSpace;
102
+ canWrite: (path: string) => boolean;
103
+ tmpDir: string;
104
+ home: string;
105
+ env: NodeJS.ProcessEnv;
106
+ confirm: (question: string) => Promise<boolean>;
107
+ record: (binary: string, version: string | null) => Promise<void>;
108
+ /** Rewrite one progress line instead of printing one per 10%. */
109
+ stdoutIsTTY: boolean;
110
+ }
111
+ /**
112
+ * Install Summer Engine for this platform: `summer install`, and the engine
113
+ * step of `summer dev`. Never exits the process and asks on stdin only when
114
+ * `isTTY` is true; every failure is an EngineInstallError whose reason is the
115
+ * telemetry code and whose message ends in one next step.
116
+ */
117
+ export declare function installEngine(opts: InstallEngineOptions, deps?: Partial<InstallDeps>): Promise<InstallEngineResult>;
118
+ /** ~/.summer/install.lock: held while one install runs. A holder whose
119
+ * process is gone, or that is hours old, is stale and removed. */
120
+ export declare const INSTALL_LOCK_DIR = "install.lock";
121
+ export type LockOwner = {
122
+ pid: number;
123
+ createdAt: number;
124
+ };
125
+ /**
126
+ * Remove a stale lock so that only one waiter wins: rename it aside (one
127
+ * rename of a folder succeeds), then check that the folder moved is still
128
+ * the stale one judged. If a live holder took the lock in between, put its
129
+ * lock back.
130
+ */
131
+ export declare function takeOverStaleLock(lockDir: string, stale: LockOwner): void;
132
+ export declare function downloadFile(url: string, dest: string): Promise<{
133
+ sha256: string;
134
+ }>;