@rebon/cli-win32-x64 1.2.0 → 1.4.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 (98) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +10 -0
  3. package/README.md +203 -144
  4. package/THIRD_PARTY_NOTICES.txt +1232 -128
  5. package/bin/rebon.js +22 -22
  6. package/lib/windows-managed.js +390 -390
  7. package/package.json +9 -2
  8. package/payload/compose-runtime/package.json +17 -17
  9. package/payload/compose-runtime/payload/compose/shims/dsh-anonymous-user-id.js +10 -10
  10. package/payload/compose-runtime/payload/compose/shims/dsh-credentials.js +13 -13
  11. package/payload/compose-runtime/payload/compose/shims/dsh-launch-environment.js +21 -21
  12. package/payload/compose-runtime/payload/compose/shims/dsh-llm.js +313 -313
  13. package/payload/compose-runtime/payload/compose/shims/dsh-settings.js +43 -43
  14. package/payload/compose-runtime/payload/compose/shims/dsh-tools.js +20 -20
  15. package/payload/compose-runtime/payload/compose/shims/dsh-web.js +10 -10
  16. package/payload/compose-runtime/payload/compose/shims/llm-adapter.js +32 -32
  17. package/payload/compose-runtime/payload/compose/shims/zod-lite.js +49 -49
  18. package/payload/compose-runtime/payload/vendor/cordis/LICENSE +21 -0
  19. package/payload/compose-runtime/payload/vendor/cordis/index.js +1530 -1530
  20. package/payload/compose-runtime/payload/vendor/cosmokit/LICENSE +21 -21
  21. package/payload/compose-runtime/payload/vendor/cosmokit/index.mjs +357 -357
  22. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-agent +21 -21
  23. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-agent-loop +21 -21
  24. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-llm-core +21 -21
  25. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-llm-deepseek +21 -21
  26. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-logger-console +21 -21
  27. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-scope +21 -21
  28. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-session +21 -21
  29. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-system-prompt +21 -21
  30. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-timeout +21 -21
  31. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-timer +21 -21
  32. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-tool-todo +21 -21
  33. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-tool-web +21 -21
  34. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-tools-schema +21 -21
  35. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-turndown +21 -0
  36. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-turndown-plugin-gfm +21 -0
  37. package/payload/compose-runtime/payload/vendor/dsh/LICENSE-web-search-exa +21 -21
  38. package/payload/compose-runtime/payload/vendor/dsh/agent-loop.js +1193 -1193
  39. package/payload/compose-runtime/payload/vendor/dsh/agent.js +714 -714
  40. package/payload/compose-runtime/payload/vendor/dsh/llm-core.js +269 -269
  41. package/payload/compose-runtime/payload/vendor/dsh/llm-deepseek.js +672 -672
  42. package/payload/compose-runtime/payload/vendor/dsh/logger-console.js +83 -83
  43. package/payload/compose-runtime/payload/vendor/dsh/scope.js +287 -287
  44. package/payload/compose-runtime/payload/vendor/dsh/session.js +1668 -1668
  45. package/payload/compose-runtime/payload/vendor/dsh/system-prompt.js +309 -309
  46. package/payload/compose-runtime/payload/vendor/dsh/timeout.js +100 -100
  47. package/payload/compose-runtime/payload/vendor/dsh/timer.js +128 -128
  48. package/payload/compose-runtime/payload/vendor/dsh/tool-todo.js +143 -143
  49. package/payload/compose-runtime/payload/vendor/dsh/tool-web.js +1527 -1527
  50. package/payload/compose-runtime/payload/vendor/dsh/tools-schema.js +849 -849
  51. package/payload/compose-runtime/payload/vendor/dsh/web-search-exa.js +122 -122
  52. package/payload/compose-runtime/payload/vendor/eventsource-parser/LICENSE +21 -21
  53. package/payload/compose-runtime/payload/vendor/eventsource-parser/index.js +177 -177
  54. package/payload/compose-runtime/payload/vendor/eventsource-parser/stream.js +48 -48
  55. package/payload/compose-runtime/payload/vendor/schemastery/LICENSE +21 -0
  56. package/payload/compose-runtime/payload/vendor/schemastery/index.mjs +656 -656
  57. package/payload/compose-runtime/payload-manifests.json +48 -48
  58. package/payload/compose-runtime/src/bridge.mjs +193 -195
  59. package/payload/compose-runtime/src/credentials-runtime.mjs +50 -50
  60. package/payload/compose-runtime/src/eventsource-stream.mjs +48 -48
  61. package/payload/compose-runtime/src/index.mjs +7 -7
  62. package/payload/compose-runtime/src/llm-runtime.mjs +326 -326
  63. package/payload/compose-runtime/src/loader.mjs +78 -78
  64. package/payload/compose-runtime/src/loop-assembly.mjs +237 -237
  65. package/payload/compose-runtime/src/payload.mjs +49 -49
  66. package/payload/compose-runtime/src/plugin.mjs +59 -59
  67. package/payload/compose-runtime/src/realm.mjs +223 -223
  68. package/payload/compose-runtime/src/registry.mjs +191 -191
  69. package/payload/compose-runtime/src/resolve.mjs +115 -115
  70. package/payload/compose-runtime/src/systemprompt-runtime.mjs +67 -67
  71. package/payload/compose-runtime/src/tools-runtime.mjs +239 -239
  72. package/payload/compose-runtime/src/web-runtime.mjs +209 -209
  73. package/payload/plugin-host/package.json +11 -11
  74. package/payload/plugin-host/src/bridge.mjs +64 -64
  75. package/payload/plugin-host/src/cli.mjs +147 -147
  76. package/payload/plugin-host/src/framing.mjs +113 -113
  77. package/payload/plugin-host/src/host.mjs +691 -691
  78. package/payload/plugin-host/src/json.mjs +208 -208
  79. package/payload/plugin-host/src/lifecycle.mjs +114 -114
  80. package/payload/plugin-host/src/loader.mjs +183 -183
  81. package/payload/plugin-host/src/methods.mjs +377 -377
  82. package/payload/plugin-host/src/ownership.mjs +57 -57
  83. package/payload/plugin-host/src/protocol.mjs +129 -129
  84. package/payload/plugin-host/src/sdk.mjs +7 -7
  85. package/payload/rebon-boa-helper.exe +0 -0
  86. package/payload/rebon-browser-mcp.exe +0 -0
  87. package/payload/rebon-computer-use.exe +0 -0
  88. package/payload/rebon-lsp-mcp.exe +0 -0
  89. package/payload/rebon.exe +2 -2
  90. package/payload/sandbox-win.exe +0 -0
  91. package/scripts/postinstall.js +112 -112
  92. package/payload/compose-runtime/payload/compose/credentials-runtime.js +0 -38
  93. package/payload/compose-runtime/payload/compose/llm-runtime.js +0 -330
  94. package/payload/compose-runtime/payload/compose/loop-assembly.js +0 -149
  95. package/payload/compose-runtime/payload/compose/serve-dispatch.js +0 -82
  96. package/payload/compose-runtime/payload/compose/systemprompt-runtime.js +0 -74
  97. package/payload/compose-runtime/payload/compose/tools-runtime.js +0 -228
  98. package/payload/compose-runtime/payload/compose/web-runtime.js +0 -204
