orkestrator 2.26.3-beta → 2.28.0-beta
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.
- package/dist/client.js +508 -209
- package/dist/main.js +16148 -10171
- package/package.json +4 -4
- package/resources/claude-bridge/dist/index.js +132 -25
- package/resources/codex-bridge/dist/index.js +266 -31
package/dist/client.js
CHANGED
|
@@ -131,22 +131,22 @@ __export(exports_standalone_service, {
|
|
|
131
131
|
writeServiceConfig: () => writeServiceConfig
|
|
132
132
|
});
|
|
133
133
|
import { execFile } from "child_process";
|
|
134
|
-
import { existsSync as
|
|
134
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, readlinkSync } from "fs";
|
|
135
135
|
import { copyFile, mkdir, readFile, rename, rm, symlink, writeFile } from "fs/promises";
|
|
136
|
-
import
|
|
136
|
+
import path13 from "path";
|
|
137
137
|
import { promisify } from "util";
|
|
138
138
|
function standaloneLayout(dataDir) {
|
|
139
|
-
const root =
|
|
139
|
+
const root = path13.join(dataDir, STANDALONE_DIRECTORY);
|
|
140
140
|
return {
|
|
141
141
|
root,
|
|
142
|
-
releases:
|
|
143
|
-
current:
|
|
144
|
-
previous:
|
|
145
|
-
serviceFile:
|
|
146
|
-
stateFile:
|
|
147
|
-
restartMarker:
|
|
148
|
-
launcher:
|
|
149
|
-
logs:
|
|
142
|
+
releases: path13.join(root, "releases"),
|
|
143
|
+
current: path13.join(root, "current"),
|
|
144
|
+
previous: path13.join(root, "previous"),
|
|
145
|
+
serviceFile: path13.join(root, "service.json"),
|
|
146
|
+
stateFile: path13.join(root, "launcher-state.json"),
|
|
147
|
+
restartMarker: path13.join(root, "restart-requested"),
|
|
148
|
+
launcher: path13.join(root, "launcher.js"),
|
|
149
|
+
logs: path13.join(root, "logs")
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
152
|
function readJson(file) {
|
|
@@ -192,28 +192,28 @@ async function writeAtomically(file, contents) {
|
|
|
192
192
|
}
|
|
193
193
|
function linkedVersion(link) {
|
|
194
194
|
try {
|
|
195
|
-
return
|
|
195
|
+
return path13.basename(readlinkSync(link));
|
|
196
196
|
} catch {
|
|
197
197
|
return null;
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
function releaseDirectory(layout, version) {
|
|
201
|
-
return
|
|
201
|
+
return path13.join(layout.releases, version);
|
|
202
202
|
}
|
|
203
203
|
function releasePackageRoot(releaseDir) {
|
|
204
|
-
return
|
|
204
|
+
return path13.join(releaseDir, "node_modules", STANDALONE_PACKAGE);
|
|
205
205
|
}
|
|
206
206
|
function releaseEntry(releaseDir) {
|
|
207
|
-
return
|
|
207
|
+
return path13.join(releasePackageRoot(releaseDir), "bin", "orkestrator.js");
|
|
208
208
|
}
|
|
209
209
|
function releaseLauncher(releaseDir) {
|
|
210
|
-
return
|
|
210
|
+
return path13.join(releasePackageRoot(releaseDir), "bin", "orkestrator-launcher.js");
|
|
211
211
|
}
|
|
212
212
|
function readReleaseManifest(releaseDir) {
|
|
213
|
-
const manifest = readJson(
|
|
213
|
+
const manifest = readJson(path13.join(releasePackageRoot(releaseDir), "package.json"));
|
|
214
214
|
if (!manifest || typeof manifest.version !== "string")
|
|
215
215
|
return null;
|
|
216
|
-
if (!
|
|
216
|
+
if (!existsSync4(releaseEntry(releaseDir)))
|
|
217
217
|
return null;
|
|
218
218
|
return {
|
|
219
219
|
version: manifest.version,
|
|
@@ -226,11 +226,11 @@ async function installRelease(layout, version, options2) {
|
|
|
226
226
|
return target;
|
|
227
227
|
const run = options2.run ?? runFile;
|
|
228
228
|
await mkdir(layout.releases, { recursive: true });
|
|
229
|
-
const staging =
|
|
229
|
+
const staging = path13.join(layout.releases, `.staging-${version}-${process.pid}`);
|
|
230
230
|
await rm(staging, { recursive: true, force: true });
|
|
231
231
|
await mkdir(staging, { recursive: true });
|
|
232
232
|
try {
|
|
233
|
-
await writeFile(
|
|
233
|
+
await writeFile(path13.join(staging, "package.json"), `${JSON.stringify({
|
|
234
234
|
name: "orkestrator-release",
|
|
235
235
|
private: true,
|
|
236
236
|
dependencies: { [STANDALONE_PACKAGE]: version }
|
|
@@ -4356,11 +4356,11 @@ function pinnedToolchainArtifacts(platform = process.platform, architecture = pr
|
|
|
4356
4356
|
var PINNED_TOOLCHAIN_VERSIONS, PINNED_SUPPORT_TOOL_VERSIONS, PINNED_TOOL_VERSIONS, GITHUB_RELEASE_HOSTS, NPM_REGISTRY_HOSTS, GROK_DOWNLOAD_HOSTS, CODEX_RELEASE_BASE, PI_RELEASE_BASE, GH_RELEASE_BASE, OPENCODE_RELEASE_BASE, CODEX_CODE_MODE_HOST_FILE_NAME = "codex-code-mode-host", PINNED_TOOLCHAIN_ARTIFACTS;
|
|
4357
4357
|
var init_manifest = __esm(() => {
|
|
4358
4358
|
PINNED_TOOLCHAIN_VERSIONS = {
|
|
4359
|
-
claude: "2.1.
|
|
4360
|
-
codex: "0.
|
|
4361
|
-
grok: "1.0.
|
|
4362
|
-
opencode: "1.19.
|
|
4363
|
-
pi: "1.
|
|
4359
|
+
claude: "2.1.309",
|
|
4360
|
+
codex: "0.164.0",
|
|
4361
|
+
grok: "1.0.67",
|
|
4362
|
+
opencode: "1.19.4",
|
|
4363
|
+
pi: "1.4.0"
|
|
4364
4364
|
};
|
|
4365
4365
|
PINNED_SUPPORT_TOOL_VERSIONS = {
|
|
4366
4366
|
gh: "2.102.0"
|
|
@@ -4390,23 +4390,23 @@ var init_manifest = __esm(() => {
|
|
|
4390
4390
|
format: "tar.gz",
|
|
4391
4391
|
url: `${CODEX_RELEASE_BASE}/codex-aarch64-apple-darwin.tar.gz`,
|
|
4392
4392
|
entryPath: "codex-aarch64-apple-darwin",
|
|
4393
|
-
size:
|
|
4394
|
-
sha256: "
|
|
4393
|
+
size: 101767166,
|
|
4394
|
+
sha256: "aa8299c169d80111aac05543ad2621c9bdbedb9bc252c905fe3f5a5baf9a4142",
|
|
4395
4395
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4396
4396
|
},
|
|
4397
4397
|
companions: [
|
|
4398
4398
|
codexCodeModeHost("aarch64-apple-darwin", {
|
|
4399
|
-
size:
|
|
4400
|
-
sha256: "
|
|
4399
|
+
size: 24347400,
|
|
4400
|
+
sha256: "7bc3ca697567bc884a76233999c46cb22b023b09f2d4d4ab3518f1354c64e415"
|
|
4401
4401
|
}, {
|
|
4402
|
-
size:
|
|
4403
|
-
sha256: "
|
|
4402
|
+
size: 68543072,
|
|
4403
|
+
sha256: "416721e33af8822041dc650793512b3e58d43e0be4f3a5c6187eb4dfaad3148a"
|
|
4404
4404
|
})
|
|
4405
4405
|
],
|
|
4406
4406
|
executable: {
|
|
4407
4407
|
fileName: "codex",
|
|
4408
|
-
size:
|
|
4409
|
-
sha256: "
|
|
4408
|
+
size: 260293200,
|
|
4409
|
+
sha256: "d8990e3ee7acfbc26f91265b12a1a83f0fee40d0e0f8f1f40a37d4ec21f499cf"
|
|
4410
4410
|
}
|
|
4411
4411
|
},
|
|
4412
4412
|
{
|
|
@@ -4418,23 +4418,23 @@ var init_manifest = __esm(() => {
|
|
|
4418
4418
|
format: "tar.gz",
|
|
4419
4419
|
url: `${CODEX_RELEASE_BASE}/codex-x86_64-apple-darwin.tar.gz`,
|
|
4420
4420
|
entryPath: "codex-x86_64-apple-darwin",
|
|
4421
|
-
size:
|
|
4422
|
-
sha256: "
|
|
4421
|
+
size: 110491441,
|
|
4422
|
+
sha256: "de6bbc013c56337f6ddd3f26dfbfd62aad5924cb68cd5ef6430538922bfa0e75",
|
|
4423
4423
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4424
4424
|
},
|
|
4425
4425
|
companions: [
|
|
4426
4426
|
codexCodeModeHost("x86_64-apple-darwin", {
|
|
4427
|
-
size:
|
|
4428
|
-
sha256: "
|
|
4427
|
+
size: 26213130,
|
|
4428
|
+
sha256: "50f93d5413647488940aa23db9b1c822ee86f2c45fa37af34993e992c9848211"
|
|
4429
4429
|
}, {
|
|
4430
|
-
size:
|
|
4431
|
-
sha256: "
|
|
4430
|
+
size: 72251296,
|
|
4431
|
+
sha256: "067f9c14f67b02bdb984d4fc4740da14cd397da7ee60b4506eb378921afe3e7d"
|
|
4432
4432
|
})
|
|
4433
4433
|
],
|
|
4434
4434
|
executable: {
|
|
4435
4435
|
fileName: "codex",
|
|
4436
|
-
size:
|
|
4437
|
-
sha256: "
|
|
4436
|
+
size: 279923568,
|
|
4437
|
+
sha256: "d7e19691e0c1945612475ee8ab32e59ead55472e976b5cea1682d827d34dbba1"
|
|
4438
4438
|
}
|
|
4439
4439
|
},
|
|
4440
4440
|
{
|
|
@@ -4446,23 +4446,23 @@ var init_manifest = __esm(() => {
|
|
|
4446
4446
|
format: "tar.gz",
|
|
4447
4447
|
url: `${CODEX_RELEASE_BASE}/codex-aarch64-unknown-linux-musl.tar.gz`,
|
|
4448
4448
|
entryPath: "codex-aarch64-unknown-linux-musl",
|
|
4449
|
-
size:
|
|
4450
|
-
sha256: "
|
|
4449
|
+
size: 106977873,
|
|
4450
|
+
sha256: "29a507a2a3fd8f6cd94b96b762d281d299d15d7902dee6132d314b78cf9108eb",
|
|
4451
4451
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4452
4452
|
},
|
|
4453
4453
|
companions: [
|
|
4454
4454
|
codexCodeModeHost("aarch64-unknown-linux-musl", {
|
|
4455
|
-
size:
|
|
4456
|
-
sha256: "
|
|
4455
|
+
size: 26642339,
|
|
4456
|
+
sha256: "0e0bdde24d5b31b05519693635baa9c4f2dc4fe7eee31c67b92155f190dd32d2"
|
|
4457
4457
|
}, {
|
|
4458
|
-
size:
|
|
4459
|
-
sha256: "
|
|
4458
|
+
size: 70117728,
|
|
4459
|
+
sha256: "7d28b996b825b13ea058af67655b619a26a125d61d4fb2985694a9c4e77d2e21"
|
|
4460
4460
|
})
|
|
4461
4461
|
],
|
|
4462
4462
|
executable: {
|
|
4463
4463
|
fileName: "codex",
|
|
4464
|
-
size:
|
|
4465
|
-
sha256: "
|
|
4464
|
+
size: 268045528,
|
|
4465
|
+
sha256: "8813c8d8a4cea2eeba271b72ab22f49628b184b24ab18dbef06b4ce41e9a8d39"
|
|
4466
4466
|
}
|
|
4467
4467
|
},
|
|
4468
4468
|
{
|
|
@@ -4474,23 +4474,23 @@ var init_manifest = __esm(() => {
|
|
|
4474
4474
|
format: "tar.gz",
|
|
4475
4475
|
url: `${CODEX_RELEASE_BASE}/codex-x86_64-unknown-linux-musl.tar.gz`,
|
|
4476
4476
|
entryPath: "codex-x86_64-unknown-linux-musl",
|
|
4477
|
-
size:
|
|
4478
|
-
sha256: "
|
|
4477
|
+
size: 114979035,
|
|
4478
|
+
sha256: "90dd0b03b28afcb7fa733a4f73b413db2916a47347efd43fb669cc1c774ee8e4",
|
|
4479
4479
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4480
4480
|
},
|
|
4481
4481
|
companions: [
|
|
4482
4482
|
codexCodeModeHost("x86_64-unknown-linux-musl", {
|
|
4483
|
-
size:
|
|
4484
|
-
sha256: "
|
|
4483
|
+
size: 28137475,
|
|
4484
|
+
sha256: "feade7026436baa4e82e898050c7ef82a8adbd98163dc504771275b5ef224f2f"
|
|
4485
4485
|
}, {
|
|
4486
|
-
size:
|
|
4487
|
-
sha256: "
|
|
4486
|
+
size: 76997904,
|
|
4487
|
+
sha256: "8ee4f472e92ac226a189e98998633b2d07f989f208515750764db660369f2926"
|
|
4488
4488
|
})
|
|
4489
4489
|
],
|
|
4490
4490
|
executable: {
|
|
4491
4491
|
fileName: "codex",
|
|
4492
|
-
size:
|
|
4493
|
-
sha256: "
|
|
4492
|
+
size: 308139304,
|
|
4493
|
+
sha256: "b93f6811d3f653f0fb83be4050d857fb9abbb111dfa2ce160563327daff7f306"
|
|
4494
4494
|
}
|
|
4495
4495
|
},
|
|
4496
4496
|
{
|
|
@@ -4502,14 +4502,14 @@ var init_manifest = __esm(() => {
|
|
|
4502
4502
|
format: "zip",
|
|
4503
4503
|
url: `${OPENCODE_RELEASE_BASE}/opencode-darwin-arm64.zip`,
|
|
4504
4504
|
entryPath: "opencode",
|
|
4505
|
-
size:
|
|
4506
|
-
sha256: "
|
|
4505
|
+
size: 64291659,
|
|
4506
|
+
sha256: "c400a2f8c8ab7e99478a7f4dd1a466b57bf33888e520d85c55780a5464c4b689",
|
|
4507
4507
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4508
4508
|
},
|
|
4509
4509
|
executable: {
|
|
4510
4510
|
fileName: "opencode",
|
|
4511
|
-
size:
|
|
4512
|
-
sha256: "
|
|
4511
|
+
size: 180803872,
|
|
4512
|
+
sha256: "417af53923f3d529759ab85ce3e8dd09116f742efcd332de591d2da6ebae696b",
|
|
4513
4513
|
repairInvalidMacSignature: true
|
|
4514
4514
|
}
|
|
4515
4515
|
},
|
|
@@ -4522,14 +4522,14 @@ var init_manifest = __esm(() => {
|
|
|
4522
4522
|
format: "zip",
|
|
4523
4523
|
url: `${OPENCODE_RELEASE_BASE}/opencode-darwin-x64.zip`,
|
|
4524
4524
|
entryPath: "opencode",
|
|
4525
|
-
size:
|
|
4526
|
-
sha256: "
|
|
4525
|
+
size: 69113309,
|
|
4526
|
+
sha256: "123ebd72609c4f8dbae0485cdac39b9aedfeb6576b2eef64f2e73152b1de82f4",
|
|
4527
4527
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4528
4528
|
},
|
|
4529
4529
|
executable: {
|
|
4530
4530
|
fileName: "opencode",
|
|
4531
|
-
size:
|
|
4532
|
-
sha256: "
|
|
4531
|
+
size: 194103008,
|
|
4532
|
+
sha256: "6d6a980039553a6b4efe2221fdbd5e8945abf3c2365d97fcab097713a327228f",
|
|
4533
4533
|
repairInvalidMacSignature: true
|
|
4534
4534
|
}
|
|
4535
4535
|
},
|
|
@@ -4542,14 +4542,14 @@ var init_manifest = __esm(() => {
|
|
|
4542
4542
|
format: "tar.gz",
|
|
4543
4543
|
url: `${OPENCODE_RELEASE_BASE}/opencode-linux-arm64.tar.gz`,
|
|
4544
4544
|
entryPath: "opencode",
|
|
4545
|
-
size:
|
|
4546
|
-
sha256: "
|
|
4545
|
+
size: 78526339,
|
|
4546
|
+
sha256: "8568230ccd847dc93e95b9f6894379077d3e014a16b48040743573e77c23e85f",
|
|
4547
4547
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4548
4548
|
},
|
|
4549
4549
|
executable: {
|
|
4550
4550
|
fileName: "opencode",
|
|
4551
|
-
size:
|
|
4552
|
-
sha256: "
|
|
4551
|
+
size: 211340280,
|
|
4552
|
+
sha256: "eba0da50d9cc22f2dd062c32e0e7e58d7ece301aa50aabdad1e9dba4ffbf25b4"
|
|
4553
4553
|
}
|
|
4554
4554
|
},
|
|
4555
4555
|
{
|
|
@@ -4561,14 +4561,14 @@ var init_manifest = __esm(() => {
|
|
|
4561
4561
|
format: "tar.gz",
|
|
4562
4562
|
url: `${OPENCODE_RELEASE_BASE}/opencode-linux-x64.tar.gz`,
|
|
4563
4563
|
entryPath: "opencode",
|
|
4564
|
-
size:
|
|
4565
|
-
sha256: "
|
|
4564
|
+
size: 79667571,
|
|
4565
|
+
sha256: "849bd6b3d959a1d2ef200ed1634a51c79a45ca236aa26665d75debd694805cce",
|
|
4566
4566
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4567
4567
|
},
|
|
4568
4568
|
executable: {
|
|
4569
4569
|
fileName: "opencode",
|
|
4570
|
-
size:
|
|
4571
|
-
sha256: "
|
|
4570
|
+
size: 214522032,
|
|
4571
|
+
sha256: "538fcb1b6408c8d4608822acee19f7ff5b3a3eb3383c0633c4f06170857312a7"
|
|
4572
4572
|
}
|
|
4573
4573
|
},
|
|
4574
4574
|
{
|
|
@@ -4580,14 +4580,14 @@ var init_manifest = __esm(() => {
|
|
|
4580
4580
|
format: "tar.gz",
|
|
4581
4581
|
url: claudeArchiveUrl("darwin-arm64"),
|
|
4582
4582
|
entryPath: "package/claude",
|
|
4583
|
-
size:
|
|
4584
|
-
sha256: "
|
|
4583
|
+
size: 122689402,
|
|
4584
|
+
sha256: "0e8ce1ddb8566129661bb7698db69db89d904e23b464afc6e85d5bd8879b9a51",
|
|
4585
4585
|
allowedHosts: NPM_REGISTRY_HOSTS
|
|
4586
4586
|
},
|
|
4587
4587
|
executable: {
|
|
4588
4588
|
fileName: "claude",
|
|
4589
|
-
size:
|
|
4590
|
-
sha256: "
|
|
4589
|
+
size: 275923296,
|
|
4590
|
+
sha256: "5eadc0009cdcdbc0d06e58110d7b2baf88ced6088b1c33a60a21217fe410619c"
|
|
4591
4591
|
}
|
|
4592
4592
|
},
|
|
4593
4593
|
{
|
|
@@ -4599,14 +4599,14 @@ var init_manifest = __esm(() => {
|
|
|
4599
4599
|
format: "tar.gz",
|
|
4600
4600
|
url: claudeArchiveUrl("darwin-x64"),
|
|
4601
4601
|
entryPath: "package/claude",
|
|
4602
|
-
size:
|
|
4603
|
-
sha256: "
|
|
4602
|
+
size: 127778018,
|
|
4603
|
+
sha256: "58f2fcea83ddc59839353a55dafc2a8cd084b8acb9bf7131ff7db48a28604c33",
|
|
4604
4604
|
allowedHosts: NPM_REGISTRY_HOSTS
|
|
4605
4605
|
},
|
|
4606
4606
|
executable: {
|
|
4607
4607
|
fileName: "claude",
|
|
4608
|
-
size:
|
|
4609
|
-
sha256: "
|
|
4608
|
+
size: 287157296,
|
|
4609
|
+
sha256: "200e0d775ae55c040db3bb8db8de3e22efcddbd7e0abff5ab50dd10f6853425d"
|
|
4610
4610
|
}
|
|
4611
4611
|
},
|
|
4612
4612
|
{
|
|
@@ -4618,14 +4618,14 @@ var init_manifest = __esm(() => {
|
|
|
4618
4618
|
format: "tar.gz",
|
|
4619
4619
|
url: claudeArchiveUrl("linux-arm64"),
|
|
4620
4620
|
entryPath: "package/claude",
|
|
4621
|
-
size:
|
|
4622
|
-
sha256: "
|
|
4621
|
+
size: 133084470,
|
|
4622
|
+
sha256: "3108f1bf04723cd654cf98269eb861827a15d9256db13ebf88a09d3b497926b2",
|
|
4623
4623
|
allowedHosts: NPM_REGISTRY_HOSTS
|
|
4624
4624
|
},
|
|
4625
4625
|
executable: {
|
|
4626
4626
|
fileName: "claude",
|
|
4627
|
-
size:
|
|
4628
|
-
sha256: "
|
|
4627
|
+
size: 293331128,
|
|
4628
|
+
sha256: "9796dd26899337f687739a0b39a7353b639f062a3436a7b941fcf19a1b757a9b"
|
|
4629
4629
|
}
|
|
4630
4630
|
},
|
|
4631
4631
|
{
|
|
@@ -4637,14 +4637,14 @@ var init_manifest = __esm(() => {
|
|
|
4637
4637
|
format: "tar.gz",
|
|
4638
4638
|
url: claudeArchiveUrl("linux-x64"),
|
|
4639
4639
|
entryPath: "package/claude",
|
|
4640
|
-
size:
|
|
4641
|
-
sha256: "
|
|
4640
|
+
size: 132508222,
|
|
4641
|
+
sha256: "e960c4437f6f99648437784db43e04ad5f12711aecd710864f96876f94c2fc1a",
|
|
4642
4642
|
allowedHosts: NPM_REGISTRY_HOSTS
|
|
4643
4643
|
},
|
|
4644
4644
|
executable: {
|
|
4645
4645
|
fileName: "claude",
|
|
4646
|
-
size:
|
|
4647
|
-
sha256: "
|
|
4646
|
+
size: 293469552,
|
|
4647
|
+
sha256: "4d704a8aecbe038affa3000f498ae17c1b4f753add8facb8764120affc99b658"
|
|
4648
4648
|
}
|
|
4649
4649
|
},
|
|
4650
4650
|
{
|
|
@@ -4656,14 +4656,14 @@ var init_manifest = __esm(() => {
|
|
|
4656
4656
|
format: "raw",
|
|
4657
4657
|
url: `https://storage.googleapis.com/grok-build-public-artifacts/cli/grok-${PINNED_TOOLCHAIN_VERSIONS.grok}-macos-aarch64`,
|
|
4658
4658
|
entryPath: "",
|
|
4659
|
-
size:
|
|
4660
|
-
sha256: "
|
|
4659
|
+
size: 177770992,
|
|
4660
|
+
sha256: "036a47ce2987adae04de827f7803bf0cc460bf169b640db168f18ec7acb734db",
|
|
4661
4661
|
allowedHosts: GROK_DOWNLOAD_HOSTS
|
|
4662
4662
|
},
|
|
4663
4663
|
executable: {
|
|
4664
4664
|
fileName: "grok",
|
|
4665
|
-
size:
|
|
4666
|
-
sha256: "
|
|
4665
|
+
size: 177770992,
|
|
4666
|
+
sha256: "036a47ce2987adae04de827f7803bf0cc460bf169b640db168f18ec7acb734db"
|
|
4667
4667
|
}
|
|
4668
4668
|
},
|
|
4669
4669
|
{
|
|
@@ -4675,14 +4675,14 @@ var init_manifest = __esm(() => {
|
|
|
4675
4675
|
format: "raw",
|
|
4676
4676
|
url: `https://storage.googleapis.com/grok-build-public-artifacts/cli/grok-${PINNED_TOOLCHAIN_VERSIONS.grok}-macos-x86_64`,
|
|
4677
4677
|
entryPath: "",
|
|
4678
|
-
size:
|
|
4679
|
-
sha256: "
|
|
4678
|
+
size: 192143296,
|
|
4679
|
+
sha256: "24a951871bfb7b3f6036fc1e1cd2442c664e2b2eeba58de9e8f47de4c633a03e",
|
|
4680
4680
|
allowedHosts: GROK_DOWNLOAD_HOSTS
|
|
4681
4681
|
},
|
|
4682
4682
|
executable: {
|
|
4683
4683
|
fileName: "grok",
|
|
4684
|
-
size:
|
|
4685
|
-
sha256: "
|
|
4684
|
+
size: 192143296,
|
|
4685
|
+
sha256: "24a951871bfb7b3f6036fc1e1cd2442c664e2b2eeba58de9e8f47de4c633a03e"
|
|
4686
4686
|
}
|
|
4687
4687
|
},
|
|
4688
4688
|
{
|
|
@@ -4694,14 +4694,14 @@ var init_manifest = __esm(() => {
|
|
|
4694
4694
|
format: "raw",
|
|
4695
4695
|
url: `https://storage.googleapis.com/grok-build-public-artifacts/cli/grok-${PINNED_TOOLCHAIN_VERSIONS.grok}-linux-aarch64`,
|
|
4696
4696
|
entryPath: "",
|
|
4697
|
-
size:
|
|
4698
|
-
sha256: "
|
|
4697
|
+
size: 165548280,
|
|
4698
|
+
sha256: "089a0acc2c1b570efcd791c5cd0f8aa074f6e8ab82c00ab78af0b934acdb6386",
|
|
4699
4699
|
allowedHosts: GROK_DOWNLOAD_HOSTS
|
|
4700
4700
|
},
|
|
4701
4701
|
executable: {
|
|
4702
4702
|
fileName: "grok",
|
|
4703
|
-
size:
|
|
4704
|
-
sha256: "
|
|
4703
|
+
size: 165548280,
|
|
4704
|
+
sha256: "089a0acc2c1b570efcd791c5cd0f8aa074f6e8ab82c00ab78af0b934acdb6386"
|
|
4705
4705
|
}
|
|
4706
4706
|
},
|
|
4707
4707
|
{
|
|
@@ -4713,14 +4713,14 @@ var init_manifest = __esm(() => {
|
|
|
4713
4713
|
format: "raw",
|
|
4714
4714
|
url: `https://storage.googleapis.com/grok-build-public-artifacts/cli/grok-${PINNED_TOOLCHAIN_VERSIONS.grok}-linux-x86_64`,
|
|
4715
4715
|
entryPath: "",
|
|
4716
|
-
size:
|
|
4717
|
-
sha256: "
|
|
4716
|
+
size: 194169184,
|
|
4717
|
+
sha256: "ce33b1a29e37901f56fe59916cda7a1149e6fd377118f918e90d89f9abb52a51",
|
|
4718
4718
|
allowedHosts: GROK_DOWNLOAD_HOSTS
|
|
4719
4719
|
},
|
|
4720
4720
|
executable: {
|
|
4721
4721
|
fileName: "grok",
|
|
4722
|
-
size:
|
|
4723
|
-
sha256: "
|
|
4722
|
+
size: 194169184,
|
|
4723
|
+
sha256: "ce33b1a29e37901f56fe59916cda7a1149e6fd377118f918e90d89f9abb52a51"
|
|
4724
4724
|
}
|
|
4725
4725
|
},
|
|
4726
4726
|
{
|
|
@@ -4734,18 +4734,18 @@ var init_manifest = __esm(() => {
|
|
|
4734
4734
|
entryPath: "pi/pi",
|
|
4735
4735
|
bundleRoot: "pi/",
|
|
4736
4736
|
bundleIntegrity: {
|
|
4737
|
-
fileCount:
|
|
4738
|
-
totalSize:
|
|
4739
|
-
sha256: "
|
|
4737
|
+
fileCount: 210,
|
|
4738
|
+
totalSize: 7362755,
|
|
4739
|
+
sha256: "8390783a7e1486f056a1dc473d43683336f1b81626ab00b51fabf98e195916ae"
|
|
4740
4740
|
},
|
|
4741
|
-
size:
|
|
4742
|
-
sha256: "
|
|
4741
|
+
size: 31098931,
|
|
4742
|
+
sha256: "79d9979d76a2a5adb7c28e27e9b44629928ccd0dc9fbb6ae7217860bd5e8be5d",
|
|
4743
4743
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4744
4744
|
},
|
|
4745
4745
|
executable: {
|
|
4746
4746
|
fileName: "pi",
|
|
4747
|
-
size:
|
|
4748
|
-
sha256: "
|
|
4747
|
+
size: 77151074,
|
|
4748
|
+
sha256: "b4d93b78e542ca8d1792242cf6c1a875ef4e6fb644141fb4cf67ec7c81ef9b14",
|
|
4749
4749
|
repairInvalidMacSignature: true
|
|
4750
4750
|
}
|
|
4751
4751
|
},
|
|
@@ -4760,18 +4760,18 @@ var init_manifest = __esm(() => {
|
|
|
4760
4760
|
entryPath: "pi/pi",
|
|
4761
4761
|
bundleRoot: "pi/",
|
|
4762
4762
|
bundleIntegrity: {
|
|
4763
|
-
fileCount:
|
|
4764
|
-
totalSize:
|
|
4765
|
-
sha256: "
|
|
4763
|
+
fileCount: 210,
|
|
4764
|
+
totalSize: 7333515,
|
|
4765
|
+
sha256: "c4af61868d7cc22df475c17b35433d3a4ecc553a4183b869602a120d80673f7f"
|
|
4766
4766
|
},
|
|
4767
|
-
size:
|
|
4768
|
-
sha256: "
|
|
4767
|
+
size: 33558360,
|
|
4768
|
+
sha256: "1bdefc9e1074c1de458ea9f2e43e6013ce49cd05326009b3de144037036585e2",
|
|
4769
4769
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4770
4770
|
},
|
|
4771
4771
|
executable: {
|
|
4772
4772
|
fileName: "pi",
|
|
4773
|
-
size:
|
|
4774
|
-
sha256: "
|
|
4773
|
+
size: 82772048,
|
|
4774
|
+
sha256: "b8e0bd3c24cd8f91a6cf37aa7cecbc3a931702cbffd0f709b26d5a79daeaa48a",
|
|
4775
4775
|
repairInvalidMacSignature: true
|
|
4776
4776
|
}
|
|
4777
4777
|
},
|
|
@@ -4786,18 +4786,18 @@ var init_manifest = __esm(() => {
|
|
|
4786
4786
|
entryPath: "pi/pi",
|
|
4787
4787
|
bundleRoot: "pi/",
|
|
4788
4788
|
bundleIntegrity: {
|
|
4789
|
-
fileCount:
|
|
4790
|
-
totalSize:
|
|
4791
|
-
sha256: "
|
|
4789
|
+
fileCount: 210,
|
|
4790
|
+
totalSize: 7377971,
|
|
4791
|
+
sha256: "8180603c37f66e67aacb554e3a0063ff2c99f8f53592386b9aec9a7465eb9347"
|
|
4792
4792
|
},
|
|
4793
|
-
size:
|
|
4794
|
-
sha256: "
|
|
4793
|
+
size: 42745801,
|
|
4794
|
+
sha256: "fa5829c7ef83ffeaebba015715c8306220f89b2aa8a00154efbba98dd5440156",
|
|
4795
4795
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4796
4796
|
},
|
|
4797
4797
|
executable: {
|
|
4798
4798
|
fileName: "pi",
|
|
4799
|
-
size:
|
|
4800
|
-
sha256: "
|
|
4799
|
+
size: 107260048,
|
|
4800
|
+
sha256: "26507c6bbf0beef1c5ef109dea333ddb73c058f9f75fed1de13f4186d73e919e"
|
|
4801
4801
|
}
|
|
4802
4802
|
},
|
|
4803
4803
|
{
|
|
@@ -4811,18 +4811,18 @@ var init_manifest = __esm(() => {
|
|
|
4811
4811
|
entryPath: "pi/pi",
|
|
4812
4812
|
bundleRoot: "pi/",
|
|
4813
4813
|
bundleIntegrity: {
|
|
4814
|
-
fileCount:
|
|
4815
|
-
totalSize:
|
|
4816
|
-
sha256: "
|
|
4814
|
+
fileCount: 210,
|
|
4815
|
+
totalSize: 7328739,
|
|
4816
|
+
sha256: "1c96ce5e0a7a4d61b3015cb62cfdd09d04e25289c056b33787659c3d41dcc9a8"
|
|
4817
4817
|
},
|
|
4818
|
-
size:
|
|
4819
|
-
sha256: "
|
|
4818
|
+
size: 42645744,
|
|
4819
|
+
sha256: "f2e4e4329603223d03260cdb8bd5033dbdc1f73ba58ab8939db2e56546e115d2",
|
|
4820
4820
|
allowedHosts: GITHUB_RELEASE_HOSTS
|
|
4821
4821
|
},
|
|
4822
4822
|
executable: {
|
|
4823
4823
|
fileName: "pi",
|
|
4824
|
-
size:
|
|
4825
|
-
sha256: "
|
|
4824
|
+
size: 107231360,
|
|
4825
|
+
sha256: "0d7611d0b86d38ec8f65dda8e8bee9c5e907c7bae381e9cfff9161b21e8087d0"
|
|
4826
4826
|
}
|
|
4827
4827
|
},
|
|
4828
4828
|
ghArtifact("darwin", "arm64", {
|
|
@@ -4876,26 +4876,26 @@ import {
|
|
|
4876
4876
|
symlink as symlink2,
|
|
4877
4877
|
utimes
|
|
4878
4878
|
} from "fs/promises";
|
|
4879
|
-
import
|
|
4879
|
+
import path15 from "path";
|
|
4880
4880
|
import { pipeline } from "stream/promises";
|
|
4881
4881
|
import { createGunzip } from "zlib";
|
|
4882
4882
|
function delay(milliseconds) {
|
|
4883
4883
|
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
4884
4884
|
}
|
|
4885
4885
|
function artifactDirectory(rootDir, artifact) {
|
|
4886
|
-
return
|
|
4886
|
+
return path15.join(rootDir, artifact.name, artifact.version, `${artifact.platform}-${artifact.architecture}`);
|
|
4887
4887
|
}
|
|
4888
4888
|
function artifactExecutablePath(rootDir, artifact) {
|
|
4889
|
-
return
|
|
4889
|
+
return path15.join(artifactDirectory(rootDir, artifact), artifact.executable.fileName);
|
|
4890
4890
|
}
|
|
4891
4891
|
function upstreamExecutablePath(rootDir, artifact) {
|
|
4892
|
-
return
|
|
4892
|
+
return path15.join(artifactDirectory(rootDir, artifact), `.upstream-${artifact.executable.fileName}`);
|
|
4893
4893
|
}
|
|
4894
4894
|
function artifactCompanions(artifact) {
|
|
4895
4895
|
return artifact.companions ?? [];
|
|
4896
4896
|
}
|
|
4897
4897
|
function companionPath(rootDir, artifact, companion) {
|
|
4898
|
-
return
|
|
4898
|
+
return path15.join(artifactDirectory(rootDir, artifact), companion.fileName);
|
|
4899
4899
|
}
|
|
4900
4900
|
function artifactArchiveBytes(artifact) {
|
|
4901
4901
|
return artifactCompanions(artifact).reduce((total, companion) => total + companion.archive.size, artifact.archive.size);
|
|
@@ -4919,7 +4919,7 @@ function assertValidArtifactMetadata(artifact) {
|
|
|
4919
4919
|
}
|
|
4920
4920
|
const paths = new Set;
|
|
4921
4921
|
for (const file of artifact.archive.bundleFiles) {
|
|
4922
|
-
const normalized =
|
|
4922
|
+
const normalized = path15.posix.normalize(file.path);
|
|
4923
4923
|
if (normalized !== file.path || normalized.startsWith("../") || normalized.startsWith("/") || normalized.includes("\\") || paths.has(normalized) || !Number.isSafeInteger(file.size) || file.size < 1 || !/^[a-f0-9]{64}$/.test(file.sha256)) {
|
|
4924
4924
|
throw new Error(`${artifact.name} manifest has an unsafe bundle file`);
|
|
4925
4925
|
}
|
|
@@ -4945,7 +4945,7 @@ function assertValidArtifactMetadata(artifact) {
|
|
|
4945
4945
|
}
|
|
4946
4946
|
const activationNames = new Set([artifact.name, artifact.executable.fileName]);
|
|
4947
4947
|
for (const alias of artifact.activationAliases ?? []) {
|
|
4948
|
-
if (!alias || alias.startsWith(".") || alias.includes("/") || alias.includes("\\") || alias !==
|
|
4948
|
+
if (!alias || alias.startsWith(".") || alias.includes("/") || alias.includes("\\") || alias !== path15.basename(alias) || activationNames.has(alias)) {
|
|
4949
4949
|
throw new Error(`${artifact.name} manifest has an unsafe or duplicate activation alias`);
|
|
4950
4950
|
}
|
|
4951
4951
|
activationNames.add(alias);
|
|
@@ -4955,7 +4955,7 @@ function assertValidArtifactMetadata(artifact) {
|
|
|
4955
4955
|
if (companion.archive.format !== "zip" && companion.archive.format !== "tar.gz") {
|
|
4956
4956
|
throw new Error(`${artifact.name} companion has an unsupported archive format`);
|
|
4957
4957
|
}
|
|
4958
|
-
if (!companion.fileName || companion.fileName.startsWith(".") || companion.fileName.includes("/") || companion.fileName.includes("\\") || companion.fileName !==
|
|
4958
|
+
if (!companion.fileName || companion.fileName.startsWith(".") || companion.fileName.includes("/") || companion.fileName.includes("\\") || companion.fileName !== path15.basename(companion.fileName)) {
|
|
4959
4959
|
throw new Error(`${artifact.name} companion has an unsafe file name`);
|
|
4960
4960
|
}
|
|
4961
4961
|
if (companionNames.has(companion.fileName)) {
|
|
@@ -5021,7 +5021,7 @@ async function isValidExecutable(rootDir, artifact) {
|
|
|
5021
5021
|
if (!await isValidUpstreamExecutable(rootDir, artifact))
|
|
5022
5022
|
return false;
|
|
5023
5023
|
for (const bundled of artifact.archive.bundleFiles ?? []) {
|
|
5024
|
-
if (!await isValidFile(
|
|
5024
|
+
if (!await isValidFile(path15.join(artifactDirectory(rootDir, artifact), ...bundled.path.split("/")), bundled)) {
|
|
5025
5025
|
return false;
|
|
5026
5026
|
}
|
|
5027
5027
|
}
|
|
@@ -5038,7 +5038,7 @@ async function isValidExecutable(rootDir, artifact) {
|
|
|
5038
5038
|
if ((file.mode & 511) !== 320)
|
|
5039
5039
|
await chmod(executablePath, 320);
|
|
5040
5040
|
for (const bundled of artifact.archive.bundleFiles ?? []) {
|
|
5041
|
-
if (!await isValidFile(
|
|
5041
|
+
if (!await isValidFile(path15.join(artifactDirectory(rootDir, artifact), ...bundled.path.split("/")), bundled)) {
|
|
5042
5042
|
return false;
|
|
5043
5043
|
}
|
|
5044
5044
|
}
|
|
@@ -5059,7 +5059,7 @@ async function bundleTreeEntries(directory, artifact) {
|
|
|
5059
5059
|
const visit = async (currentDirectory, prefix = "") => {
|
|
5060
5060
|
for (const entry of await readdir2(currentDirectory, { withFileTypes: true })) {
|
|
5061
5061
|
const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
5062
|
-
const filePath =
|
|
5062
|
+
const filePath = path15.join(currentDirectory, entry.name);
|
|
5063
5063
|
if (entry.isDirectory()) {
|
|
5064
5064
|
await visit(filePath, relativePath);
|
|
5065
5065
|
} else if (entry.isFile() && !entry.isSymbolicLink()) {
|
|
@@ -5174,7 +5174,7 @@ async function initializeInstallLock(lockPath, owner, openLockFile) {
|
|
|
5174
5174
|
}
|
|
5175
5175
|
}
|
|
5176
5176
|
async function acquireInstallLock(rootDir, onProgress, timings, openLockFile, ownerProcessExists) {
|
|
5177
|
-
const lockPath =
|
|
5177
|
+
const lockPath = path15.join(rootDir, INSTALL_LOCK);
|
|
5178
5178
|
const startedAt = Date.now();
|
|
5179
5179
|
let announcedWait = false;
|
|
5180
5180
|
while (Date.now() - startedAt < timings.lockWaitTimeoutMs) {
|
|
@@ -5355,8 +5355,8 @@ async function extractTarGzipBundle(archivePath, destinationDirectory, label, ar
|
|
|
5355
5355
|
stream.resume();
|
|
5356
5356
|
return;
|
|
5357
5357
|
}
|
|
5358
|
-
const normalized =
|
|
5359
|
-
if (normalized.startsWith("../") || normalized.startsWith("/") || normalized.includes("\\") ||
|
|
5358
|
+
const normalized = path15.posix.normalize(relative);
|
|
5359
|
+
if (normalized.startsWith("../") || normalized.startsWith("/") || normalized.includes("\\") || path15.isAbsolute(normalized)) {
|
|
5360
5360
|
extract2.destroy(new Error(`Unsafe path in ${label} bundle`));
|
|
5361
5361
|
stream.resume();
|
|
5362
5362
|
return;
|
|
@@ -5368,7 +5368,7 @@ async function extractTarGzipBundle(archivePath, destinationDirectory, label, ar
|
|
|
5368
5368
|
stream.resume();
|
|
5369
5369
|
return;
|
|
5370
5370
|
}
|
|
5371
|
-
const destination =
|
|
5371
|
+
const destination = path15.join(destinationDirectory, ...normalized.split("/"));
|
|
5372
5372
|
if (header.type === "directory") {
|
|
5373
5373
|
stream.once("end", next);
|
|
5374
5374
|
stream.resume();
|
|
@@ -5386,7 +5386,7 @@ async function extractTarGzipBundle(archivePath, destinationDirectory, label, ar
|
|
|
5386
5386
|
}
|
|
5387
5387
|
if (header.name === archive.entryPath)
|
|
5388
5388
|
foundExecutable = true;
|
|
5389
|
-
mkdir3(
|
|
5389
|
+
mkdir3(path15.dirname(destination), { recursive: true, mode: 448 }).then(() => pipeline(stream, createWriteStream(destination, {
|
|
5390
5390
|
flags: "wx",
|
|
5391
5391
|
mode: (header.mode ?? 0) & 73 ? 320 : 256
|
|
5392
5392
|
}))).then(() => next(), (error) => extract2.destroy(error instanceof Error ? error : new Error(String(error))));
|
|
@@ -5548,7 +5548,7 @@ async function repairInvalidMacSignature(executablePath, artifact, timeoutMs, sp
|
|
|
5548
5548
|
await runCodesign(["--sign", "-", "--force", executablePath], `${artifact.name} could not be ad-hoc signed after source verification`, timeoutMs, spawnProcess);
|
|
5549
5549
|
}
|
|
5550
5550
|
async function prepareRepairableExecutable(sourcePath, executablePath, artifact, skipExecutableProbeForTests, processTimeoutMs, spawnProcess) {
|
|
5551
|
-
const temporaryPath =
|
|
5551
|
+
const temporaryPath = path15.join(path15.dirname(executablePath), `.repair-${artifact.executable.fileName}-${randomUUID4()}.tmp`);
|
|
5552
5552
|
try {
|
|
5553
5553
|
await copyFile2(sourcePath, temporaryPath);
|
|
5554
5554
|
await chmod(temporaryPath, 448);
|
|
@@ -5580,8 +5580,8 @@ async function refreshRepairableArtifact(rootDir, artifact, skipExecutableProbeF
|
|
|
5580
5580
|
async function stageCompanions(stagingDirectory, artifact, companions, fetchImpl, onBytes, startBytes, allowInsecureDownloadsForTests, skipExecutableProbeForTests, timings, spawnProcess) {
|
|
5581
5581
|
let downloadedBytes = startBytes;
|
|
5582
5582
|
for (const companion of companions) {
|
|
5583
|
-
const companionArchivePath =
|
|
5584
|
-
const companionFilePath =
|
|
5583
|
+
const companionArchivePath = path15.join(stagingDirectory, `.archive-${companion.fileName}.${archiveExtension(companion.archive)}`);
|
|
5584
|
+
const companionFilePath = path15.join(stagingDirectory, companion.fileName);
|
|
5585
5585
|
const precedingBytes = downloadedBytes;
|
|
5586
5586
|
await downloadArchive(companion.fileName, companion.archive, companionArchivePath, fetchImpl, (received) => onBytes(precedingBytes + received), allowInsecureDownloadsForTests, timings.downloadTimeoutMs);
|
|
5587
5587
|
downloadedBytes += companion.archive.size;
|
|
@@ -5606,28 +5606,28 @@ async function stageCompanions(stagingDirectory, artifact, companions, fetchImpl
|
|
|
5606
5606
|
}
|
|
5607
5607
|
}
|
|
5608
5608
|
async function repairArtifactCompanions(rootDir, artifact, companions, fetchImpl, onBytes, onVerify, allowInsecureDownloadsForTests, skipExecutableProbeForTests, timings, spawnProcess) {
|
|
5609
|
-
const stagingDirectory = await mkdtemp2(
|
|
5609
|
+
const stagingDirectory = await mkdtemp2(path15.join(rootDir, `.staging-${artifact.name}-`));
|
|
5610
5610
|
try {
|
|
5611
5611
|
await stageCompanions(stagingDirectory, artifact, companions, fetchImpl, onBytes, 0, allowInsecureDownloadsForTests, skipExecutableProbeForTests, timings, spawnProcess);
|
|
5612
5612
|
onVerify();
|
|
5613
5613
|
const destinationDirectory = artifactDirectory(rootDir, artifact);
|
|
5614
5614
|
for (const companion of companions) {
|
|
5615
|
-
await rename2(
|
|
5615
|
+
await rename2(path15.join(stagingDirectory, companion.fileName), path15.join(destinationDirectory, companion.fileName));
|
|
5616
5616
|
}
|
|
5617
5617
|
} finally {
|
|
5618
5618
|
await rm3(stagingDirectory, { recursive: true, force: true });
|
|
5619
5619
|
}
|
|
5620
5620
|
}
|
|
5621
5621
|
async function installArtifact(rootDir, artifact, fetchImpl, onBytes, onVerify, allowInsecureDownloadsForTests, skipExecutableProbeForTests, timings, spawnProcess) {
|
|
5622
|
-
const stagingDirectory = await mkdtemp2(
|
|
5623
|
-
const archivePath =
|
|
5624
|
-
const executablePath =
|
|
5625
|
-
const extractedPath = artifact.executable.repairInvalidMacSignature ?
|
|
5622
|
+
const stagingDirectory = await mkdtemp2(path15.join(rootDir, `.staging-${artifact.name}-`));
|
|
5623
|
+
const archivePath = path15.join(stagingDirectory, `archive.${archiveExtension(artifact.archive)}`);
|
|
5624
|
+
const executablePath = path15.join(stagingDirectory, artifact.executable.fileName);
|
|
5625
|
+
const extractedPath = artifact.executable.repairInvalidMacSignature ? path15.join(stagingDirectory, `.upstream-${artifact.executable.fileName}`) : executablePath;
|
|
5626
5626
|
try {
|
|
5627
5627
|
await downloadArchive(artifact.name, artifact.archive, archivePath, fetchImpl, onBytes, allowInsecureDownloadsForTests, timings.downloadTimeoutMs);
|
|
5628
5628
|
if (artifact.archive.bundleRoot) {
|
|
5629
5629
|
await extractTarGzipBundle(archivePath, stagingDirectory, artifact.name, artifact.archive);
|
|
5630
|
-
const bundledExecutable =
|
|
5630
|
+
const bundledExecutable = path15.join(stagingDirectory, ...artifact.archive.entryPath.slice(artifact.archive.bundleRoot.length).split("/"));
|
|
5631
5631
|
if (bundledExecutable !== extractedPath) {
|
|
5632
5632
|
await rename2(bundledExecutable, extractedPath);
|
|
5633
5633
|
}
|
|
@@ -5678,7 +5678,7 @@ async function installArtifact(rootDir, artifact, fetchImpl, onBytes, onVerify,
|
|
|
5678
5678
|
await stageCompanions(stagingDirectory, artifact, artifactCompanions(artifact), fetchImpl, onBytes, artifact.archive.size, allowInsecureDownloadsForTests, skipExecutableProbeForTests, timings, spawnProcess);
|
|
5679
5679
|
onVerify();
|
|
5680
5680
|
const destinationDirectory = artifactDirectory(rootDir, artifact);
|
|
5681
|
-
await mkdir3(
|
|
5681
|
+
await mkdir3(path15.dirname(destinationDirectory), { recursive: true, mode: 448 });
|
|
5682
5682
|
await rm3(destinationDirectory, { recursive: true, force: true });
|
|
5683
5683
|
await rename2(stagingDirectory, destinationDirectory);
|
|
5684
5684
|
await chmod(destinationDirectory, 448);
|
|
@@ -5690,16 +5690,16 @@ async function installArtifact(rootDir, artifact, fetchImpl, onBytes, onVerify,
|
|
|
5690
5690
|
}
|
|
5691
5691
|
async function cleanStagingDirectories(rootDir) {
|
|
5692
5692
|
const entries = await readdir2(rootDir, { withFileTypes: true });
|
|
5693
|
-
await Promise.all(entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(".staging-")).map((entry) => rm3(
|
|
5693
|
+
await Promise.all(entries.filter((entry) => entry.isDirectory() && entry.name.startsWith(".staging-")).map((entry) => rm3(path15.join(rootDir, entry.name), { recursive: true, force: true })));
|
|
5694
5694
|
}
|
|
5695
5695
|
async function touchArtifactDirectory(rootDir, artifact) {
|
|
5696
5696
|
const now = new Date;
|
|
5697
|
-
await utimes(
|
|
5697
|
+
await utimes(path15.dirname(artifactDirectory(rootDir, artifact)), now, now).catch(() => {
|
|
5698
5698
|
return;
|
|
5699
5699
|
});
|
|
5700
5700
|
}
|
|
5701
5701
|
function versionLeaseDirectory(rootDir, name, version) {
|
|
5702
|
-
return
|
|
5702
|
+
return path15.join(rootDir, LEASE_DIRECTORY, name, version);
|
|
5703
5703
|
}
|
|
5704
5704
|
async function acquireVersionLease(rootDir, artifact, openLeaseFile) {
|
|
5705
5705
|
const leaseKey = `${rootDir}\x00${artifact.name}\x00${artifact.version}`;
|
|
@@ -5714,7 +5714,7 @@ async function acquireVersionLease(rootDir, artifact, openLeaseFile) {
|
|
|
5714
5714
|
};
|
|
5715
5715
|
const directory = versionLeaseDirectory(rootDir, artifact.name, artifact.version);
|
|
5716
5716
|
await mkdir3(directory, { recursive: true, mode: 448 });
|
|
5717
|
-
const leasePath =
|
|
5717
|
+
const leasePath = path15.join(directory, `${owner.pid}-${owner.token}.json`);
|
|
5718
5718
|
const handle = await openLeaseFile(leasePath, "wx", 384);
|
|
5719
5719
|
try {
|
|
5720
5720
|
await handle.writeFile(JSON.stringify(owner), "utf8");
|
|
@@ -5735,7 +5735,7 @@ async function versionHasLiveLease(rootDir, name, version, ownerProcessExists) {
|
|
|
5735
5735
|
const entries = await readdir2(directory, { withFileTypes: true }).catch(() => []);
|
|
5736
5736
|
let live = false;
|
|
5737
5737
|
await Promise.all(entries.filter((entry) => entry.isFile()).map(async (entry) => {
|
|
5738
|
-
const leasePath =
|
|
5738
|
+
const leasePath = path15.join(directory, entry.name);
|
|
5739
5739
|
try {
|
|
5740
5740
|
const parsed = JSON.parse(await readFile2(leasePath, "utf8"));
|
|
5741
5741
|
if (typeof parsed.token === "string" && typeof parsed.pid === "number" && typeof parsed.createdAt === "string" && ownerProcessExists(parsed.pid)) {
|
|
@@ -5758,11 +5758,11 @@ async function pruneSupersededVersions(rootDir, artifacts, retainSupersededMs, o
|
|
|
5758
5758
|
}
|
|
5759
5759
|
const staleBefore = Date.now() - retainSupersededMs;
|
|
5760
5760
|
await Promise.all(Array.from(keepByName, async ([name, keep]) => {
|
|
5761
|
-
const toolDir =
|
|
5761
|
+
const toolDir = path15.join(rootDir, name);
|
|
5762
5762
|
try {
|
|
5763
5763
|
const entries = await readdir2(toolDir, { withFileTypes: true });
|
|
5764
5764
|
await Promise.all(entries.filter((entry) => entry.isDirectory() && !keep.has(entry.name)).map(async (entry) => {
|
|
5765
|
-
const versionDir =
|
|
5765
|
+
const versionDir = path15.join(toolDir, entry.name);
|
|
5766
5766
|
try {
|
|
5767
5767
|
if ((await stat2(versionDir)).mtimeMs > staleBefore)
|
|
5768
5768
|
return;
|
|
@@ -5803,8 +5803,8 @@ function activationSetId(artifacts) {
|
|
|
5803
5803
|
return createHash4("sha256").update(JSON.stringify(identity)).digest("hex");
|
|
5804
5804
|
}
|
|
5805
5805
|
async function activateExecutables(rootDir, artifacts) {
|
|
5806
|
-
const binRoot =
|
|
5807
|
-
const binDir =
|
|
5806
|
+
const binRoot = path15.join(rootDir, "bin");
|
|
5807
|
+
const binDir = path15.join(binRoot, activationSetId(artifacts));
|
|
5808
5808
|
await mkdir3(binRoot, { recursive: true, mode: 448 });
|
|
5809
5809
|
const binRootEntry = await lstat(binRoot);
|
|
5810
5810
|
if (!binRootEntry.isDirectory() || binRootEntry.isSymbolicLink()) {
|
|
@@ -5819,8 +5819,8 @@ async function activateExecutables(rootDir, artifacts) {
|
|
|
5819
5819
|
await chmod(binDir, 448);
|
|
5820
5820
|
const executables = {};
|
|
5821
5821
|
const activate = async (linkName, target) => {
|
|
5822
|
-
const activePath =
|
|
5823
|
-
const temporaryLink =
|
|
5822
|
+
const activePath = path15.join(binDir, linkName);
|
|
5823
|
+
const temporaryLink = path15.join(binDir, `.${linkName}-${randomUUID4()}.tmp`);
|
|
5824
5824
|
const existingTarget = await readlink(activePath).catch(() => null);
|
|
5825
5825
|
if (existingTarget !== target) {
|
|
5826
5826
|
await symlink2(target, temporaryLink, "file");
|
|
@@ -5868,7 +5868,7 @@ async function ensurePinnedToolchains(options2) {
|
|
|
5868
5868
|
const timings = { ...DEFAULT_TIMINGS, ...options2.timingsForTests };
|
|
5869
5869
|
const spawnProcess = options2.spawnForTests ?? spawn;
|
|
5870
5870
|
const ownerProcessExists = options2.processExistsForTests ?? ((pid) => processExists(pid, options2.processKillForTests));
|
|
5871
|
-
const rootDir =
|
|
5871
|
+
const rootDir = path15.join(options2.dataDir, TOOLCHAIN_DIRECTORY);
|
|
5872
5872
|
const totalTools = artifacts.length;
|
|
5873
5873
|
const toolFractions = new Map(artifacts.map((artifact) => [artifact.name, 0]));
|
|
5874
5874
|
const progress = (value) => {
|
|
@@ -6033,7 +6033,7 @@ var init_agent_platforms = __esm(() => {
|
|
|
6033
6033
|
|
|
6034
6034
|
// ../toolchain/src/platform-selection.ts
|
|
6035
6035
|
import { promises as fs7 } from "fs";
|
|
6036
|
-
import
|
|
6036
|
+
import path16 from "path";
|
|
6037
6037
|
async function readJsonFile(filePath) {
|
|
6038
6038
|
try {
|
|
6039
6039
|
return JSON.parse(await fs7.readFile(filePath, "utf8"));
|
|
@@ -6042,7 +6042,7 @@ async function readJsonFile(filePath) {
|
|
|
6042
6042
|
}
|
|
6043
6043
|
}
|
|
6044
6044
|
async function loadAgentPlatformSelection(dataDir) {
|
|
6045
|
-
const config = await readJsonFile(
|
|
6045
|
+
const config = await readJsonFile(path16.join(dataDir, AGENT_CONFIG_FILE));
|
|
6046
6046
|
if (config && typeof config === "object" && !Array.isArray(config)) {
|
|
6047
6047
|
const global2 = config.global;
|
|
6048
6048
|
if (global2 && typeof global2 === "object" && !Array.isArray(global2)) {
|
|
@@ -6058,7 +6058,7 @@ async function loadAgentPlatformSelection(dataDir) {
|
|
|
6058
6058
|
needsFirstRunChoice: false
|
|
6059
6059
|
};
|
|
6060
6060
|
}
|
|
6061
|
-
const sidecar = await readJsonFile(
|
|
6061
|
+
const sidecar = await readJsonFile(path16.join(dataDir, AGENT_PLATFORM_SELECTION_FILE));
|
|
6062
6062
|
if (sidecar && typeof sidecar === "object" && !Array.isArray(sidecar)) {
|
|
6063
6063
|
const enabled = normalizeAgentPlatforms(sidecar.enabled, []);
|
|
6064
6064
|
if (enabled.length > 0)
|
|
@@ -6074,7 +6074,7 @@ var init_platform_selection = __esm(() => {
|
|
|
6074
6074
|
// ../toolchain/src/install.ts
|
|
6075
6075
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
6076
6076
|
import { lstat as lstat2, mkdir as mkdir4, readdir as readdir3, readlink as readlink2, rename as rename3, rm as rm4, symlink as symlink3 } from "fs/promises";
|
|
6077
|
-
import
|
|
6077
|
+
import path17 from "path";
|
|
6078
6078
|
async function resolveToolchainSelection(options2) {
|
|
6079
6079
|
const known = Object.keys(PINNED_TOOL_VERSIONS);
|
|
6080
6080
|
const withSupportTools = (chosen) => known.filter((name) => chosen.has(name) || isSupportToolName(name));
|
|
@@ -6133,16 +6133,16 @@ async function installPinnedToolchains(options2) {
|
|
|
6133
6133
|
};
|
|
6134
6134
|
}
|
|
6135
6135
|
async function toolsInCurrent(rootDir) {
|
|
6136
|
-
const entries = await readdir3(
|
|
6136
|
+
const entries = await readdir3(path17.join(rootDir, "bin", CURRENT_TOOLCHAIN_LINK)).catch(() => []);
|
|
6137
6137
|
return Object.keys(PINNED_TOOL_VERSIONS).filter((tool) => entries.includes(tool));
|
|
6138
6138
|
}
|
|
6139
6139
|
async function pointCurrentAt(rootDir, binDir) {
|
|
6140
|
-
const binRoot =
|
|
6141
|
-
if (
|
|
6140
|
+
const binRoot = path17.join(rootDir, "bin");
|
|
6141
|
+
if (path17.dirname(binDir) !== binRoot) {
|
|
6142
6142
|
throw new Error(`Activation directory ${binDir} is not directly inside ${binRoot}`);
|
|
6143
6143
|
}
|
|
6144
|
-
const link =
|
|
6145
|
-
const target =
|
|
6144
|
+
const link = path17.join(binRoot, CURRENT_TOOLCHAIN_LINK);
|
|
6145
|
+
const target = path17.basename(binDir);
|
|
6146
6146
|
await mkdir4(binRoot, { recursive: true, mode: 448 });
|
|
6147
6147
|
const existing = await lstat2(link).catch(() => null);
|
|
6148
6148
|
if (existing && !existing.isSymbolicLink()) {
|
|
@@ -6150,7 +6150,7 @@ async function pointCurrentAt(rootDir, binDir) {
|
|
|
6150
6150
|
}
|
|
6151
6151
|
if (existing && await readlink2(link) === target)
|
|
6152
6152
|
return link;
|
|
6153
|
-
const temporary =
|
|
6153
|
+
const temporary = path17.join(binRoot, `.${CURRENT_TOOLCHAIN_LINK}-${randomUUID5()}.tmp`);
|
|
6154
6154
|
await symlink3(target, temporary, "dir");
|
|
6155
6155
|
try {
|
|
6156
6156
|
await rename3(temporary, link);
|
|
@@ -7444,7 +7444,7 @@ import path4 from "path";
|
|
|
7444
7444
|
// ../../apps/backend/package.json
|
|
7445
7445
|
var package_default = {
|
|
7446
7446
|
name: "@orkestrator/backend",
|
|
7447
|
-
version: "2.
|
|
7447
|
+
version: "2.28.0-beta",
|
|
7448
7448
|
private: true,
|
|
7449
7449
|
type: "module",
|
|
7450
7450
|
exports: {
|
|
@@ -7464,7 +7464,7 @@ var package_default = {
|
|
|
7464
7464
|
dependencies: {
|
|
7465
7465
|
"@modelcontextprotocol/node": "2.1.1",
|
|
7466
7466
|
"@modelcontextprotocol/server": "2.3.1",
|
|
7467
|
-
"@opencode-ai/sdk": "1.19.
|
|
7467
|
+
"@opencode-ai/sdk": "1.19.4",
|
|
7468
7468
|
"@orkestrator/protocol": "workspace:*",
|
|
7469
7469
|
"@orkestrator/toolchain": "workspace:*",
|
|
7470
7470
|
"@xterm/addon-serialize": "0.14.0",
|
|
@@ -7508,6 +7508,7 @@ var DEFAULT_ALLOWED_DOMAINS = Object.freeze([
|
|
|
7508
7508
|
var AGENT_NETWORK_DOMAINS_BY_PLATFORM = Object.freeze({
|
|
7509
7509
|
codex: Object.freeze(["chatgpt.com", "auth.openai.com"]),
|
|
7510
7510
|
cursor: Object.freeze([
|
|
7511
|
+
"api.cursor.com",
|
|
7511
7512
|
"api2.cursor.sh",
|
|
7512
7513
|
"api3.cursor.sh",
|
|
7513
7514
|
"api4.cursor.sh",
|
|
@@ -8257,6 +8258,10 @@ function defaultSleep(ms, signal) {
|
|
|
8257
8258
|
function signalName(signal) {
|
|
8258
8259
|
return signal?.reason === "SIGTERM" ? "SIGTERM" : "SIGINT";
|
|
8259
8260
|
}
|
|
8261
|
+
function throwIfInterrupted(signal) {
|
|
8262
|
+
if (signal?.aborted)
|
|
8263
|
+
throw new CliError("observation-interrupted", "Interrupted");
|
|
8264
|
+
}
|
|
8260
8265
|
async function observe(check, options2) {
|
|
8261
8266
|
if (options2.timeoutMs > PUBLIC_API_LIMITS.waitMaxMs) {
|
|
8262
8267
|
throw new CliError("invalid-input", "--timeout may be at most 24h");
|
|
@@ -10859,18 +10864,185 @@ var hostCommands = [
|
|
|
10859
10864
|
|
|
10860
10865
|
// src/client/commands/service.ts
|
|
10861
10866
|
import { spawnSync } from "child_process";
|
|
10862
|
-
import { existsSync as
|
|
10867
|
+
import { existsSync as existsSync5 } from "fs";
|
|
10863
10868
|
import { mkdir as mkdir2, rm as rm2, writeFile as writeFile2 } from "fs/promises";
|
|
10864
|
-
import
|
|
10869
|
+
import path14 from "path";
|
|
10870
|
+
|
|
10871
|
+
// src/client/service-connection.ts
|
|
10872
|
+
import path11 from "path";
|
|
10873
|
+
async function currentDescriptorGeneration(dataDir) {
|
|
10874
|
+
try {
|
|
10875
|
+
return (await readDescriptor(path11.join(dataDir, BACKEND_INSTANCE_DESCRIPTOR_FILE))).generation;
|
|
10876
|
+
} catch {
|
|
10877
|
+
return null;
|
|
10878
|
+
}
|
|
10879
|
+
}
|
|
10880
|
+
async function awaitServiceConnection(dataDir, previousGeneration, options2) {
|
|
10881
|
+
const file = path11.join(dataDir, BACKEND_INSTANCE_DESCRIPTOR_FILE);
|
|
10882
|
+
try {
|
|
10883
|
+
const descriptor = await observe(async () => {
|
|
10884
|
+
try {
|
|
10885
|
+
const value = await readDescriptor(file);
|
|
10886
|
+
const fresh = value.generation !== previousGeneration && path11.resolve(value.dataDir) === path11.resolve(dataDir) && processIsAlive(value.pid);
|
|
10887
|
+
return fresh ? { done: true, value } : { done: false };
|
|
10888
|
+
} catch {
|
|
10889
|
+
return { done: false };
|
|
10890
|
+
}
|
|
10891
|
+
}, options2);
|
|
10892
|
+
const connection = {
|
|
10893
|
+
browserUrl: descriptor.browserUrl ?? (isLoopbackHost(new URL(descriptor.url).hostname) || descriptor.endpoints?.some((endpoint) => endpoint.url === descriptor.url) ? null : descriptor.url),
|
|
10894
|
+
authFile: descriptor.authFile,
|
|
10895
|
+
token: null
|
|
10896
|
+
};
|
|
10897
|
+
try {
|
|
10898
|
+
connection.token = await readTokenFile(descriptor.authFile, true);
|
|
10899
|
+
} catch (error) {
|
|
10900
|
+
if (!(error instanceof CliError))
|
|
10901
|
+
throw error;
|
|
10902
|
+
connection.credentialError = error.message;
|
|
10903
|
+
}
|
|
10904
|
+
throwIfInterrupted(options2.signal);
|
|
10905
|
+
return connection;
|
|
10906
|
+
} catch (error) {
|
|
10907
|
+
if (error instanceof ObservationStopped) {
|
|
10908
|
+
if (error.reason === "deadline")
|
|
10909
|
+
return null;
|
|
10910
|
+
throw new CliError("observation-interrupted", "Stopped waiting for the backend to start");
|
|
10911
|
+
}
|
|
10912
|
+
throw error;
|
|
10913
|
+
}
|
|
10914
|
+
}
|
|
10915
|
+
|
|
10916
|
+
// src/client/service-setup.ts
|
|
10917
|
+
import { existsSync as existsSync3 } from "fs";
|
|
10918
|
+
import os5 from "os";
|
|
10919
|
+
var HOSTED_WEB_ORIGINS = "https://orkestrator.dev,https://www.orkestrator.dev";
|
|
10920
|
+
var SSH_LOOPBACK_PORT = "34125";
|
|
10921
|
+
var MACOS_TAILSCALE_APP_CLI = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
|
|
10922
|
+
var systemSetupProbe = {
|
|
10923
|
+
hasTailscaleAddress: () => Object.values(os5.networkInterfaces()).some((entries) => (entries ?? []).some((entry) => entry.family === "IPv4" && isTailscaleIPv4(entry.address))),
|
|
10924
|
+
findTailscaleCli: () => {
|
|
10925
|
+
if (process.platform === "darwin" && existsSync3(MACOS_TAILSCALE_APP_CLI)) {
|
|
10926
|
+
return MACOS_TAILSCALE_APP_CLI;
|
|
10927
|
+
}
|
|
10928
|
+
return typeof Bun === "undefined" ? null : Bun.which("tailscale");
|
|
10929
|
+
}
|
|
10930
|
+
};
|
|
10931
|
+
function isTailscaleIPv4(address) {
|
|
10932
|
+
const [first, second] = address.split(".").map(Number);
|
|
10933
|
+
return first === 100 && second !== undefined && second >= 64 && second <= 127;
|
|
10934
|
+
}
|
|
10935
|
+
function cancelled() {
|
|
10936
|
+
return new CliError("invalid-input", "Setup cancelled; nothing was installed");
|
|
10937
|
+
}
|
|
10938
|
+
async function ask(io, prompt) {
|
|
10939
|
+
const answer = await io.question(prompt);
|
|
10940
|
+
if (answer === null)
|
|
10941
|
+
throw cancelled();
|
|
10942
|
+
return answer.trim();
|
|
10943
|
+
}
|
|
10944
|
+
async function choose(io, title, choices) {
|
|
10945
|
+
io.stderr(`${title}
|
|
10946
|
+
`);
|
|
10947
|
+
choices.forEach((choice, index) => io.stderr(` ${index + 1}) ${choice.label}
|
|
10948
|
+
`));
|
|
10949
|
+
for (;; ) {
|
|
10950
|
+
const answer = await ask(io, `Choose 1-${choices.length} [1]: `);
|
|
10951
|
+
if (answer === "")
|
|
10952
|
+
return choices[0].value;
|
|
10953
|
+
const picked = choices[Number(answer) - 1];
|
|
10954
|
+
if (/^\d+$/.test(answer) && picked)
|
|
10955
|
+
return picked.value;
|
|
10956
|
+
io.stderr(`Enter a number from 1 to ${choices.length}.
|
|
10957
|
+
`);
|
|
10958
|
+
}
|
|
10959
|
+
}
|
|
10960
|
+
async function confirm(io, prompt, fallback) {
|
|
10961
|
+
for (;; ) {
|
|
10962
|
+
const answer = (await ask(io, `${prompt} ${fallback ? "[Y/n]" : "[y/N]"} `)).toLowerCase();
|
|
10963
|
+
if (answer === "")
|
|
10964
|
+
return fallback;
|
|
10965
|
+
if (answer === "y" || answer === "yes")
|
|
10966
|
+
return true;
|
|
10967
|
+
if (answer === "n" || answer === "no")
|
|
10968
|
+
return false;
|
|
10969
|
+
io.stderr(`Answer y or n.
|
|
10970
|
+
`);
|
|
10971
|
+
}
|
|
10972
|
+
}
|
|
10973
|
+
function quote(arg) {
|
|
10974
|
+
return /^[\w@%+=:,./-]+$/.test(arg) ? arg : `'${arg.replaceAll("'", `'\\''`)}'`;
|
|
10975
|
+
}
|
|
10976
|
+
async function askServeArguments(io, options2) {
|
|
10977
|
+
const source = io;
|
|
10978
|
+
io = {
|
|
10979
|
+
...source,
|
|
10980
|
+
question: async (prompt) => {
|
|
10981
|
+
throwIfInterrupted(options2.signal);
|
|
10982
|
+
const answer = await source.question(prompt, options2.signal);
|
|
10983
|
+
throwIfInterrupted(options2.signal);
|
|
10984
|
+
return answer;
|
|
10985
|
+
}
|
|
10986
|
+
};
|
|
10987
|
+
throwIfInterrupted(options2.signal);
|
|
10988
|
+
const probe = options2.probe ?? systemSetupProbe;
|
|
10989
|
+
io.stderr(`Set up the Orkestrator backend service.
|
|
10990
|
+
|
|
10991
|
+
`);
|
|
10992
|
+
const access = await choose(io, "How will you connect to this machine?", [
|
|
10993
|
+
{
|
|
10994
|
+
value: "serve",
|
|
10995
|
+
label: "Tailscale with HTTPS (Tailscale Serve): the desktop app, the CLI and orkestrator.dev"
|
|
10996
|
+
},
|
|
10997
|
+
{ value: "tailnet", label: "Tailscale address over HTTP: the desktop app and the CLI" },
|
|
10998
|
+
{ value: "ssh", label: "SSH only: the desktop app through an SSH tunnel, no Tailscale" }
|
|
10999
|
+
]);
|
|
11000
|
+
const args = [];
|
|
11001
|
+
if (access === "ssh")
|
|
11002
|
+
args.push("--host", "127.0.0.1", "--allow-non-tailscale-bind");
|
|
11003
|
+
if (access !== "ssh" && !probe.hasTailscaleAddress()) {
|
|
11004
|
+
io.stderr(`
|
|
11005
|
+
This machine has no Tailscale address yet. Connect Tailscale before the service starts, or it will not serve.
|
|
11006
|
+
`);
|
|
11007
|
+
}
|
|
11008
|
+
if (access === "serve") {
|
|
11009
|
+
args.push("--tailscale-serve");
|
|
11010
|
+
if (!probe.findTailscaleCli()) {
|
|
11011
|
+
io.stderr(`
|
|
11012
|
+
The Tailscale CLI was not found, and Tailscale Serve needs it.
|
|
11013
|
+
`);
|
|
11014
|
+
const cli = await ask(io, "Path to the tailscale executable (empty to keep `tailscale`): ");
|
|
11015
|
+
if (cli !== "")
|
|
11016
|
+
args.push("--tailscale-bin", cli);
|
|
11017
|
+
}
|
|
11018
|
+
if (await confirm(io, `
|
|
11019
|
+
Allow the hosted web client at orkestrator.dev?`, true)) {
|
|
11020
|
+
args.push("--allowed-origins", HOSTED_WEB_ORIGINS);
|
|
11021
|
+
}
|
|
11022
|
+
}
|
|
11023
|
+
const ssh = access === "ssh" || await confirm(io, `
|
|
11024
|
+
Also accept desktop connections over SSH (loopback port ${SSH_LOOPBACK_PORT})?`, false);
|
|
11025
|
+
if (ssh)
|
|
11026
|
+
args.push("--loopback-client-port", SSH_LOOPBACK_PORT);
|
|
11027
|
+
const command = [...options2.installCommand, "--", ...args].map(quote).join(" ");
|
|
11028
|
+
io.stderr(`
|
|
11029
|
+
Equivalent command, for scripts:
|
|
11030
|
+
${command}
|
|
11031
|
+
|
|
11032
|
+
`);
|
|
11033
|
+
if (!await confirm(io, "Install with these settings?", true))
|
|
11034
|
+
throw cancelled();
|
|
11035
|
+
return args;
|
|
11036
|
+
}
|
|
10865
11037
|
|
|
10866
11038
|
// src/client/service-units.ts
|
|
10867
11039
|
import { createHash as createHash3 } from "crypto";
|
|
10868
|
-
import
|
|
10869
|
-
import
|
|
11040
|
+
import os6 from "os";
|
|
11041
|
+
import path12 from "path";
|
|
10870
11042
|
function suffix(dataDir, defaultDataDir) {
|
|
10871
|
-
if (
|
|
11043
|
+
if (path12.resolve(dataDir) === path12.resolve(defaultDataDir))
|
|
10872
11044
|
return "";
|
|
10873
|
-
return `-${createHash3("sha256").update(
|
|
11045
|
+
return `-${createHash3("sha256").update(path12.resolve(dataDir)).digest("hex").slice(0, 8)}`;
|
|
10874
11046
|
}
|
|
10875
11047
|
function xml(text) {
|
|
10876
11048
|
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
@@ -10879,7 +11051,7 @@ function systemdWord(text) {
|
|
|
10879
11051
|
return `"${text.replaceAll("\\", "\\\\").replaceAll('"', "\\\"").replaceAll("%", "%%")}"`;
|
|
10880
11052
|
}
|
|
10881
11053
|
function serviceUnit(options2) {
|
|
10882
|
-
const home = options2.home ??
|
|
11054
|
+
const home = options2.home ?? os6.homedir();
|
|
10883
11055
|
const tag = suffix(options2.dataDir, options2.defaultDataDir);
|
|
10884
11056
|
const pathValue = options2.env.PATH ?? "/usr/local/bin:/usr/bin:/bin";
|
|
10885
11057
|
if (options2.platform === "darwin") {
|
|
@@ -10889,7 +11061,7 @@ function serviceUnit(options2) {
|
|
|
10889
11061
|
return {
|
|
10890
11062
|
manager: "launchd",
|
|
10891
11063
|
name,
|
|
10892
|
-
file:
|
|
11064
|
+
file: path12.join(home, "Library", "LaunchAgents", `${name}.plist`),
|
|
10893
11065
|
contents: `<?xml version="1.0" encoding="UTF-8"?>
|
|
10894
11066
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
10895
11067
|
<plist version="1.0">
|
|
@@ -10923,11 +11095,11 @@ ${args}
|
|
|
10923
11095
|
};
|
|
10924
11096
|
}
|
|
10925
11097
|
const name = `orkestrator-backend${tag}.service`;
|
|
10926
|
-
const configHome = options2.env.XDG_CONFIG_HOME ??
|
|
11098
|
+
const configHome = options2.env.XDG_CONFIG_HOME ?? path12.join(home, ".config");
|
|
10927
11099
|
return {
|
|
10928
11100
|
manager: "systemd",
|
|
10929
11101
|
name,
|
|
10930
|
-
file:
|
|
11102
|
+
file: path12.join(configHome, "systemd", "user", name),
|
|
10931
11103
|
contents: `[Unit]
|
|
10932
11104
|
Description=Orkestrator backend (${options2.dataDir})
|
|
10933
11105
|
After=network-online.target
|
|
@@ -10980,9 +11152,26 @@ var DATA_DIR_OPTION = {
|
|
|
10980
11152
|
valueName: "DIR",
|
|
10981
11153
|
description: "Backend data directory. Defaults to ORKESTRATOR_DATA_DIR, then the platform default."
|
|
10982
11154
|
};
|
|
11155
|
+
var DEFAULT_READY_WAIT_MS = 3 * 60 * 1000;
|
|
10983
11156
|
var RESERVED_SERVE_FLAGS = new Set(["--data-dir", "--standalone-updater", "--desktop-updater"]);
|
|
10984
11157
|
function dataDirectory(context, parsed) {
|
|
10985
|
-
return
|
|
11158
|
+
return path14.resolve(stringOption(parsed.options, "data-dir") ?? context.io.env.ORKESTRATOR_DATA_DIR ?? defaultDataDir(process.platform, context.io.env));
|
|
11159
|
+
}
|
|
11160
|
+
function installCommandLine(parsed) {
|
|
11161
|
+
const line = ["bunx", "orkestrator", "service", "install"];
|
|
11162
|
+
for (const name of ["data-dir", "release", "timeout"]) {
|
|
11163
|
+
const value = parsed.options[name];
|
|
11164
|
+
if (typeof value === "string")
|
|
11165
|
+
line.push(`--${name}`, value);
|
|
11166
|
+
else if (typeof value === "number")
|
|
11167
|
+
line.push(`--${name}`, `${Math.ceil(value / 1000)}s`);
|
|
11168
|
+
}
|
|
11169
|
+
for (const name of ["skip-start", "dry-run"]) {
|
|
11170
|
+
if (parsed.options[name] === true)
|
|
11171
|
+
line.push(`--${name}`);
|
|
11172
|
+
}
|
|
11173
|
+
line.push("--yes");
|
|
11174
|
+
return line;
|
|
10986
11175
|
}
|
|
10987
11176
|
function unitFor(context, dataDir, bun) {
|
|
10988
11177
|
if (process.platform !== "darwin" && process.platform !== "linux") {
|
|
@@ -10999,7 +11188,7 @@ function unitFor(context, dataDir, bun) {
|
|
|
10999
11188
|
defaultDataDir: defaultDataDir(process.platform, context.io.env),
|
|
11000
11189
|
bun,
|
|
11001
11190
|
launcher: layout.launcher,
|
|
11002
|
-
logFile:
|
|
11191
|
+
logFile: path14.join(layout.logs, "service.log"),
|
|
11003
11192
|
env: context.io.env
|
|
11004
11193
|
})
|
|
11005
11194
|
};
|
|
@@ -11025,8 +11214,13 @@ var serviceCommands = [
|
|
|
11025
11214
|
"previous release when a new one fails to start twice.",
|
|
11026
11215
|
"",
|
|
11027
11216
|
"Arguments after `--` are passed to `orkestrator serve` (for example `--tailscale-serve`).",
|
|
11217
|
+
"With none, in a terminal, it asks how clients will connect (Tailscale Serve, the",
|
|
11218
|
+
"tailnet address or SSH) and prints the equivalent command; --yes skips the questions.",
|
|
11028
11219
|
"The Bun running this command is the Bun the service uses; reinstall to change it.",
|
|
11029
|
-
"On Linux, run `loginctl enable-linger $USER` so the service runs without a login."
|
|
11220
|
+
"On Linux, run `loginctl enable-linger $USER` so the service runs without a login.",
|
|
11221
|
+
"",
|
|
11222
|
+
"Once the service is running, the address it serves and its gateway token are printed.",
|
|
11223
|
+
"The token is shown only in this terminal: never in --output json or the service log."
|
|
11030
11224
|
].join(`
|
|
11031
11225
|
`),
|
|
11032
11226
|
positionals: [],
|
|
@@ -11047,11 +11241,23 @@ var serviceCommands = [
|
|
|
11047
11241
|
name: "dry-run",
|
|
11048
11242
|
kind: "boolean",
|
|
11049
11243
|
description: "Show what would be written without installing anything."
|
|
11244
|
+
},
|
|
11245
|
+
{
|
|
11246
|
+
name: "yes",
|
|
11247
|
+
kind: "boolean",
|
|
11248
|
+
description: "Install with the arguments after `--` (or none) without asking."
|
|
11249
|
+
},
|
|
11250
|
+
{
|
|
11251
|
+
name: "timeout",
|
|
11252
|
+
kind: "duration",
|
|
11253
|
+
valueName: "DURATION",
|
|
11254
|
+
description: "How long to wait for the service to start before printing its address and token. Default 3m; 0 skips the wait."
|
|
11050
11255
|
}
|
|
11051
11256
|
],
|
|
11052
11257
|
acceptsRest: true,
|
|
11053
11258
|
local: true,
|
|
11054
11259
|
examples: [
|
|
11260
|
+
"orkestrator service install",
|
|
11055
11261
|
"orkestrator service install -- --tailscale-serve",
|
|
11056
11262
|
"orkestrator service install --release 2.22.0 -- --host 100.64.0.1",
|
|
11057
11263
|
"orkestrator service install --dry-run"
|
|
@@ -11066,6 +11272,15 @@ var serviceCommands = [
|
|
|
11066
11272
|
if (reserved) {
|
|
11067
11273
|
throw new CliError("invalid-input", `${reserved} is set by the service; leave it out`);
|
|
11068
11274
|
}
|
|
11275
|
+
const interactive = parsed.rest.length === 0 && parsed.options.yes !== true && context.global.output === "human" && context.io.stdinIsTty && context.io.question !== undefined;
|
|
11276
|
+
const readyWaitMs = typeof parsed.options.timeout === "number" ? parsed.options.timeout : DEFAULT_READY_WAIT_MS;
|
|
11277
|
+
if (readyWaitMs > PUBLIC_API_LIMITS.waitMaxMs) {
|
|
11278
|
+
throw new CliError("invalid-input", "--timeout may be at most 24h");
|
|
11279
|
+
}
|
|
11280
|
+
const serveArgs = interactive ? await askServeArguments(context.io, {
|
|
11281
|
+
installCommand: installCommandLine(parsed),
|
|
11282
|
+
signal: context.signal
|
|
11283
|
+
}) : parsed.rest;
|
|
11069
11284
|
const bun = process.execPath;
|
|
11070
11285
|
const bunVersion = typeof Bun === "undefined" ? "" : Bun.version;
|
|
11071
11286
|
const { service, layout, unit } = await unitFor(context, dataDir, bun);
|
|
@@ -11074,7 +11289,7 @@ var serviceCommands = [
|
|
|
11074
11289
|
version,
|
|
11075
11290
|
bun,
|
|
11076
11291
|
bunVersion,
|
|
11077
|
-
args:
|
|
11292
|
+
args: serveArgs,
|
|
11078
11293
|
unit: { manager: unit.manager, name: unit.name, file: unit.file },
|
|
11079
11294
|
release: service.releaseDirectory(layout, version)
|
|
11080
11295
|
};
|
|
@@ -11088,7 +11303,7 @@ var serviceCommands = [
|
|
|
11088
11303
|
["release", `${version} \u2192 ${summary.release}`],
|
|
11089
11304
|
["bun", `${bun} (${bunVersion})`],
|
|
11090
11305
|
["unit", `${unit.manager} ${unit.name} \u2192 ${unit.file}`],
|
|
11091
|
-
["serve arguments",
|
|
11306
|
+
["serve arguments", serveArgs.join(" ") || "(none)"]
|
|
11092
11307
|
]),
|
|
11093
11308
|
"",
|
|
11094
11309
|
"Dry run: nothing was installed."
|
|
@@ -11097,6 +11312,7 @@ var serviceCommands = [
|
|
|
11097
11312
|
}
|
|
11098
11313
|
context.io.stderr(`Installing orkestrator@${version}\u2026
|
|
11099
11314
|
`);
|
|
11315
|
+
throwIfInterrupted(context.signal);
|
|
11100
11316
|
let releaseDir;
|
|
11101
11317
|
try {
|
|
11102
11318
|
releaseDir = await service.installRelease(layout, version, { bun });
|
|
@@ -11110,28 +11326,59 @@ var serviceCommands = [
|
|
|
11110
11326
|
dataDir,
|
|
11111
11327
|
bun,
|
|
11112
11328
|
bunVersion,
|
|
11113
|
-
args:
|
|
11329
|
+
args: serveArgs,
|
|
11114
11330
|
installedAt: new Date().toISOString()
|
|
11115
11331
|
});
|
|
11116
11332
|
await mkdir2(layout.logs, { recursive: true });
|
|
11117
|
-
await mkdir2(
|
|
11333
|
+
await mkdir2(path14.dirname(unit.file), { recursive: true });
|
|
11118
11334
|
await writeFile2(unit.file, unit.contents);
|
|
11119
11335
|
const started = parsed.options["skip-start"] !== true;
|
|
11336
|
+
const logFile = path14.join(layout.logs, "service.log");
|
|
11337
|
+
let connection = null;
|
|
11120
11338
|
if (started) {
|
|
11339
|
+
const previousGeneration = await currentDescriptorGeneration(dataDir);
|
|
11121
11340
|
const commands = serviceManagerCommands(unit);
|
|
11122
11341
|
commands.load.forEach((argv, index) => runManager(argv, unit.manager === "launchd" && index === 0));
|
|
11342
|
+
if (readyWaitMs > 0) {
|
|
11343
|
+
context.io.stderr(`Waiting for the backend to start\u2026
|
|
11344
|
+
`);
|
|
11345
|
+
connection = await awaitServiceConnection(dataDir, previousGeneration, {
|
|
11346
|
+
timeoutMs: readyWaitMs,
|
|
11347
|
+
signal: context.signal
|
|
11348
|
+
});
|
|
11349
|
+
}
|
|
11123
11350
|
}
|
|
11124
11351
|
return {
|
|
11125
11352
|
action: "service.install",
|
|
11126
|
-
result: {
|
|
11353
|
+
result: {
|
|
11354
|
+
dryRun: false,
|
|
11355
|
+
started,
|
|
11356
|
+
ready: connection !== null,
|
|
11357
|
+
browserUrl: connection?.browserUrl ?? null,
|
|
11358
|
+
authFile: connection?.authFile ?? null,
|
|
11359
|
+
...connection?.credentialError ? { credentialError: connection.credentialError } : {},
|
|
11360
|
+
...summary
|
|
11361
|
+
},
|
|
11127
11362
|
human: [
|
|
11128
11363
|
...keyValues([
|
|
11129
11364
|
["release", `${version} (${releaseDir})`],
|
|
11130
11365
|
["unit", `${unit.manager} ${unit.name}`],
|
|
11131
|
-
["logs",
|
|
11366
|
+
["logs", logFile]
|
|
11132
11367
|
]),
|
|
11133
11368
|
"",
|
|
11134
11369
|
started ? "The service is running. Remote clients can update it from Settings \u2192 Machines or `orkestrator host update`." : `The unit is written but not loaded; load it with: ${serviceManagerCommands(unit).load.at(-1).join(" ")}`,
|
|
11370
|
+
...connection ? [
|
|
11371
|
+
"",
|
|
11372
|
+
...keyValues([
|
|
11373
|
+
["address", connection.browserUrl ?? "(no browser listener; see the log)"],
|
|
11374
|
+
["auth file", connection.authFile],
|
|
11375
|
+
...context.io.stdoutIsTty && context.global.output === "human" && connection.token ? [["token", connection.token]] : []
|
|
11376
|
+
]),
|
|
11377
|
+
...connection.credentialError ? [`Credential file error: ${connection.credentialError}`] : context.io.stdoutIsTty && context.global.output === "human" ? ["Keep the token private: it grants full access to this backend."] : ["Read the gateway token locally from the private auth file."]
|
|
11378
|
+
] : started && readyWaitMs > 0 ? [
|
|
11379
|
+
"",
|
|
11380
|
+
`The backend has not reported ready yet. Follow ${logFile}; its address and token file are logged there.`
|
|
11381
|
+
] : [],
|
|
11135
11382
|
...unit.manager === "systemd" ? ["Run `loginctl enable-linger $USER` so it keeps running after you log out."] : []
|
|
11136
11383
|
]
|
|
11137
11384
|
};
|
|
@@ -11154,7 +11401,7 @@ var serviceCommands = [
|
|
|
11154
11401
|
const dataDir = dataDirectory(context, parsed);
|
|
11155
11402
|
const { service, layout, unit } = await unitFor(context, dataDir, process.execPath);
|
|
11156
11403
|
const config = service.readServiceConfig(layout);
|
|
11157
|
-
if (
|
|
11404
|
+
if (existsSync5(unit.file)) {
|
|
11158
11405
|
for (const argv of serviceManagerCommands(unit).unload)
|
|
11159
11406
|
runManager(argv, true);
|
|
11160
11407
|
await rm2(unit.file, { force: true });
|
|
@@ -11182,7 +11429,7 @@ var serviceCommands = [
|
|
|
11182
11429
|
const { service, layout, unit } = await unitFor(context, dataDir, process.execPath);
|
|
11183
11430
|
const config = service.readServiceConfig(layout);
|
|
11184
11431
|
const state = service.readLauncherState(layout);
|
|
11185
|
-
const installed =
|
|
11432
|
+
const installed = existsSync5(unit.file);
|
|
11186
11433
|
const running = installed ? runManager(serviceManagerCommands(unit).status, true).ok : false;
|
|
11187
11434
|
const result = {
|
|
11188
11435
|
dataDir,
|
|
@@ -12375,9 +12622,9 @@ var sessionCommands = [
|
|
|
12375
12622
|
];
|
|
12376
12623
|
|
|
12377
12624
|
// src/client/commands/toolchain.ts
|
|
12378
|
-
import
|
|
12625
|
+
import path18 from "path";
|
|
12379
12626
|
function dataDirectory2(context, parsed) {
|
|
12380
|
-
return
|
|
12627
|
+
return path18.resolve(stringOption(parsed.options, "data-dir") ?? context.io.env.ORKESTRATOR_DATA_DIR ?? defaultDataDir(process.platform, context.io.env));
|
|
12381
12628
|
}
|
|
12382
12629
|
function requestedTools(parsed) {
|
|
12383
12630
|
const raw = parsed.options.tool;
|
|
@@ -12480,7 +12727,7 @@ var toolchainCommands = [
|
|
|
12480
12727
|
const rows = installed.tools.map((tool) => ({
|
|
12481
12728
|
tool,
|
|
12482
12729
|
version: installed.versions[tool] ?? "",
|
|
12483
|
-
executable:
|
|
12730
|
+
executable: path18.join(installed.currentBinDir, path18.basename(installed.executables[tool]))
|
|
12484
12731
|
}));
|
|
12485
12732
|
return {
|
|
12486
12733
|
action: "toolchain.install",
|
|
@@ -12566,6 +12813,7 @@ function rootHelp(tree) {
|
|
|
12566
12813
|
return [
|
|
12567
12814
|
"Usage:",
|
|
12568
12815
|
" orkestrator [serve] [service options] Run the backend service in the foreground",
|
|
12816
|
+
" orkestrator service install [options] Install the backend as a background service",
|
|
12569
12817
|
" orkestrator <group> <command> [options] Talk to an already-running backend",
|
|
12570
12818
|
" orkestrator --fix AGENT Get an agent's help reporting a problem",
|
|
12571
12819
|
"",
|
|
@@ -12744,6 +12992,53 @@ function defaultHuman(result) {
|
|
|
12744
12992
|
`);
|
|
12745
12993
|
}
|
|
12746
12994
|
|
|
12995
|
+
// src/client/questions.ts
|
|
12996
|
+
import { createInterface } from "readline/promises";
|
|
12997
|
+
function terminalQuestions(input, output, onInterrupt) {
|
|
12998
|
+
let reader;
|
|
12999
|
+
let ended = false;
|
|
13000
|
+
return {
|
|
13001
|
+
async question(prompt, signal) {
|
|
13002
|
+
throwIfInterrupted(signal);
|
|
13003
|
+
if (ended)
|
|
13004
|
+
return null;
|
|
13005
|
+
if (!reader) {
|
|
13006
|
+
reader = createInterface({ input, output });
|
|
13007
|
+
reader.once("close", () => {
|
|
13008
|
+
ended = true;
|
|
13009
|
+
});
|
|
13010
|
+
reader.on("SIGINT", onInterrupt);
|
|
13011
|
+
}
|
|
13012
|
+
const current = reader;
|
|
13013
|
+
let onClose = () => {};
|
|
13014
|
+
let onAbort = () => {};
|
|
13015
|
+
try {
|
|
13016
|
+
return await new Promise((resolve, reject) => {
|
|
13017
|
+
onClose = () => resolve(null);
|
|
13018
|
+
onAbort = () => {
|
|
13019
|
+
reject(new CliError("observation-interrupted", "Interrupted"));
|
|
13020
|
+
current.close();
|
|
13021
|
+
};
|
|
13022
|
+
current.once("close", onClose);
|
|
13023
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
13024
|
+
if (signal?.aborted) {
|
|
13025
|
+
onAbort();
|
|
13026
|
+
return;
|
|
13027
|
+
}
|
|
13028
|
+
current.question(prompt).then(resolve, reject);
|
|
13029
|
+
});
|
|
13030
|
+
} finally {
|
|
13031
|
+
current.off("close", onClose);
|
|
13032
|
+
signal?.removeEventListener("abort", onAbort);
|
|
13033
|
+
}
|
|
13034
|
+
},
|
|
13035
|
+
close() {
|
|
13036
|
+
ended = true;
|
|
13037
|
+
reader?.close();
|
|
13038
|
+
}
|
|
13039
|
+
};
|
|
13040
|
+
}
|
|
13041
|
+
|
|
12747
13042
|
// src/client/main.ts
|
|
12748
13043
|
var CLIENT_COMMANDS = [
|
|
12749
13044
|
...connectionCommands,
|
|
@@ -12864,6 +13159,7 @@ async function runClientProcess(argv, version) {
|
|
|
12864
13159
|
};
|
|
12865
13160
|
process.on("SIGINT", onSignal);
|
|
12866
13161
|
process.on("SIGTERM", onSignal);
|
|
13162
|
+
const questions = terminalQuestions(process.stdin, process.stderr, () => onSignal("SIGINT"));
|
|
12867
13163
|
const io = {
|
|
12868
13164
|
stdout: (text) => process.stdout.write(text),
|
|
12869
13165
|
stdoutBytes: (bytes) => process.stdout.write(Buffer.from(bytes)),
|
|
@@ -12875,11 +13171,14 @@ async function runClientProcess(argv, version) {
|
|
|
12875
13171
|
env: process.env,
|
|
12876
13172
|
cwd: process.cwd(),
|
|
12877
13173
|
now: () => Date.now(),
|
|
12878
|
-
stdinIsTty: Boolean(process.stdin.isTTY)
|
|
13174
|
+
stdinIsTty: Boolean(process.stdin.isTTY),
|
|
13175
|
+
stdoutIsTty: Boolean(process.stdout.isTTY),
|
|
13176
|
+
question: questions.question
|
|
12879
13177
|
};
|
|
12880
13178
|
try {
|
|
12881
13179
|
return await runClient(argv, { io, version, signal: controller.signal });
|
|
12882
13180
|
} finally {
|
|
13181
|
+
questions.close();
|
|
12883
13182
|
process.off("SIGINT", onSignal);
|
|
12884
13183
|
process.off("SIGTERM", onSignal);
|
|
12885
13184
|
}
|