@@ -1,390 +1,390 @@
1
- "use strict";
2
-
3
- const fs = require("fs");
4
- const path = require("path");
5
-
6
- const CURRENT_MANIFEST = "current.json";
7
- const EXECUTABLE_NAME = "rebon.exe";
8
- const PAYLOAD_DIR = "payload";
9
- const VERSIONS_DIR = "versions";
10
- const STAGING_DIR = "staging";
11
-
12
- function defaultPackageRoot() {
13
- return path.resolve(__dirname, "..");
14
- }
15
-
16
- function managedBinDir() {
17
- const base = process.env.LOCALAPPDATA || (process.env.USERPROFILE && path.join(process.env.USERPROFILE, ".rebon"));
18
- if (!base) {
19
- return null;
20
- }
21
- return path.join(base, "rebon", "bin");
22
- }
23
-
24
- function requireManagedBinDir() {
25
- const binDir = managedBinDir();
26
- if (!binDir) {
27
- throw new Error("LOCALAPPDATA and USERPROFILE are both unset; cannot choose a per-user install directory");
28
- }
29
- return binDir;
30
- }
31
-
32
- function sanitizeVersionPart(value) {
33
- return String(value || "unknown").replace(/[^0-9A-Za-z._-]/g, "_");
34
- }
35
-
36
- function firstString(candidates) {
37
- for (const candidate of candidates) {
38
- if (typeof candidate === "string" && candidate.length > 0) {
39
- return candidate;
40
- }
41
- }
42
- return null;
43
- }
44
-
45
- function packageBuildId(packageJson) {
46
- const rebon = packageJson && packageJson.rebon;
47
- return firstString([
48
- rebon && rebon.build,
49
- rebon && rebon.buildId,
50
- rebon && rebon.commit,
51
- rebon && rebon.hash,
52
- packageJson && packageJson.rebonBuild,
53
- packageJson && packageJson.rebonBuildId,
54
- ]);
55
- }
56
-
57
- function versionKeyFromPackageJson(packageJson) {
58
- const version = sanitizeVersionPart(packageJson && packageJson.version);
59
- const buildId = packageBuildId(packageJson);
60
- return buildId ? `${version}-${sanitizeVersionPart(buildId)}` : version;
61
- }
62
-
63
- function payloadSignature(payloadPath) {
64
- const stat = fs.statSync(payloadPath);
65
- return { size: stat.size, mtimeMs: Math.trunc(stat.mtimeMs) };
66
- }
67
-
68
- function readPackageInfo(packageRoot) {
69
- const root = path.resolve(packageRoot || defaultPackageRoot());
70
- const packageJson = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
71
- const payloadDir = path.join(root, PAYLOAD_DIR);
72
- const payloadPath = path.join(payloadDir, EXECUTABLE_NAME);
73
- return {
74
- packageRoot: root,
75
- name: String(packageJson.name || "rebon"),
76
- version: String(packageJson.version || "unknown"),
77
- versionKey: versionKeyFromPackageJson(packageJson),
78
- payloadDir,
79
- payloadPath,
80
- payload: fs.existsSync(payloadPath) ? payloadSignature(payloadPath) : null,
81
- };
82
- }
83
-
84
- function managedRelativeExecutable(versionKey) {
85
- return `${VERSIONS_DIR}/${versionKey}/${EXECUTABLE_NAME}`;
86
- }
87
-
88
- function payloadSpecificVersionKey(packageInfo) {
89
- if (!packageInfo.payload) {
90
- return packageInfo.versionKey;
91
- }
92
- return `${packageInfo.versionKey}-${packageInfo.payload.size}-${packageInfo.payload.mtimeMs}`;
93
- }
94
-
95
- function acceptedVersionKeys(packageInfo) {
96
- const keys = [packageInfo.versionKey];
97
- const payloadKey = payloadSpecificVersionKey(packageInfo);
98
- if (payloadKey !== packageInfo.versionKey) {
99
- keys.push(payloadKey);
100
- }
101
- return keys;
102
- }
103
-
104
- function layoutForVersion(binDir, versionKey) {
105
- const versionDir = path.join(binDir, VERSIONS_DIR, versionKey);
106
- const stagingDir = path.join(binDir, STAGING_DIR, versionKey);
107
- return {
108
- versionDir,
109
- stagingDir,
110
- exePath: path.join(versionDir, EXECUTABLE_NAME),
111
- manifestPath: path.join(binDir, CURRENT_MANIFEST),
112
- manifestRelativePath: managedRelativeExecutable(versionKey),
113
- };
114
- }
115
-
116
- function normalizeManifestPath(value) {
117
- return String(value || "").replace(/\\/g, "/").replace(/\/+/g, "/");
118
- }
119
-
120
- function resolveManifestPath(binDir, manifestPath) {
121
- if (typeof manifestPath !== "string" || path.isAbsolute(manifestPath)) {
122
- return null;
123
- }
124
-
125
- const resolved = path.resolve(binDir, manifestPath.replace(/[\\/]+/g, path.sep));
126
- const relative = path.relative(path.resolve(binDir), resolved);
127
- if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
128
- return null;
129
- }
130
- return resolved;
131
- }
132
-
133
- function readCurrentManifest(binDir) {
134
- try {
135
- return JSON.parse(fs.readFileSync(path.join(binDir, CURRENT_MANIFEST), "utf8"));
136
- } catch (_) {
137
- return null;
138
- }
139
- }
140
-
141
- function payloadMatchesManifest(manifest, packageInfo) {
142
- if (!packageInfo.payload) {
143
- return true;
144
- }
145
- if (!manifest.payload) {
146
- return false;
147
- }
148
- return (
149
- Number(manifest.payload.size) === packageInfo.payload.size &&
150
- Math.trunc(Number(manifest.payload.mtimeMs)) === packageInfo.payload.mtimeMs
151
- );
152
- }
153
-
154
- function manifestMatchesPackage(manifest, binDir, packageInfo) {
155
- if (!manifest) {
156
- return false;
157
- }
158
- if (manifest.package !== packageInfo.name || manifest.version !== packageInfo.version) {
159
- return false;
160
- }
161
- if (!acceptedVersionKeys(packageInfo).includes(manifest.versionKey)) {
162
- return false;
163
- }
164
- if (normalizeManifestPath(manifest.path) !== managedRelativeExecutable(manifest.versionKey)) {
165
- return false;
166
- }
167
-
168
- const resolved = resolveManifestPath(binDir, manifest.path);
169
- return Boolean(resolved && fs.existsSync(resolved) && payloadMatchesManifest(manifest, packageInfo));
170
- }
171
-
172
- function readInstalledManifest(packageInfo) {
173
- const binDir = managedBinDir();
174
- if (!binDir) {
175
- return null;
176
- }
177
-
178
- const manifest = readCurrentManifest(binDir);
179
- if (!manifestMatchesPackage(manifest, binDir, packageInfo)) {
180
- return null;
181
- }
182
- return manifest;
183
- }
184
-
185
- function readInstalledExecutable(packageInfo) {
186
- const binDir = managedBinDir();
187
- const manifest = readInstalledManifest(packageInfo);
188
- if (!binDir || !manifest) {
189
- return null;
190
- }
191
- return resolveManifestPath(binDir, manifest.path);
192
- }
193
-
194
- function writeManifest(manifestPath, manifest) {
195
- const nonce = Math.random().toString(36).slice(2, 10);
196
- const tmpPath = `${manifestPath}.${process.pid}.${nonce}.tmp`;
197
- fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
198
- fs.writeFileSync(tmpPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
199
- fs.renameSync(tmpPath, manifestPath);
200
- }
201
-
202
- function copyPayloadDirectory(srcDir, destDir) {
203
- fs.mkdirSync(destDir, { recursive: true });
204
- const entries = fs.readdirSync(srcDir, { withFileTypes: true });
205
- for (const entry of entries) {
206
- const src = path.join(srcDir, entry.name);
207
- const dest = path.join(destDir, entry.name);
208
- if (entry.isDirectory()) {
209
- copyPayloadDirectory(src, dest);
210
- } else if (entry.isFile()) {
211
- fs.mkdirSync(path.dirname(dest), { recursive: true });
212
- fs.copyFileSync(src, dest);
213
- }
214
- }
215
- }
216
-
217
- function resetDirectory(dir) {
218
- try {
219
- fs.rmSync(dir, { recursive: true, force: true });
220
- } catch (_) {
221
- }
222
- fs.mkdirSync(dir, { recursive: true });
223
- }
224
-
225
- function removeDirectoryIfExists(dir) {
226
- try {
227
- fs.rmSync(dir, { recursive: true, force: true });
228
- } catch (_) {
229
- }
230
- }
231
-
232
- function cleanupDirectoryEntries(rootDir, keepName) {
233
- let entries;
234
- try {
235
- entries = fs.readdirSync(rootDir, { withFileTypes: true });
236
- } catch (_) {
237
- return;
238
- }
239
-
240
- for (const entry of entries) {
241
- if (!entry.isDirectory() || entry.name === keepName) {
242
- continue;
243
- }
244
- removeDirectoryIfExists(path.join(rootDir, entry.name));
245
- }
246
- }
247
-
248
- function cleanupLegacyRootFiles(binDir) {
249
- let entries;
250
- try {
251
- entries = fs.readdirSync(binDir, { withFileTypes: true });
252
- } catch (_) {
253
- return;
254
- }
255
-
256
- for (const entry of entries) {
257
- if (!entry.isFile()) {
258
- continue;
259
- }
260
- if (!/^rebon-.+\.exe$/i.test(entry.name)) {
261
- continue;
262
- }
263
- try {
264
- fs.unlinkSync(path.join(binDir, entry.name));
265
- } catch (_) {
266
- }
267
- }
268
- }
269
-
270
- function cleanupOldVersions(binDir, keepVersionKey) {
271
- cleanupDirectoryEntries(path.join(binDir, VERSIONS_DIR), keepVersionKey);
272
- cleanupDirectoryEntries(path.join(binDir, STAGING_DIR), keepVersionKey);
273
- cleanupLegacyRootFiles(binDir);
274
- }
275
-
276
- function promoteStagingDirectory(stagingDir, versionDir) {
277
- fs.mkdirSync(path.dirname(versionDir), { recursive: true });
278
- if (fs.existsSync(versionDir)) {
279
- fs.rmSync(versionDir, { recursive: true, force: true });
280
- }
281
- fs.renameSync(stagingDir, versionDir);
282
- }
283
-
284
- function installToVersionKey(packageInfo, binDir, versionKey) {
285
- const layout = layoutForVersion(binDir, versionKey);
286
- resetDirectory(layout.stagingDir);
287
- copyPayloadDirectory(packageInfo.payloadDir, layout.stagingDir);
288
- promoteStagingDirectory(layout.stagingDir, layout.versionDir);
289
-
290
- writeManifest(layout.manifestPath, {
291
- version: packageInfo.version,
292
- versionKey,
293
- path: layout.manifestRelativePath,
294
- package: packageInfo.name,
295
- payload: packageInfo.payload || payloadSignature(packageInfo.payloadPath),
296
- installedAt: new Date().toISOString(),
297
- });
298
- cleanupOldVersions(binDir, versionKey);
299
- return layout.exePath;
300
- }
301
-
302
- function installManagedPackage(packageInfo) {
303
- const binDir = managedBinDir();
304
- if (!binDir || !fs.existsSync(packageInfo.payloadPath)) {
305
- return null;
306
- }
307
-
308
- const installedManifest = readInstalledManifest(packageInfo);
309
- if (installedManifest) {
310
- cleanupOldVersions(binDir, installedManifest.versionKey);
311
- return resolveManifestPath(binDir, installedManifest.path);
312
- }
313
-
314
- try {
315
- return installToVersionKey(packageInfo, binDir, packageInfo.versionKey);
316
- } catch (error) {
317
- const fallbackVersionKey = payloadSpecificVersionKey(packageInfo);
318
- if (fallbackVersionKey === packageInfo.versionKey) {
319
- throw error;
320
- }
321
- return installToVersionKey(packageInfo, binDir, fallbackVersionKey);
322
- }
323
- }
324
-
325
- function resolveExecutable(packageInfo) {
326
- const info = packageInfo || readPackageInfo();
327
- const installed = readInstalledExecutable(info);
328
- if (installed) {
329
- return { exe: installed, usedFallback: false, installError: null };
330
- }
331
-
332
- let installError = null;
333
- try {
334
- const managed = installManagedPackage(info);
335
- if (managed) {
336
- return { exe: managed, usedFallback: false, installError: null };
337
- }
338
- } catch (error) {
339
- installError = error;
340
- }
341
-
342
- if (fs.existsSync(info.payloadPath)) {
343
- return { exe: info.payloadPath, usedFallback: true, installError };
344
- }
345
-
346
- return { exe: null, usedFallback: false, installError };
347
- }
348
-
349
- function spawnResolvedExecutable(resolved, argv, spawnImpl) {
350
- const child = spawnImpl(resolved.exe, argv, {
351
- stdio: "inherit",
352
- windowsHide: false,
353
- env: { ...process.env, REBON_CODE_MODE_NODE: process.execPath },
354
- });
355
-
356
- child.on("error", (error) => {
357
- console.error(`rebon: failed to start ${resolved.exe}: ${error.message}`);
358
- process.exit(1);
359
- });
360
-
361
- child.on("exit", (code, signal) => {
362
- if (signal) {
363
- try {
364
- process.kill(process.pid, signal);
365
- } catch (_) {
366
- process.exit(1);
367
- }
368
- return;
369
- }
370
- process.exit(code === null ? 1 : code);
371
- });
372
-
373
- return child;
374
- }
375
-
376
- module.exports = {
377
- cleanupOldVersions,
378
- installManagedPackage,
379
- layoutForVersion,
380
- managedBinDir,
381
- managedRelativeExecutable,
382
- payloadSignature,
383
- readCurrentManifest,
384
- readInstalledExecutable,
385
- readPackageInfo,
386
- requireManagedBinDir,
387
- resolveExecutable,
388
- spawnResolvedExecutable,
389
- versionKeyFromPackageJson,
390
- };
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const CURRENT_MANIFEST = "current.json";
7
+ const EXECUTABLE_NAME = "rebon.exe";
8
+ const PAYLOAD_DIR = "payload";
9
+ const VERSIONS_DIR = "versions";
10
+ const STAGING_DIR = "staging";
11
+
12
+ function defaultPackageRoot() {
13
+ return path.resolve(__dirname, "..");
14
+ }
15
+
16
+ function managedBinDir() {
17
+ const base = process.env.LOCALAPPDATA || (process.env.USERPROFILE && path.join(process.env.USERPROFILE, ".rebon"));
18
+ if (!base) {
19
+ return null;
20
+ }
21
+ return path.join(base, "rebon", "bin");
22
+ }
23
+
24
+ function requireManagedBinDir() {
25
+ const binDir = managedBinDir();
26
+ if (!binDir) {
27
+ throw new Error("LOCALAPPDATA and USERPROFILE are both unset; cannot choose a per-user install directory");
28
+ }
29
+ return binDir;
30
+ }
31
+
32
+ function sanitizeVersionPart(value) {
33
+ return String(value || "unknown").replace(/[^0-9A-Za-z._-]/g, "_");
34
+ }
35
+
36
+ function firstString(candidates) {
37
+ for (const candidate of candidates) {
38
+ if (typeof candidate === "string" && candidate.length > 0) {
39
+ return candidate;
40
+ }
41
+ }
42
+ return null;
43
+ }
44
+
45
+ function packageBuildId(packageJson) {
46
+ const rebon = packageJson && packageJson.rebon;
47
+ return firstString([
48
+ rebon && rebon.build,
49
+ rebon && rebon.buildId,
50
+ rebon && rebon.commit,
51
+ rebon && rebon.hash,
52
+ packageJson && packageJson.rebonBuild,
53
+ packageJson && packageJson.rebonBuildId,
54
+ ]);
55
+ }
56
+
57
+ function versionKeyFromPackageJson(packageJson) {
58
+ const version = sanitizeVersionPart(packageJson && packageJson.version);
59
+ const buildId = packageBuildId(packageJson);
60
+ return buildId ? `${version}-${sanitizeVersionPart(buildId)}` : version;
61
+ }
62
+
63
+ function payloadSignature(payloadPath) {
64
+ const stat = fs.statSync(payloadPath);
65
+ return { size: stat.size, mtimeMs: Math.trunc(stat.mtimeMs) };
66
+ }
67
+
68
+ function readPackageInfo(packageRoot) {
69
+ const root = path.resolve(packageRoot || defaultPackageRoot());
70
+ const packageJson = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
71
+ const payloadDir = path.join(root, PAYLOAD_DIR);
72
+ const payloadPath = path.join(payloadDir, EXECUTABLE_NAME);
73
+ return {
74
+ packageRoot: root,
75
+ name: String(packageJson.name || "rebon"),
76
+ version: String(packageJson.version || "unknown"),
77
+ versionKey: versionKeyFromPackageJson(packageJson),
78
+ payloadDir,
79
+ payloadPath,
80
+ payload: fs.existsSync(payloadPath) ? payloadSignature(payloadPath) : null,
81
+ };
82
+ }
83
+
84
+ function managedRelativeExecutable(versionKey) {
85
+ return `${VERSIONS_DIR}/${versionKey}/${EXECUTABLE_NAME}`;
86
+ }
87
+
88
+ function payloadSpecificVersionKey(packageInfo) {
89
+ if (!packageInfo.payload) {
90
+ return packageInfo.versionKey;
91
+ }
92
+ return `${packageInfo.versionKey}-${packageInfo.payload.size}-${packageInfo.payload.mtimeMs}`;
93
+ }
94
+
95
+ function acceptedVersionKeys(packageInfo) {
96
+ const keys = [packageInfo.versionKey];
97
+ const payloadKey = payloadSpecificVersionKey(packageInfo);
98
+ if (payloadKey !== packageInfo.versionKey) {
99
+ keys.push(payloadKey);
100
+ }
101
+ return keys;
102
+ }
103
+
104
+ function layoutForVersion(binDir, versionKey) {
105
+ const versionDir = path.join(binDir, VERSIONS_DIR, versionKey);
106
+ const stagingDir = path.join(binDir, STAGING_DIR, versionKey);
107
+ return {
108
+ versionDir,
109
+ stagingDir,
110
+ exePath: path.join(versionDir, EXECUTABLE_NAME),
111
+ manifestPath: path.join(binDir, CURRENT_MANIFEST),
112
+ manifestRelativePath: managedRelativeExecutable(versionKey),
113
+ };
114
+ }
115
+
116
+ function normalizeManifestPath(value) {
117
+ return String(value || "").replace(/\\/g, "/").replace(/\/+/g, "/");
118
+ }
119
+
120
+ function resolveManifestPath(binDir, manifestPath) {
121
+ if (typeof manifestPath !== "string" || path.isAbsolute(manifestPath)) {
122
+ return null;
123
+ }
124
+
125
+ const resolved = path.resolve(binDir, manifestPath.replace(/[\\/]+/g, path.sep));
126
+ const relative = path.relative(path.resolve(binDir), resolved);
127
+ if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
128
+ return null;
129
+ }
130
+ return resolved;
131
+ }
132
+
133
+ function readCurrentManifest(binDir) {
134
+ try {
135
+ return JSON.parse(fs.readFileSync(path.join(binDir, CURRENT_MANIFEST), "utf8"));
136
+ } catch (_) {
137
+ return null;
138
+ }
139
+ }
140
+
141
+ function payloadMatchesManifest(manifest, packageInfo) {
142
+ if (!packageInfo.payload) {
143
+ return true;
144
+ }
145
+ if (!manifest.payload) {
146
+ return false;
147
+ }
148
+ return (
149
+ Number(manifest.payload.size) === packageInfo.payload.size &&
150
+ Math.trunc(Number(manifest.payload.mtimeMs)) === packageInfo.payload.mtimeMs
151
+ );
152
+ }
153
+
154
+ function manifestMatchesPackage(manifest, binDir, packageInfo) {
155
+ if (!manifest) {
156
+ return false;
157
+ }
158
+ if (manifest.package !== packageInfo.name || manifest.version !== packageInfo.version) {
159
+ return false;
160
+ }
161
+ if (!acceptedVersionKeys(packageInfo).includes(manifest.versionKey)) {
162
+ return false;
163
+ }
164
+ if (normalizeManifestPath(manifest.path) !== managedRelativeExecutable(manifest.versionKey)) {
165
+ return false;
166
+ }
167
+
168
+ const resolved = resolveManifestPath(binDir, manifest.path);
169
+ return Boolean(resolved && fs.existsSync(resolved) && payloadMatchesManifest(manifest, packageInfo));
170
+ }
171
+
172
+ function readInstalledManifest(packageInfo) {
173
+ const binDir = managedBinDir();
174
+ if (!binDir) {
175
+ return null;
176
+ }
177
+
178
+ const manifest = readCurrentManifest(binDir);
179
+ if (!manifestMatchesPackage(manifest, binDir, packageInfo)) {
180
+ return null;
181
+ }
182
+ return manifest;
183
+ }
184
+
185
+ function readInstalledExecutable(packageInfo) {
186
+ const binDir = managedBinDir();
187
+ const manifest = readInstalledManifest(packageInfo);
188
+ if (!binDir || !manifest) {
189
+ return null;
190
+ }
191
+ return resolveManifestPath(binDir, manifest.path);
192
+ }
193
+
194
+ function writeManifest(manifestPath, manifest) {
195
+ const nonce = Math.random().toString(36).slice(2, 10);
196
+ const tmpPath = `${manifestPath}.${process.pid}.${nonce}.tmp`;
197
+ fs.mkdirSync(path.dirname(manifestPath), { recursive: true });
198
+ fs.writeFileSync(tmpPath, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
199
+ fs.renameSync(tmpPath, manifestPath);
200
+ }
201
+
202
+ function copyPayloadDirectory(srcDir, destDir) {
203
+ fs.mkdirSync(destDir, { recursive: true });
204
+ const entries = fs.readdirSync(srcDir, { withFileTypes: true });
205
+ for (const entry of entries) {
206
+ const src = path.join(srcDir, entry.name);
207
+ const dest = path.join(destDir, entry.name);
208
+ if (entry.isDirectory()) {
209
+ copyPayloadDirectory(src, dest);
210
+ } else if (entry.isFile()) {
211
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
212
+ fs.copyFileSync(src, dest);
213
+ }
214
+ }
215
+ }
216
+
217
+ function resetDirectory(dir) {
218
+ try {
219
+ fs.rmSync(dir, { recursive: true, force: true });
220
+ } catch (_) {
221
+ }
222
+ fs.mkdirSync(dir, { recursive: true });
223
+ }
224
+
225
+ function removeDirectoryIfExists(dir) {
226
+ try {
227
+ fs.rmSync(dir, { recursive: true, force: true });
228
+ } catch (_) {
229
+ }
230
+ }
231
+
232
+ function cleanupDirectoryEntries(rootDir, keepName) {
233
+ let entries;
234
+ try {
235
+ entries = fs.readdirSync(rootDir, { withFileTypes: true });
236
+ } catch (_) {
237
+ return;
238
+ }
239
+
240
+ for (const entry of entries) {
241
+ if (!entry.isDirectory() || entry.name === keepName) {
242
+ continue;
243
+ }
244
+ removeDirectoryIfExists(path.join(rootDir, entry.name));
245
+ }
246
+ }
247
+
248
+ function cleanupLegacyRootFiles(binDir) {
249
+ let entries;
250
+ try {
251
+ entries = fs.readdirSync(binDir, { withFileTypes: true });
252
+ } catch (_) {
253
+ return;
254
+ }
255
+
256
+ for (const entry of entries) {
257
+ if (!entry.isFile()) {
258
+ continue;
259
+ }
260
+ if (!/^rebon-.+\.exe$/i.test(entry.name)) {
261
+ continue;
262
+ }
263
+ try {
264
+ fs.unlinkSync(path.join(binDir, entry.name));
265
+ } catch (_) {
266
+ }
267
+ }
268
+ }
269
+
270
+ function cleanupOldVersions(binDir, keepVersionKey) {
271
+ cleanupDirectoryEntries(path.join(binDir, VERSIONS_DIR), keepVersionKey);
272
+ cleanupDirectoryEntries(path.join(binDir, STAGING_DIR), keepVersionKey);
273
+ cleanupLegacyRootFiles(binDir);
274
+ }
275
+
276
+ function promoteStagingDirectory(stagingDir, versionDir) {
277
+ fs.mkdirSync(path.dirname(versionDir), { recursive: true });
278
+ if (fs.existsSync(versionDir)) {
279
+ fs.rmSync(versionDir, { recursive: true, force: true });
280
+ }
281
+ fs.renameSync(stagingDir, versionDir);
282
+ }
283
+
284
+ function installToVersionKey(packageInfo, binDir, versionKey) {
285
+ const layout = layoutForVersion(binDir, versionKey);
286
+ resetDirectory(layout.stagingDir);
287
+ copyPayloadDirectory(packageInfo.payloadDir, layout.stagingDir);
288
+ promoteStagingDirectory(layout.stagingDir, layout.versionDir);
289
+
290
+ writeManifest(layout.manifestPath, {
291
+ version: packageInfo.version,
292
+ versionKey,
293
+ path: layout.manifestRelativePath,
294
+ package: packageInfo.name,
295
+ payload: packageInfo.payload || payloadSignature(packageInfo.payloadPath),
296
+ installedAt: new Date().toISOString(),
297
+ });
298
+ cleanupOldVersions(binDir, versionKey);
299
+ return layout.exePath;
300
+ }
301
+
302
+ function installManagedPackage(packageInfo) {
303
+ const binDir = managedBinDir();
304
+ if (!binDir || !fs.existsSync(packageInfo.payloadPath)) {
305
+ return null;
306
+ }
307
+
308
+ const installedManifest = readInstalledManifest(packageInfo);
309
+ if (installedManifest) {
310
+ cleanupOldVersions(binDir, installedManifest.versionKey);
311
+ return resolveManifestPath(binDir, installedManifest.path);
312
+ }
313
+
314
+ try {
315
+ return installToVersionKey(packageInfo, binDir, packageInfo.versionKey);
316
+ } catch (error) {
317
+ const fallbackVersionKey = payloadSpecificVersionKey(packageInfo);
318
+ if (fallbackVersionKey === packageInfo.versionKey) {
319
+ throw error;
320
+ }
321
+ return installToVersionKey(packageInfo, binDir, fallbackVersionKey);
322
+ }
323
+ }
324
+
325
+ function resolveExecutable(packageInfo) {
326
+ const info = packageInfo || readPackageInfo();
327
+ const installed = readInstalledExecutable(info);
328
+ if (installed) {
329
+ return { exe: installed, usedFallback: false, installError: null };
330
+ }
331
+
332
+ let installError = null;
333
+ try {
334
+ const managed = installManagedPackage(info);
335
+ if (managed) {
336
+ return { exe: managed, usedFallback: false, installError: null };
337
+ }
338
+ } catch (error) {
339
+ installError = error;
340
+ }
341
+
342
+ if (fs.existsSync(info.payloadPath)) {
343
+ return { exe: info.payloadPath, usedFallback: true, installError };
344
+ }
345
+
346
+ return { exe: null, usedFallback: false, installError };
347
+ }
348
+
349
+ function spawnResolvedExecutable(resolved, argv, spawnImpl) {
350
+ const child = spawnImpl(resolved.exe, argv, {
351
+ stdio: "inherit",
352
+ windowsHide: false,
353
+ env: { ...process.env, REBON_CODE_MODE_NODE: process.execPath },
354
+ });
355
+
356
+ child.on("error", (error) => {
357
+ console.error(`rebon: failed to start ${resolved.exe}: ${error.message}`);
358
+ process.exit(1);
359
+ });
360
+
361
+ child.on("exit", (code, signal) => {
362
+ if (signal) {
363
+ try {
364
+ process.kill(process.pid, signal);
365
+ } catch (_) {
366
+ process.exit(1);
367
+ }
368
+ return;
369
+ }
370
+ process.exit(code === null ? 1 : code);
371
+ });
372
+
373
+ return child;
374
+ }
375
+
376
+ module.exports = {
377
+ cleanupOldVersions,
378
+ installManagedPackage,
379
+ layoutForVersion,
380
+ managedBinDir,
381
+ managedRelativeExecutable,
382
+ payloadSignature,
383
+ readCurrentManifest,
384
+ readInstalledExecutable,
385
+ readPackageInfo,
386
+ requireManagedBinDir,
387
+ resolveExecutable,
388
+ spawnResolvedExecutable,
389
+ versionKeyFromPackageJson,
390
+ };