@dotobokuri/fleet-console 1.71.0 → 1.72.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.
- package/CLAUDE.md +1 -1
- package/README.md +13 -0
- package/dist/cli.mjs +437 -350
- package/dist/client/assets/{_baseUniq--GYoaiDn.js → _baseUniq-D_AjNlwO.js} +1 -1
- package/dist/client/assets/{arc-ioTPutEb.js → arc-DiscagS3.js} +1 -1
- package/dist/client/assets/{architectureDiagram-Q4EWVU46-DLfH6cdt.js → architectureDiagram-Q4EWVU46-PGPwULb9.js} +1 -1
- package/dist/client/assets/{blockDiagram-DXYQGD6D-ZM6X_dlD.js → blockDiagram-DXYQGD6D-DLexJaxZ.js} +1 -1
- package/dist/client/assets/{c4Diagram-AHTNJAMY-DDPTnZGS.js → c4Diagram-AHTNJAMY-D9Ye73ny.js} +1 -1
- package/dist/client/assets/channel-CR5OWwKU.js +1 -0
- package/dist/client/assets/{chunk-4BX2VUAB-0ShpcAto.js → chunk-4BX2VUAB-B7YgJYL4.js} +1 -1
- package/dist/client/assets/{chunk-4TB4RGXK-CvMAl5bA.js → chunk-4TB4RGXK-CEEQcTWi.js} +1 -1
- package/dist/client/assets/{chunk-55IACEB6-CgV8t6TS.js → chunk-55IACEB6-B8AcnGT7.js} +1 -1
- package/dist/client/assets/{chunk-EDXVE4YY-DQkbYjs9.js → chunk-EDXVE4YY-DjZ88S2h.js} +1 -1
- package/dist/client/assets/{chunk-FMBD7UC4-D4Pm3UM-.js → chunk-FMBD7UC4-io3C2TDz.js} +1 -1
- package/dist/client/assets/{chunk-OYMX7WX6-BrWIgOQ6.js → chunk-OYMX7WX6-s0DPD-0B.js} +1 -1
- package/dist/client/assets/{chunk-QZHKN3VN-BC-GEuDl.js → chunk-QZHKN3VN-DGcrSXIn.js} +1 -1
- package/dist/client/assets/{chunk-YZCP3GAM-Dst--QPc.js → chunk-YZCP3GAM-Dp1DewA_.js} +1 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-BxfrF-vv.js +1 -0
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-BxfrF-vv.js +1 -0
- package/dist/client/assets/clone-BH8tX1wM.js +1 -0
- package/dist/client/assets/{cose-bilkent-S5V4N54A-D87Ru6Nw.js → cose-bilkent-S5V4N54A-D9PZkL8M.js} +1 -1
- package/dist/client/assets/{dagre-KV5264BT-CUG8AIPS.js → dagre-KV5264BT-M-8Bl0QN.js} +1 -1
- package/dist/client/assets/{diagram-5BDNPKRD-DrhhXUdy.js → diagram-5BDNPKRD-CbFVI18N.js} +1 -1
- package/dist/client/assets/{diagram-G4DWMVQ6-DgGQFVlD.js → diagram-G4DWMVQ6-Bofydoge.js} +1 -1
- package/dist/client/assets/{diagram-MMDJMWI5-DEyFyzNg.js → diagram-MMDJMWI5-BZQV1jqh.js} +1 -1
- package/dist/client/assets/{diagram-TYMM5635-ari8AKd5.js → diagram-TYMM5635-v_pX67fP.js} +1 -1
- package/dist/client/assets/{erDiagram-SMLLAGMA-Aywt-vx8.js → erDiagram-SMLLAGMA-DA8k24I7.js} +1 -1
- package/dist/client/assets/{flowDiagram-DWJPFMVM-FO46vDh_.js → flowDiagram-DWJPFMVM-CA3Jm5mj.js} +1 -1
- package/dist/client/assets/{ganttDiagram-T4ZO3ILL-C0m3r6C5.js → ganttDiagram-T4ZO3ILL-B6YPlixu.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-CTUKGfIc.js → gitGraphDiagram-UUTBAWPF-3BjoRhTq.js} +1 -1
- package/dist/client/assets/{graph-PzhNFXt_.js → graph-CjQR1bpo.js} +1 -1
- package/dist/client/assets/index-B21kBRWF.js +467 -0
- package/dist/client/assets/{index-Bcc3Exng.css → index-DKMT7UVt.css} +1 -1
- package/dist/client/assets/{infoDiagram-42DDH7IO-CFry6eYn.js → infoDiagram-42DDH7IO-Cz8NXcwy.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-BBJvVjTh.js → ishikawaDiagram-UXIWVN3A-dJiEc4oW.js} +1 -1
- package/dist/client/assets/{journeyDiagram-VCZTEJTY-glHJeITG.js → journeyDiagram-VCZTEJTY-D0e9gSNl.js} +1 -1
- package/dist/client/assets/{kanban-definition-6JOO6SKY-Dp7IjAmS.js → kanban-definition-6JOO6SKY-DJ-tyN1D.js} +1 -1
- package/dist/client/assets/{layout-PhtOMDDE.js → layout-By8oq65c.js} +1 -1
- package/dist/client/assets/{linear-B3pjuRWl.js → linear-Bgvt1y1F.js} +1 -1
- package/dist/client/assets/{mermaid.core-DDurtDWt.js → mermaid.core-BzUsxrJd.js} +4 -4
- package/dist/client/assets/{min-ZS3oLuaq.js → min-C5LKMAsm.js} +1 -1
- package/dist/client/assets/{mindmap-definition-QFDTVHPH-D67iQI4K.js → mindmap-definition-QFDTVHPH-BVEgUjPO.js} +1 -1
- package/dist/client/assets/{pieDiagram-DEJITSTG-B95nftHb.js → pieDiagram-DEJITSTG-H6ERErU1.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-34T5L4WZ-BbBVDSwm.js → quadrantDiagram-34T5L4WZ-B3Y2XYCJ.js} +1 -1
- package/dist/client/assets/{requirementDiagram-MS252O5E-Dbtcs04o.js → requirementDiagram-MS252O5E-NgcHrVQM.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-XADWPNL6-BuqmxYyX.js → sankeyDiagram-XADWPNL6-DtmwsCxU.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-FGHM5R23-DmLihX3U.js → sequenceDiagram-FGHM5R23-Rd0S2w1n.js} +1 -1
- package/dist/client/assets/{stateDiagram-FHFEXIEX-D3Z_iYXj.js → stateDiagram-FHFEXIEX-Cpag_fk7.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Cbjujcp-.js +1 -0
- package/dist/client/assets/{timeline-definition-GMOUNBTQ-witmATQr.js → timeline-definition-GMOUNBTQ-C8yS2XLP.js} +1 -1
- package/dist/client/assets/{vennDiagram-DHZGUBPP-BDI4z0F-.js → vennDiagram-DHZGUBPP-Bj7SvZFm.js} +1 -1
- package/dist/client/assets/{wardley-RL74JXVD-oYmBD5eO.js → wardley-RL74JXVD-DZhhw2v9.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-NUSXRM2D-DhnyRjSq.js → wardleyDiagram-NUSXRM2D-DgpBbIN3.js} +1 -1
- package/dist/client/assets/{xychartDiagram-5P7HB3ND-DUY-bU_6.js → xychartDiagram-5P7HB3ND-CUq82Sal.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/fleet-plugins/ledger/routes.mjs +103 -16
- package/dist/fleet-plugins/quota/routes.mjs +662 -148
- package/dist/fleet-plugins/scuttlebutt/routes.mjs +103 -16
- package/dist/fleet-plugins/terminal/routes.mjs +1394 -488
- package/dist/fleet.mjs +3468 -1329
- package/package.json +1 -1
- package/dist/client/assets/channel-BvAoE0IP.js +0 -1
- package/dist/client/assets/classDiagram-6PBFFD2Q-BeVFxENS.js +0 -1
- package/dist/client/assets/classDiagram-v2-HSJHXN6E-BeVFxENS.js +0 -1
- package/dist/client/assets/clone-TnYsvJuQ.js +0 -1
- package/dist/client/assets/index-DkOT93yC.js +0 -467
- package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-BbUn16lr.js +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import * as
|
|
3
|
-
import
|
|
2
|
+
import * as fs10 from 'node:fs';
|
|
3
|
+
import fs10__default, { realpathSync, accessSync, constants as constants$1, existsSync, lstatSync } from 'node:fs';
|
|
4
4
|
import * as path18 from 'node:path';
|
|
5
5
|
import path18__default, { join, resolve, relative, sep } from 'node:path';
|
|
6
6
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
@@ -14,7 +14,8 @@ import http from 'node:http';
|
|
|
14
14
|
import https from 'node:https';
|
|
15
15
|
import { mkdtemp, rm, mkdir, readdir, readFile, stat, appendFile, writeFile, rename, realpath, lstat } from 'node:fs/promises';
|
|
16
16
|
import fontList from 'font-list';
|
|
17
|
-
import
|
|
17
|
+
import net3 from 'node:net';
|
|
18
|
+
import tls from 'node:tls';
|
|
18
19
|
import { execFile } from 'child_process';
|
|
19
20
|
import { constants } from 'fs';
|
|
20
21
|
import 'fs/promises';
|
|
@@ -24,7 +25,6 @@ import { deflateRawSync } from 'zlib';
|
|
|
24
25
|
import { EventEmitter } from 'node:events';
|
|
25
26
|
import { query } from '@anthropic-ai/claude-agent-sdk';
|
|
26
27
|
import selfsigned from 'selfsigned';
|
|
27
|
-
import tls from 'node:tls';
|
|
28
28
|
|
|
29
29
|
var __defProp = Object.defineProperty;
|
|
30
30
|
var __export = (target, all) => {
|
|
@@ -238,6 +238,18 @@ function createConsoleHealthClient(deps = {}) {
|
|
|
238
238
|
}
|
|
239
239
|
return { probe };
|
|
240
240
|
}
|
|
241
|
+
function createConsoleStalePolicy(deps = {}) {
|
|
242
|
+
const fsImpl = deps.fs ?? fs10__default;
|
|
243
|
+
function isBuildStale(lock, buildFile) {
|
|
244
|
+
try {
|
|
245
|
+
return lock.startedAt < fsImpl.statSync(buildFile).mtimeMs;
|
|
246
|
+
} catch (err) {
|
|
247
|
+
if (err.code === "ENOENT") return false;
|
|
248
|
+
throw err;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return { isBuildStale };
|
|
252
|
+
}
|
|
241
253
|
|
|
242
254
|
// cli/styles/tokens.ts
|
|
243
255
|
var ANSI_RESET = "\x1B[0m";
|
|
@@ -301,7 +313,7 @@ function readFleetCliRelease() {
|
|
|
301
313
|
var LOCK_DIR_MODE = 448;
|
|
302
314
|
var LOCK_FILE_MODE = 384;
|
|
303
315
|
function createConsoleLock(deps = {}) {
|
|
304
|
-
const fsImpl = deps.fs ??
|
|
316
|
+
const fsImpl = deps.fs ?? fs10__default;
|
|
305
317
|
const now = deps.now ?? Date.now;
|
|
306
318
|
const randomToken = deps.randomToken ?? (() => crypto5.randomBytes(32).toString("base64url"));
|
|
307
319
|
const hostname5 = deps.hostname ?? (() => "127.0.0.1");
|
|
@@ -333,7 +345,7 @@ function createConsoleLock(deps = {}) {
|
|
|
333
345
|
version: input.version,
|
|
334
346
|
...input.owner ? { owner: input.owner } : {}
|
|
335
347
|
};
|
|
336
|
-
const fd = fsImpl.openSync(input.lockFile,
|
|
348
|
+
const fd = fsImpl.openSync(input.lockFile, fs10__default.constants.O_CREAT | fs10__default.constants.O_EXCL | fs10__default.constants.O_WRONLY, LOCK_FILE_MODE);
|
|
337
349
|
try {
|
|
338
350
|
fsImpl.writeFileSync(fd, `${JSON.stringify(payload, null, 2)}
|
|
339
351
|
`, "utf8");
|
|
@@ -409,10 +421,10 @@ function getFleetDataDir(env = process.env) {
|
|
|
409
421
|
}
|
|
410
422
|
var SECURE_DIR_MODE = 448;
|
|
411
423
|
var SECURE_FILE_MODE = 384;
|
|
412
|
-
var NOFOLLOW_FLAG =
|
|
424
|
+
var NOFOLLOW_FLAG = fs10.constants.O_NOFOLLOW ?? 0;
|
|
413
425
|
function safeLstat(targetPath) {
|
|
414
426
|
try {
|
|
415
|
-
return
|
|
427
|
+
return fs10.lstatSync(targetPath);
|
|
416
428
|
} catch (error51) {
|
|
417
429
|
if (error51.code === "ENOENT") {
|
|
418
430
|
return null;
|
|
@@ -426,15 +438,15 @@ function ensureSafeDirectory(dirPath) {
|
|
|
426
438
|
if (!stat4.isDirectory() || stat4.isSymbolicLink()) {
|
|
427
439
|
throw new Error(`Unsafe Fleet directory: ${dirPath}`);
|
|
428
440
|
}
|
|
429
|
-
|
|
441
|
+
fs10.chmodSync(dirPath, SECURE_DIR_MODE);
|
|
430
442
|
return;
|
|
431
443
|
}
|
|
432
|
-
|
|
444
|
+
fs10.mkdirSync(dirPath, { recursive: true, mode: SECURE_DIR_MODE });
|
|
433
445
|
const created = safeLstat(dirPath);
|
|
434
446
|
if (!created?.isDirectory() || created.isSymbolicLink()) {
|
|
435
447
|
throw new Error(`Unsafe Fleet directory: ${dirPath}`);
|
|
436
448
|
}
|
|
437
|
-
|
|
449
|
+
fs10.chmodSync(dirPath, SECURE_DIR_MODE);
|
|
438
450
|
}
|
|
439
451
|
function assertWithinRoot(root, candidatePath) {
|
|
440
452
|
const resolvedRoot = path18.resolve(root);
|
|
@@ -460,17 +472,17 @@ function writeAtomicSync(filePath, content, options = {}) {
|
|
|
460
472
|
const tempPath = buildTempPath(filePath);
|
|
461
473
|
let tempCreated = false;
|
|
462
474
|
try {
|
|
463
|
-
|
|
475
|
+
fs10.writeFileSync(tempPath, content, { encoding: "utf-8", flag: "wx", mode });
|
|
464
476
|
tempCreated = true;
|
|
465
477
|
if (doFsync) {
|
|
466
|
-
const fd =
|
|
478
|
+
const fd = fs10.openSync(tempPath, "r");
|
|
467
479
|
try {
|
|
468
480
|
fsyncSyncBestEffort(fd);
|
|
469
481
|
} finally {
|
|
470
|
-
|
|
482
|
+
fs10.closeSync(fd);
|
|
471
483
|
}
|
|
472
484
|
}
|
|
473
|
-
|
|
485
|
+
fs10.renameSync(tempPath, filePath);
|
|
474
486
|
return;
|
|
475
487
|
} catch (error51) {
|
|
476
488
|
const code = error51.code;
|
|
@@ -480,7 +492,7 @@ function writeAtomicSync(filePath, content, options = {}) {
|
|
|
480
492
|
}
|
|
481
493
|
if (tempCreated) {
|
|
482
494
|
try {
|
|
483
|
-
|
|
495
|
+
fs10.unlinkSync(tempPath);
|
|
484
496
|
} catch {
|
|
485
497
|
}
|
|
486
498
|
}
|
|
@@ -492,7 +504,7 @@ function writeAtomicSync(filePath, content, options = {}) {
|
|
|
492
504
|
function cleanupTempFiles(dir, prefix, minAgeMs, now) {
|
|
493
505
|
let entries;
|
|
494
506
|
try {
|
|
495
|
-
entries =
|
|
507
|
+
entries = fs10.readdirSync(dir);
|
|
496
508
|
} catch {
|
|
497
509
|
return;
|
|
498
510
|
}
|
|
@@ -502,9 +514,9 @@ function cleanupTempFiles(dir, prefix, minAgeMs, now) {
|
|
|
502
514
|
}
|
|
503
515
|
const tempPath = path18.join(dir, entry);
|
|
504
516
|
try {
|
|
505
|
-
const stat4 =
|
|
517
|
+
const stat4 = fs10.lstatSync(tempPath);
|
|
506
518
|
if (stat4?.isFile() && !stat4.isSymbolicLink() && now - stat4.mtimeMs >= minAgeMs) {
|
|
507
|
-
|
|
519
|
+
fs10.unlinkSync(tempPath);
|
|
508
520
|
}
|
|
509
521
|
} catch {
|
|
510
522
|
}
|
|
@@ -516,7 +528,7 @@ function isIgnoredFsyncError(error51) {
|
|
|
516
528
|
}
|
|
517
529
|
function fsyncSyncBestEffort(fd) {
|
|
518
530
|
try {
|
|
519
|
-
|
|
531
|
+
fs10.fsyncSync(fd);
|
|
520
532
|
} catch (error51) {
|
|
521
533
|
if (!isIgnoredFsyncError(error51)) {
|
|
522
534
|
throw error51;
|
|
@@ -536,7 +548,7 @@ function withDirectoryLock(deps, operation) {
|
|
|
536
548
|
const startedAt = now();
|
|
537
549
|
while (true) {
|
|
538
550
|
try {
|
|
539
|
-
|
|
551
|
+
fs10.mkdirSync(deps.lockDir, { mode: 448 });
|
|
540
552
|
writeLockOwner(deps.lockDir, ownerFileName, now());
|
|
541
553
|
try {
|
|
542
554
|
return operation();
|
|
@@ -556,7 +568,7 @@ function withDirectoryLock(deps, operation) {
|
|
|
556
568
|
}
|
|
557
569
|
function releaseLock(lockDir) {
|
|
558
570
|
try {
|
|
559
|
-
|
|
571
|
+
fs10.rmSync(lockDir, { recursive: true, force: true });
|
|
560
572
|
} catch {
|
|
561
573
|
}
|
|
562
574
|
}
|
|
@@ -566,14 +578,14 @@ function recoverStaleLock(lockDir, ownerFileName, now, staleLockMs) {
|
|
|
566
578
|
if (!isRecoverableSnapshot(initialSnapshot, now, staleLockMs)) return;
|
|
567
579
|
const quarantineDir = buildQuarantinePath(lockDir);
|
|
568
580
|
try {
|
|
569
|
-
|
|
581
|
+
fs10.renameSync(lockDir, quarantineDir);
|
|
570
582
|
} catch {
|
|
571
583
|
return;
|
|
572
584
|
}
|
|
573
585
|
try {
|
|
574
586
|
const quarantinedSnapshot = readLockSnapshot(quarantineDir, ownerFileName);
|
|
575
587
|
if (sameLockSnapshot(initialSnapshot, quarantinedSnapshot) && isRecoverableSnapshot(quarantinedSnapshot, now, staleLockMs)) {
|
|
576
|
-
|
|
588
|
+
fs10.rmSync(quarantineDir, { recursive: true, force: true });
|
|
577
589
|
} else {
|
|
578
590
|
restoreQuarantinedLock(quarantineDir, lockDir);
|
|
579
591
|
}
|
|
@@ -587,7 +599,7 @@ function recoverStaleLock(lockDir, ownerFileName, now, staleLockMs) {
|
|
|
587
599
|
}
|
|
588
600
|
}
|
|
589
601
|
function readLockSnapshot(lockDir, ownerFileName) {
|
|
590
|
-
const stat4 =
|
|
602
|
+
const stat4 = fs10.lstatSync(lockDir);
|
|
591
603
|
if (stat4.isSymbolicLink()) {
|
|
592
604
|
return { owner: null, mtimeMs: 0 };
|
|
593
605
|
}
|
|
@@ -608,7 +620,7 @@ function writeLockOwner(lockDir, ownerFileName, startedAt) {
|
|
|
608
620
|
};
|
|
609
621
|
const ownerPath = path18.join(lockDir, ownerFileName);
|
|
610
622
|
try {
|
|
611
|
-
|
|
623
|
+
fs10.writeFileSync(ownerPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
|
|
612
624
|
} catch (error51) {
|
|
613
625
|
releaseLock(lockDir);
|
|
614
626
|
throw error51;
|
|
@@ -617,7 +629,7 @@ function writeLockOwner(lockDir, ownerFileName, startedAt) {
|
|
|
617
629
|
function readLockOwner(lockDir, ownerFileName) {
|
|
618
630
|
const ownerPath = path18.join(lockDir, ownerFileName);
|
|
619
631
|
try {
|
|
620
|
-
return sanitizeLockOwner(JSON.parse(
|
|
632
|
+
return sanitizeLockOwner(JSON.parse(fs10.readFileSync(ownerPath, "utf-8")));
|
|
621
633
|
} catch (error51) {
|
|
622
634
|
const code = error51.code;
|
|
623
635
|
if (code === "ENOENT") return null;
|
|
@@ -639,7 +651,7 @@ function sameLockSnapshot(a, b) {
|
|
|
639
651
|
}
|
|
640
652
|
function restoreQuarantinedLock(quarantineDir, lockDir) {
|
|
641
653
|
try {
|
|
642
|
-
|
|
654
|
+
fs10.renameSync(quarantineDir, lockDir);
|
|
643
655
|
} catch {
|
|
644
656
|
}
|
|
645
657
|
}
|
|
@@ -679,17 +691,17 @@ var AUTH_LOCK_TIMEOUT_MS = 5e3;
|
|
|
679
691
|
function readAuthStoreFile(filePath) {
|
|
680
692
|
let fd;
|
|
681
693
|
try {
|
|
682
|
-
fd =
|
|
683
|
-
if (!
|
|
694
|
+
fd = fs10.openSync(filePath, fs10.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
695
|
+
if (!fs10.fstatSync(fd).isFile()) {
|
|
684
696
|
return {};
|
|
685
697
|
}
|
|
686
|
-
return JSON.parse(
|
|
698
|
+
return JSON.parse(fs10.readFileSync(fd, "utf-8"));
|
|
687
699
|
} catch {
|
|
688
700
|
return {};
|
|
689
701
|
} finally {
|
|
690
702
|
if (fd !== void 0) {
|
|
691
703
|
try {
|
|
692
|
-
|
|
704
|
+
fs10.closeSync(fd);
|
|
693
705
|
} catch {
|
|
694
706
|
}
|
|
695
707
|
}
|
|
@@ -703,7 +715,7 @@ function createAuthService(deps = {}) {
|
|
|
703
715
|
async deleteApiKey(providerId) {
|
|
704
716
|
let deleted = false;
|
|
705
717
|
withAuthLock(authPath, lockDir, () => {
|
|
706
|
-
if (!
|
|
718
|
+
if (!fs10.existsSync(authPath)) return;
|
|
707
719
|
const data = readAuthStoreFile(authPath);
|
|
708
720
|
if (!Object.prototype.hasOwnProperty.call(data, providerId)) return;
|
|
709
721
|
delete data[providerId];
|
|
@@ -716,21 +728,21 @@ function createAuthService(deps = {}) {
|
|
|
716
728
|
async getApiKey(providerId) {
|
|
717
729
|
let fd;
|
|
718
730
|
try {
|
|
719
|
-
if (!
|
|
731
|
+
if (!fs10.existsSync(authPath)) {
|
|
720
732
|
return void 0;
|
|
721
733
|
}
|
|
722
|
-
fd =
|
|
723
|
-
if (!
|
|
734
|
+
fd = fs10.openSync(authPath, fs10.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
735
|
+
if (!fs10.fstatSync(fd).isFile()) {
|
|
724
736
|
return void 0;
|
|
725
737
|
}
|
|
726
|
-
const data = JSON.parse(
|
|
738
|
+
const data = JSON.parse(fs10.readFileSync(fd, "utf-8"));
|
|
727
739
|
return typeof data[providerId]?.key === "string" ? data[providerId].key : void 0;
|
|
728
740
|
} catch {
|
|
729
741
|
return void 0;
|
|
730
742
|
} finally {
|
|
731
743
|
if (fd !== void 0) {
|
|
732
744
|
try {
|
|
733
|
-
|
|
745
|
+
fs10.closeSync(fd);
|
|
734
746
|
} catch {
|
|
735
747
|
}
|
|
736
748
|
}
|
|
@@ -738,7 +750,7 @@ function createAuthService(deps = {}) {
|
|
|
738
750
|
},
|
|
739
751
|
// [HIGH #2] 읽기 경로: fd 기반 O_RDONLY|O_NOFOLLOW 통일
|
|
740
752
|
async listProviderIds() {
|
|
741
|
-
if (!
|
|
753
|
+
if (!fs10.existsSync(authPath)) {
|
|
742
754
|
return [];
|
|
743
755
|
}
|
|
744
756
|
try {
|
|
@@ -751,7 +763,7 @@ function createAuthService(deps = {}) {
|
|
|
751
763
|
const dir = path18.dirname(authPath);
|
|
752
764
|
ensureSafeDirectory(dir);
|
|
753
765
|
withAuthLock(authPath, lockDir, () => {
|
|
754
|
-
const data =
|
|
766
|
+
const data = fs10.existsSync(authPath) ? readAuthStoreFile(authPath) : {};
|
|
755
767
|
data[providerId] = {
|
|
756
768
|
...data[providerId] ?? {},
|
|
757
769
|
key
|
|
@@ -834,21 +846,21 @@ function createDurableJsonStore(deps) {
|
|
|
834
846
|
function readJsonFile(filePath, sanitize) {
|
|
835
847
|
let fd;
|
|
836
848
|
try {
|
|
837
|
-
const stat4 =
|
|
849
|
+
const stat4 = fs10.lstatSync(filePath);
|
|
838
850
|
if (!stat4 || !stat4.isFile() || stat4.isSymbolicLink()) {
|
|
839
851
|
return sanitize(void 0);
|
|
840
852
|
}
|
|
841
|
-
fd =
|
|
842
|
-
if (!
|
|
853
|
+
fd = fs10.openSync(filePath, fs10.constants.O_RDONLY | NOFOLLOW_FLAG);
|
|
854
|
+
if (!fs10.fstatSync(fd).isFile()) {
|
|
843
855
|
return sanitize(void 0);
|
|
844
856
|
}
|
|
845
|
-
return sanitize(JSON.parse(
|
|
857
|
+
return sanitize(JSON.parse(fs10.readFileSync(fd, "utf-8")));
|
|
846
858
|
} catch {
|
|
847
859
|
return sanitize(void 0);
|
|
848
860
|
} finally {
|
|
849
861
|
if (fd !== void 0) {
|
|
850
862
|
try {
|
|
851
|
-
|
|
863
|
+
fs10.closeSync(fd);
|
|
852
864
|
} catch {
|
|
853
865
|
}
|
|
854
866
|
}
|
|
@@ -858,7 +870,7 @@ function ensureSafeDirectoryIfSensitive(dir, sensitivity) {
|
|
|
858
870
|
if (sensitivity === "sensitive") {
|
|
859
871
|
ensureSafeDirectory(dir);
|
|
860
872
|
} else {
|
|
861
|
-
|
|
873
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
862
874
|
}
|
|
863
875
|
}
|
|
864
876
|
|
|
@@ -998,7 +1010,7 @@ function canonicalizeWorkspaceCwd(cwd) {
|
|
|
998
1010
|
if (!cwd.trim()) {
|
|
999
1011
|
throw new Error("Workspace cwd is required");
|
|
1000
1012
|
}
|
|
1001
|
-
return
|
|
1013
|
+
return fs10.realpathSync.native(path18.resolve(cwd));
|
|
1002
1014
|
}
|
|
1003
1015
|
function assertWorkspaceDirectoryName(name) {
|
|
1004
1016
|
if (!name || !WORKSPACE_NAME_PATTERN.test(name)) {
|
|
@@ -1013,7 +1025,7 @@ function readWorkspaceIdentity(identityPath) {
|
|
|
1013
1025
|
}
|
|
1014
1026
|
let parsed;
|
|
1015
1027
|
try {
|
|
1016
|
-
parsed = JSON.parse(
|
|
1028
|
+
parsed = JSON.parse(fs10.readFileSync(identityPath, "utf8"));
|
|
1017
1029
|
} catch (error51) {
|
|
1018
1030
|
throw new Error(`Invalid workspace identity file: ${identityPath}`, { cause: error51 });
|
|
1019
1031
|
}
|
|
@@ -1100,11 +1112,11 @@ function isDesktopDevelopmentEnvironment2(env = process.env) {
|
|
|
1100
1112
|
}
|
|
1101
1113
|
function validateDesktopResourceRoot(root, expectedPackageRoot = resolveDesktopProtocolPackageRoot()) {
|
|
1102
1114
|
if (!path18__default.isAbsolute(root)) throw new Error("desktop_resource_root_not_absolute");
|
|
1103
|
-
const resolvedRoot =
|
|
1104
|
-
const expectedRoot =
|
|
1115
|
+
const resolvedRoot = fs10__default.realpathSync(root);
|
|
1116
|
+
const expectedRoot = fs10__default.realpathSync(expectedPackageRoot);
|
|
1105
1117
|
if (resolvedRoot !== expectedRoot) throw new Error("desktop_resource_root_invalid");
|
|
1106
1118
|
const markerPath = path18__default.join(resolvedRoot, DESKTOP_RESOURCE_ROOT_MARKER);
|
|
1107
|
-
const marker =
|
|
1119
|
+
const marker = fs10__default.readFileSync(markerPath, "utf8");
|
|
1108
1120
|
if (!isDesktopResourceRootMarkerValid(marker)) throw new Error("desktop_resource_root_marker_invalid");
|
|
1109
1121
|
return resolvedRoot;
|
|
1110
1122
|
}
|
|
@@ -1112,11 +1124,11 @@ function validateDesktopDevelopmentResourceRoot(root) {
|
|
|
1112
1124
|
if (!path18__default.isAbsolute(root)) throw new Error("desktop_resource_root_not_absolute");
|
|
1113
1125
|
let resolvedRoot;
|
|
1114
1126
|
try {
|
|
1115
|
-
resolvedRoot =
|
|
1127
|
+
resolvedRoot = fs10__default.realpathSync(root);
|
|
1116
1128
|
} catch {
|
|
1117
1129
|
throw new Error("desktop_development_resource_root_invalid");
|
|
1118
1130
|
}
|
|
1119
|
-
const expectedRoot =
|
|
1131
|
+
const expectedRoot = fs10__default.realpathSync(resolveDesktopProtocolPackageRoot());
|
|
1120
1132
|
if (resolvedRoot !== expectedRoot) throw new Error("desktop_development_resource_root_invalid");
|
|
1121
1133
|
return resolvedRoot;
|
|
1122
1134
|
}
|
|
@@ -11738,7 +11750,7 @@ function resolveLocked(workspace, hooks) {
|
|
|
11738
11750
|
const stagingState = inspectTree(staging2);
|
|
11739
11751
|
if (stagingState === "content") {
|
|
11740
11752
|
removeEmptyDirectories(destination);
|
|
11741
|
-
|
|
11753
|
+
fs10.renameSync(staging2, destination);
|
|
11742
11754
|
syncDirectory(workspace.path);
|
|
11743
11755
|
} else if (stagingState !== "missing") throw new Error("Unsafe Fleet Wiki migration staging state");
|
|
11744
11756
|
return createMemoryPaths(destination);
|
|
@@ -11760,14 +11772,14 @@ function resolveLocked(workspace, hooks) {
|
|
|
11760
11772
|
`);
|
|
11761
11773
|
syncDirectory(workspace.path);
|
|
11762
11774
|
removeEmptyDirectories(destination);
|
|
11763
|
-
|
|
11775
|
+
fs10.renameSync(staging, destination);
|
|
11764
11776
|
syncDirectory(workspace.path);
|
|
11765
11777
|
return createMemoryPaths(destination);
|
|
11766
11778
|
}
|
|
11767
11779
|
function inspectTree(target, regularRootIsContent = false, treeRoot = target) {
|
|
11768
11780
|
let stat4;
|
|
11769
11781
|
try {
|
|
11770
|
-
stat4 =
|
|
11782
|
+
stat4 = fs10.lstatSync(target);
|
|
11771
11783
|
} catch (error51) {
|
|
11772
11784
|
if (error51.code === "ENOENT") return "missing";
|
|
11773
11785
|
throw error51;
|
|
@@ -11776,7 +11788,7 @@ function inspectTree(target, regularRootIsContent = false, treeRoot = target) {
|
|
|
11776
11788
|
if (nodeKind === "unsafe") return "unsafe";
|
|
11777
11789
|
if (nodeKind === "file") return regularRootIsContent ? "content" : "unsafe";
|
|
11778
11790
|
let content = false;
|
|
11779
|
-
for (const entry of
|
|
11791
|
+
for (const entry of fs10.readdirSync(target, { withFileTypes: true })) {
|
|
11780
11792
|
const entryPath = path18__default.join(target, entry.name);
|
|
11781
11793
|
if (entry.isSymbolicLink()) {
|
|
11782
11794
|
if (readSafeFileSymlink(treeRoot, entryPath) === null) return "unsafe";
|
|
@@ -11796,7 +11808,7 @@ function inspectTree(target, regularRootIsContent = false, treeRoot = target) {
|
|
|
11796
11808
|
function readMarker(markerPath) {
|
|
11797
11809
|
let stat4;
|
|
11798
11810
|
try {
|
|
11799
|
-
stat4 =
|
|
11811
|
+
stat4 = fs10.lstatSync(markerPath);
|
|
11800
11812
|
} catch (error51) {
|
|
11801
11813
|
if (error51.code === "ENOENT") return null;
|
|
11802
11814
|
throw error51;
|
|
@@ -11804,7 +11816,7 @@ function readMarker(markerPath) {
|
|
|
11804
11816
|
if (!stat4.isFile() || stat4.isSymbolicLink()) throw new Error("Unsafe Fleet Wiki migration marker");
|
|
11805
11817
|
let value;
|
|
11806
11818
|
try {
|
|
11807
|
-
value = JSON.parse(
|
|
11819
|
+
value = JSON.parse(fs10.readFileSync(markerPath, "utf8"));
|
|
11808
11820
|
} catch {
|
|
11809
11821
|
throw new Error("Invalid Fleet Wiki migration marker");
|
|
11810
11822
|
}
|
|
@@ -11814,29 +11826,29 @@ function readMarker(markerPath) {
|
|
|
11814
11826
|
return record4;
|
|
11815
11827
|
}
|
|
11816
11828
|
function copyTree(source, destination, hooks, sourceRoot = source) {
|
|
11817
|
-
|
|
11818
|
-
for (const entry of
|
|
11829
|
+
fs10.mkdirSync(destination, { recursive: true });
|
|
11830
|
+
for (const entry of fs10.readdirSync(source, { withFileTypes: true })) {
|
|
11819
11831
|
const from = path18__default.join(source, entry.name);
|
|
11820
11832
|
const to = path18__default.join(destination, entry.name);
|
|
11821
|
-
const stat4 =
|
|
11833
|
+
const stat4 = fs10.lstatSync(from);
|
|
11822
11834
|
if (stat4.isSymbolicLink()) {
|
|
11823
11835
|
const target = readSafeFileSymlink(sourceRoot, from);
|
|
11824
11836
|
if (target === null) throw new Error("Unsafe Fleet Wiki legacy source state");
|
|
11825
|
-
|
|
11837
|
+
fs10.symlinkSync(target, to, "file");
|
|
11826
11838
|
continue;
|
|
11827
11839
|
}
|
|
11828
11840
|
const nodeKind = classifyWikiWorkspaceNodeForTest(stat4);
|
|
11829
11841
|
if (nodeKind === "unsafe") throw new Error("Unsafe Fleet Wiki legacy source state");
|
|
11830
11842
|
if (nodeKind === "directory") copyTree(from, to, hooks, sourceRoot);
|
|
11831
11843
|
else {
|
|
11832
|
-
|
|
11844
|
+
fs10.copyFileSync(from, to);
|
|
11833
11845
|
syncFile(to);
|
|
11834
11846
|
}
|
|
11835
11847
|
}
|
|
11836
11848
|
syncDirectory(destination);
|
|
11837
11849
|
}
|
|
11838
11850
|
function readSafeFileSymlink(treeRoot, linkPath) {
|
|
11839
|
-
const target =
|
|
11851
|
+
const target = fs10.readlinkSync(linkPath);
|
|
11840
11852
|
if (path18__default.posix.isAbsolute(target) || path18__default.win32.isAbsolute(target)) return null;
|
|
11841
11853
|
const lexicalRoot = path18__default.resolve(treeRoot);
|
|
11842
11854
|
const lexicalTarget = path18__default.resolve(path18__default.dirname(linkPath), target);
|
|
@@ -11845,9 +11857,9 @@ function readSafeFileSymlink(treeRoot, linkPath) {
|
|
|
11845
11857
|
let canonicalTarget;
|
|
11846
11858
|
let targetStat;
|
|
11847
11859
|
try {
|
|
11848
|
-
canonicalRoot =
|
|
11849
|
-
canonicalTarget =
|
|
11850
|
-
targetStat =
|
|
11860
|
+
canonicalRoot = fs10.realpathSync(treeRoot);
|
|
11861
|
+
canonicalTarget = fs10.realpathSync(linkPath);
|
|
11862
|
+
targetStat = fs10.statSync(linkPath);
|
|
11851
11863
|
} catch (error51) {
|
|
11852
11864
|
if (error51.code === "ENOENT") return null;
|
|
11853
11865
|
throw error51;
|
|
@@ -11869,19 +11881,19 @@ function removeEmptyDirectories(target) {
|
|
|
11869
11881
|
const state = inspectTree(target, true);
|
|
11870
11882
|
if (state === "missing") return;
|
|
11871
11883
|
if (state === "unsafe") throw new Error("Unsafe Fleet Wiki destination state");
|
|
11872
|
-
if (state === "empty")
|
|
11884
|
+
if (state === "empty") fs10.rmSync(target, { recursive: true, force: false });
|
|
11873
11885
|
}
|
|
11874
11886
|
function removePriorStaging(workspacePath, stagingEntries) {
|
|
11875
|
-
for (const name of stagingEntries)
|
|
11887
|
+
for (const name of stagingEntries) fs10.rmSync(path18__default.join(workspacePath, name), { recursive: true, force: false });
|
|
11876
11888
|
}
|
|
11877
11889
|
function inspectReservedControlState(workspacePath) {
|
|
11878
11890
|
const stagingEntries = [];
|
|
11879
|
-
for (const entry of
|
|
11891
|
+
for (const entry of fs10.readdirSync(workspacePath, { withFileTypes: true })) {
|
|
11880
11892
|
if (entry.name.startsWith(`${MARKER_NAME}.`)) {
|
|
11881
11893
|
const residuePath = path18__default.join(workspacePath, entry.name);
|
|
11882
|
-
const residue =
|
|
11894
|
+
const residue = fs10.lstatSync(residuePath);
|
|
11883
11895
|
if (MARKER_TEMP_REGEXP.test(entry.name) && residue.isFile() && !residue.isSymbolicLink()) {
|
|
11884
|
-
|
|
11896
|
+
fs10.unlinkSync(residuePath);
|
|
11885
11897
|
continue;
|
|
11886
11898
|
}
|
|
11887
11899
|
throw new Error("Unsafe Fleet Wiki migration marker control state");
|
|
@@ -11895,33 +11907,33 @@ function inspectReservedControlState(workspacePath) {
|
|
|
11895
11907
|
}
|
|
11896
11908
|
function writeAtomic2(target, contents) {
|
|
11897
11909
|
const temporary = `${target}.${randomUUID()}.tmp`;
|
|
11898
|
-
|
|
11910
|
+
fs10.writeFileSync(temporary, contents, { mode: 384 });
|
|
11899
11911
|
syncFile(temporary);
|
|
11900
|
-
|
|
11912
|
+
fs10.renameSync(temporary, target);
|
|
11901
11913
|
}
|
|
11902
11914
|
function fsyncBestEffort(fd) {
|
|
11903
11915
|
try {
|
|
11904
|
-
|
|
11916
|
+
fs10.fsyncSync(fd);
|
|
11905
11917
|
} catch (error51) {
|
|
11906
11918
|
const code = error51.code;
|
|
11907
11919
|
if (typeof code !== "string" || !IGNORED_FSYNC_ERROR_CODES2.has(code)) throw error51;
|
|
11908
11920
|
}
|
|
11909
11921
|
}
|
|
11910
11922
|
function syncFile(target) {
|
|
11911
|
-
const fd =
|
|
11923
|
+
const fd = fs10.openSync(target, "r");
|
|
11912
11924
|
try {
|
|
11913
11925
|
fsyncBestEffort(fd);
|
|
11914
11926
|
} finally {
|
|
11915
|
-
|
|
11927
|
+
fs10.closeSync(fd);
|
|
11916
11928
|
}
|
|
11917
11929
|
}
|
|
11918
11930
|
function syncDirectory(target) {
|
|
11919
11931
|
if (!shouldSyncDirectoryForTest(process.platform)) return;
|
|
11920
|
-
const fd =
|
|
11932
|
+
const fd = fs10.openSync(target, "r");
|
|
11921
11933
|
try {
|
|
11922
11934
|
fsyncBestEffort(fd);
|
|
11923
11935
|
} finally {
|
|
11924
|
-
|
|
11936
|
+
fs10.closeSync(fd);
|
|
11925
11937
|
}
|
|
11926
11938
|
}
|
|
11927
11939
|
function shouldSyncDirectoryForTest(platform) {
|
|
@@ -12352,7 +12364,7 @@ function createConsoleSettingsStore(deps = {}) {
|
|
|
12352
12364
|
const paths = deps.paths ?? createConsoleDataPaths();
|
|
12353
12365
|
const createStore = deps.createStore ?? createDurableJsonStore;
|
|
12354
12366
|
const randomInt = deps.randomInt ?? crypto5.randomInt;
|
|
12355
|
-
const readFile7 = deps.readFile ?? ((file2) =>
|
|
12367
|
+
const readFile7 = deps.readFile ?? ((file2) => fs10__default.readFileSync(file2, "utf8"));
|
|
12356
12368
|
const base = createStore({
|
|
12357
12369
|
filePath: paths.settingsFile,
|
|
12358
12370
|
lockDir: path18__default.join(paths.dir, SETTINGS_LOCK_DIR_NAME),
|
|
@@ -13557,7 +13569,7 @@ function formatCookie(name, value, secure, maxAgeSeconds) {
|
|
|
13557
13569
|
var REMOTE_DIR = "remote";
|
|
13558
13570
|
var FILE_MODE = 384;
|
|
13559
13571
|
function createRemoteStorage(consoleDir, deps = {}) {
|
|
13560
|
-
const fileSystem = deps.fileSystem ??
|
|
13572
|
+
const fileSystem = deps.fileSystem ?? fs10__default;
|
|
13561
13573
|
const ensureDirectory = deps.ensureDirectory ?? ensureSafeDirectory;
|
|
13562
13574
|
const directory = path18__default.join(consoleDir, REMOTE_DIR);
|
|
13563
13575
|
return {
|
|
@@ -13587,7 +13599,7 @@ function hashPairingSecret(secret) {
|
|
|
13587
13599
|
}
|
|
13588
13600
|
function createPairedDeviceStore(consoleDir, deps = {}) {
|
|
13589
13601
|
const storage = createRemoteStorage(consoleDir, deps);
|
|
13590
|
-
const readFile7 = deps.readFile ?? ((file2) =>
|
|
13602
|
+
const readFile7 = deps.readFile ?? ((file2) => fs10__default.readFileSync(file2, "utf8"));
|
|
13591
13603
|
const now = deps.now ?? Date.now;
|
|
13592
13604
|
const randomId = deps.randomId ?? (() => crypto5.randomBytes(8).toString("hex"));
|
|
13593
13605
|
const randomSecret = deps.randomSecret ?? (() => crypto5.randomBytes(32).toString("base64url"));
|
|
@@ -13675,6 +13687,168 @@ function isStoredDevice(value) {
|
|
|
13675
13687
|
const entry = value;
|
|
13676
13688
|
return typeof entry.id === "string" && entry.id.length > 0 && typeof entry.secretHash === "string" && /^[0-9a-f]{64}$/u.test(entry.secretHash) && (entry.audience === "local" || entry.audience === "remote") && (entry.access === "full" || entry.access === "monitoring") && (entry.device === null || typeof entry.device === "string") && typeof entry.pairedAt === "number" && Number.isFinite(entry.pairedAt) && typeof entry.lastSeenAt === "number" && Number.isFinite(entry.lastSeenAt);
|
|
13677
13689
|
}
|
|
13690
|
+
|
|
13691
|
+
// access-protocol/index.ts
|
|
13692
|
+
var ACCESS_LINK_SCHEME = "fleet:";
|
|
13693
|
+
var ACCESS_LINK_HOST = "join";
|
|
13694
|
+
var ACCESS_LINK_PREFIX = "fleet://join?code=";
|
|
13695
|
+
var ACCESS_LINK_VERSION = 1;
|
|
13696
|
+
var ACCESS_JOIN_PATH = "/api/v1/join";
|
|
13697
|
+
var MAX_ACCESS_LABEL_LENGTH = 48;
|
|
13698
|
+
var MAX_ACCESS_LINK_LENGTH = 4096;
|
|
13699
|
+
var ACCESS_TOKEN = /^[A-Za-z0-9_-]{16,512}$/u;
|
|
13700
|
+
var CERTIFICATE_FINGERPRINT = /^[0-9A-F]{64}$/u;
|
|
13701
|
+
var PAYLOAD_KEYS = ["v", "endpoint", "token", "fingerprint", "label"];
|
|
13702
|
+
var BASE64_URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
13703
|
+
var BASE64_URL_DECODE = createBase64UrlDecodeTable();
|
|
13704
|
+
function encodeAccessLink(payload) {
|
|
13705
|
+
const envelope = {
|
|
13706
|
+
v: ACCESS_LINK_VERSION,
|
|
13707
|
+
endpoint: payload.endpoint,
|
|
13708
|
+
token: payload.token,
|
|
13709
|
+
fingerprint: normalizeFingerprint(payload.fingerprint),
|
|
13710
|
+
label: sanitizeAccessLabel(payload.label)
|
|
13711
|
+
};
|
|
13712
|
+
return `${ACCESS_LINK_PREFIX}${toBase64Url(new TextEncoder().encode(JSON.stringify(envelope)))}`;
|
|
13713
|
+
}
|
|
13714
|
+
function parseAccessLink(input) {
|
|
13715
|
+
if (typeof input !== "string") throw invalidLink();
|
|
13716
|
+
const candidate = input.trim();
|
|
13717
|
+
if (candidate.length === 0 || candidate.length > MAX_ACCESS_LINK_LENGTH) throw invalidLink();
|
|
13718
|
+
if (containsDisallowedLinkWhitespace(candidate)) throw invalidLink();
|
|
13719
|
+
let url2;
|
|
13720
|
+
try {
|
|
13721
|
+
url2 = new URL(candidate);
|
|
13722
|
+
} catch {
|
|
13723
|
+
throw invalidLink();
|
|
13724
|
+
}
|
|
13725
|
+
if (url2.protocol !== ACCESS_LINK_SCHEME || url2.username || url2.password || url2.hash) throw invalidLink();
|
|
13726
|
+
if (url2.hostname !== ACCESS_LINK_HOST || url2.port !== "" || url2.pathname !== "") throw invalidLink();
|
|
13727
|
+
const keys = [...url2.searchParams.keys()];
|
|
13728
|
+
if (keys.length !== 1 || keys[0] !== "code") throw invalidLink();
|
|
13729
|
+
return readPayload(decodePayload(url2.searchParams.get("code") ?? ""));
|
|
13730
|
+
}
|
|
13731
|
+
function decodePayload(code) {
|
|
13732
|
+
if (!/^[A-Za-z0-9_-]+$/u.test(code)) throw invalidLink();
|
|
13733
|
+
let text;
|
|
13734
|
+
try {
|
|
13735
|
+
text = new TextDecoder("utf-8", { fatal: true }).decode(fromBase64Url(code));
|
|
13736
|
+
} catch {
|
|
13737
|
+
throw invalidLink();
|
|
13738
|
+
}
|
|
13739
|
+
try {
|
|
13740
|
+
return JSON.parse(text);
|
|
13741
|
+
} catch {
|
|
13742
|
+
throw invalidLink();
|
|
13743
|
+
}
|
|
13744
|
+
}
|
|
13745
|
+
function readPayload(value) {
|
|
13746
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw invalidLink();
|
|
13747
|
+
const entry = value;
|
|
13748
|
+
const keys = Object.keys(entry);
|
|
13749
|
+
if (keys.length !== PAYLOAD_KEYS.length || !PAYLOAD_KEYS.every((key) => keys.includes(key))) throw invalidLink();
|
|
13750
|
+
if (entry.v !== ACCESS_LINK_VERSION) throw invalidLink();
|
|
13751
|
+
if (typeof entry.endpoint !== "string" || typeof entry.token !== "string" || typeof entry.fingerprint !== "string" || typeof entry.label !== "string") throw invalidLink();
|
|
13752
|
+
const endpoint = readEndpoint(entry.endpoint);
|
|
13753
|
+
const token = entry.token;
|
|
13754
|
+
const fingerprint = normalizeFingerprint(entry.fingerprint);
|
|
13755
|
+
if (!ACCESS_TOKEN.test(token) || !CERTIFICATE_FINGERPRINT.test(fingerprint)) throw invalidLink();
|
|
13756
|
+
const label = sanitizeAccessLabel(entry.label);
|
|
13757
|
+
if (label.length === 0) throw invalidLink();
|
|
13758
|
+
return {
|
|
13759
|
+
origin: endpoint.origin,
|
|
13760
|
+
hostname: pinHostname(endpoint.hostname),
|
|
13761
|
+
port: endpoint.port,
|
|
13762
|
+
label,
|
|
13763
|
+
consoleUrl: new URL("/console/", endpoint.origin).toString(),
|
|
13764
|
+
joinUrl: new URL(ACCESS_JOIN_PATH, endpoint.origin).toString(),
|
|
13765
|
+
token,
|
|
13766
|
+
fingerprint
|
|
13767
|
+
};
|
|
13768
|
+
}
|
|
13769
|
+
function readEndpoint(value) {
|
|
13770
|
+
let url2;
|
|
13771
|
+
try {
|
|
13772
|
+
url2 = new URL(value);
|
|
13773
|
+
} catch {
|
|
13774
|
+
throw invalidLink();
|
|
13775
|
+
}
|
|
13776
|
+
if (url2.protocol !== "https:" || url2.username || url2.password || url2.search || url2.hash) throw invalidLink();
|
|
13777
|
+
if (url2.pathname !== "/" && url2.pathname !== "") throw invalidLink();
|
|
13778
|
+
if (url2.hostname.length === 0) throw invalidLink();
|
|
13779
|
+
const port = url2.port === "" ? 443 : Number(url2.port);
|
|
13780
|
+
if (!Number.isSafeInteger(port) || port < 1 || port > 65535) throw invalidLink();
|
|
13781
|
+
return { origin: url2.origin, hostname: url2.hostname, port };
|
|
13782
|
+
}
|
|
13783
|
+
function pinHostname(hostname5) {
|
|
13784
|
+
const unwrapped = hostname5.startsWith("[") && hostname5.endsWith("]") ? hostname5.slice(1, -1) : hostname5;
|
|
13785
|
+
return unwrapped.toLowerCase();
|
|
13786
|
+
}
|
|
13787
|
+
function normalizeFingerprint(value) {
|
|
13788
|
+
return value.replace(/[^0-9a-fA-F]/gu, "").toUpperCase();
|
|
13789
|
+
}
|
|
13790
|
+
function sanitizeAccessLabel(value) {
|
|
13791
|
+
return Array.from(value).filter((character) => !isDisallowedAccessLabelCharacter(character.codePointAt(0))).join("").replace(/\s+/gu, " ").trim().slice(0, MAX_ACCESS_LABEL_LENGTH);
|
|
13792
|
+
}
|
|
13793
|
+
function containsDisallowedLinkWhitespace(value) {
|
|
13794
|
+
for (const character of value) {
|
|
13795
|
+
const codePoint = character.codePointAt(0);
|
|
13796
|
+
if (codePoint <= 31 || codePoint === 127 || isWhitespaceCharacter(character)) return true;
|
|
13797
|
+
}
|
|
13798
|
+
return false;
|
|
13799
|
+
}
|
|
13800
|
+
function isWhitespaceCharacter(character) {
|
|
13801
|
+
return character.trim().length === 0;
|
|
13802
|
+
}
|
|
13803
|
+
function isDisallowedAccessLabelCharacter(codePoint) {
|
|
13804
|
+
return codePoint <= 31 || codePoint >= 127 && codePoint <= 159 || codePoint >= 8203 && codePoint <= 8207 || codePoint === 8232 || codePoint === 8233 || codePoint >= 8234 && codePoint <= 8238 || codePoint >= 8294 && codePoint <= 8297;
|
|
13805
|
+
}
|
|
13806
|
+
function toBase64Url(bytes) {
|
|
13807
|
+
let encoded = "";
|
|
13808
|
+
for (let index = 0; index < bytes.length; index += 3) {
|
|
13809
|
+
const first = bytes[index];
|
|
13810
|
+
const second = bytes[index + 1];
|
|
13811
|
+
const third = bytes[index + 2];
|
|
13812
|
+
encoded += BASE64_URL_ALPHABET[first >> 2];
|
|
13813
|
+
encoded += BASE64_URL_ALPHABET[(first & 3) << 4 | (second ?? 0) >> 4];
|
|
13814
|
+
if (second !== void 0) encoded += BASE64_URL_ALPHABET[(second & 15) << 2 | (third ?? 0) >> 6];
|
|
13815
|
+
if (third !== void 0) encoded += BASE64_URL_ALPHABET[third & 63];
|
|
13816
|
+
}
|
|
13817
|
+
return encoded;
|
|
13818
|
+
}
|
|
13819
|
+
function fromBase64Url(value) {
|
|
13820
|
+
if (value.length % 4 === 1) throw invalidLink();
|
|
13821
|
+
const bytes = new Uint8Array(Math.floor(value.length * 6 / 8));
|
|
13822
|
+
let buffer = 0;
|
|
13823
|
+
let bits = 0;
|
|
13824
|
+
let offset = 0;
|
|
13825
|
+
for (const character of value) {
|
|
13826
|
+
const decoded = BASE64_URL_DECODE[character.charCodeAt(0)] ?? -1;
|
|
13827
|
+
if (decoded < 0) throw invalidLink();
|
|
13828
|
+
buffer = buffer << 6 | decoded;
|
|
13829
|
+
bits += 6;
|
|
13830
|
+
if (bits >= 8) {
|
|
13831
|
+
bits -= 8;
|
|
13832
|
+
bytes[offset] = buffer >> bits & 255;
|
|
13833
|
+
offset += 1;
|
|
13834
|
+
}
|
|
13835
|
+
}
|
|
13836
|
+
if (bits > 0 && (buffer & (1 << bits) - 1) !== 0) throw invalidLink();
|
|
13837
|
+
return bytes;
|
|
13838
|
+
}
|
|
13839
|
+
function createBase64UrlDecodeTable() {
|
|
13840
|
+
const table = new Int16Array(128);
|
|
13841
|
+
table.fill(-1);
|
|
13842
|
+
for (let index = 0; index < BASE64_URL_ALPHABET.length; index += 1) {
|
|
13843
|
+
table[BASE64_URL_ALPHABET.charCodeAt(index)] = index;
|
|
13844
|
+
}
|
|
13845
|
+
return table;
|
|
13846
|
+
}
|
|
13847
|
+
function invalidLink() {
|
|
13848
|
+
return new Error("pairing_target_invalid");
|
|
13849
|
+
}
|
|
13850
|
+
|
|
13851
|
+
// core/host/remote-discovery.ts
|
|
13678
13852
|
function listRemoteInterfaces(interfaces = os4__default.networkInterfaces()) {
|
|
13679
13853
|
const candidates = [];
|
|
13680
13854
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -13698,6 +13872,32 @@ function labelFor(interfaceName) {
|
|
|
13698
13872
|
function sanitizeName(value) {
|
|
13699
13873
|
return value.replace(/[^A-Za-z0-9._-]/gu, "").slice(0, 24) || "interface";
|
|
13700
13874
|
}
|
|
13875
|
+
var REMOTE_PROBE_TIMEOUT_MS = 6e3;
|
|
13876
|
+
function probeRemoteIdentity(hostname5, port, expected, timeoutMs = REMOTE_PROBE_TIMEOUT_MS) {
|
|
13877
|
+
return new Promise((resolve3) => {
|
|
13878
|
+
const settle = (result) => {
|
|
13879
|
+
socket.destroy();
|
|
13880
|
+
resolve3(result);
|
|
13881
|
+
};
|
|
13882
|
+
const socket = tls.connect({
|
|
13883
|
+
host: hostname5,
|
|
13884
|
+
port,
|
|
13885
|
+
rejectUnauthorized: false,
|
|
13886
|
+
// IP 리터럴에는 SNI를 붙이지 않는다 — 규격상 SNI는 이름에만 쓴다.
|
|
13887
|
+
...net3.isIP(hostname5) === 0 ? { servername: hostname5 } : {}
|
|
13888
|
+
}, () => {
|
|
13889
|
+
const certificate = socket.getPeerX509Certificate();
|
|
13890
|
+
if (!certificate) {
|
|
13891
|
+
settle({ state: "unreachable" });
|
|
13892
|
+
return;
|
|
13893
|
+
}
|
|
13894
|
+
const presented = normalizeFingerprint(certificate.fingerprint256);
|
|
13895
|
+
settle(presented === normalizeFingerprint(expected) ? { state: "match" } : { state: "mismatch", presented });
|
|
13896
|
+
});
|
|
13897
|
+
socket.setTimeout(timeoutMs, () => settle({ state: "unreachable" }));
|
|
13898
|
+
socket.on("error", () => settle({ state: "unreachable" }));
|
|
13899
|
+
});
|
|
13900
|
+
}
|
|
13701
13901
|
|
|
13702
13902
|
// core/host/codex/workspace-routes.ts
|
|
13703
13903
|
function createCodexWorkspaceRouter(deps) {
|
|
@@ -14422,7 +14622,7 @@ function isOriginAllowed(origin, allowedOrigins, serverPort) {
|
|
|
14422
14622
|
if (Number(parsed.port) !== serverPort) return false;
|
|
14423
14623
|
const normalizedHost = normalizeOriginHostname(parsed.hostname);
|
|
14424
14624
|
if (!normalizedHost) return false;
|
|
14425
|
-
return allowedOrigins.has(`${parsed.protocol}//${
|
|
14625
|
+
return allowedOrigins.has(`${parsed.protocol}//${net3.isIP(normalizedHost) === 6 ? `[${normalizedHost}]` : normalizedHost}:${serverPort}`);
|
|
14426
14626
|
}
|
|
14427
14627
|
function sendJson(response, statusCode, body2) {
|
|
14428
14628
|
response.writeHead(statusCode, withSecurityHeaders(JSON_HEADERS));
|
|
@@ -14444,7 +14644,7 @@ function normalizeOriginHostname(hostname5) {
|
|
|
14444
14644
|
const unbracketed = stripIpv6Brackets(hostname5).toLowerCase();
|
|
14445
14645
|
if (unbracketed.includes("%")) return null;
|
|
14446
14646
|
if (unbracketed.startsWith("::ffff:")) return null;
|
|
14447
|
-
if (
|
|
14647
|
+
if (net3.isIP(unbracketed) === 6) {
|
|
14448
14648
|
try {
|
|
14449
14649
|
return stripIpv6Brackets(new URL(`http://[${unbracketed}]:1`).hostname).toLowerCase();
|
|
14450
14650
|
} catch {
|
|
@@ -33602,6 +33802,11 @@ function hasClaudeOneMillionMarker(modelId) {
|
|
|
33602
33802
|
function stripClaudeOneMillionMarker(modelId) {
|
|
33603
33803
|
return modelId.replace(/\[1m\]$/i, "");
|
|
33604
33804
|
}
|
|
33805
|
+
var CLAUDE_CLIENT_IDENTITY_SENTENCES = [
|
|
33806
|
+
"You are Claude Code, Anthropic's official CLI for Claude.",
|
|
33807
|
+
"You are a Claude agent, built on Anthropic's Claude Agent SDK."
|
|
33808
|
+
];
|
|
33809
|
+
Math.max(...CLAUDE_CLIENT_IDENTITY_SENTENCES.map((sentence) => sentence.length)) + 16;
|
|
33605
33810
|
var benchmarks_default = {
|
|
33606
33811
|
version: 2,
|
|
33607
33812
|
sources: {
|
|
@@ -33819,8 +34024,48 @@ var benchmarks_default = {
|
|
|
33819
34024
|
};
|
|
33820
34025
|
var models_default = {
|
|
33821
34026
|
version: 1,
|
|
33822
|
-
updatedAt: "2026-08-
|
|
34027
|
+
updatedAt: "2026-08-22T00:00:00Z",
|
|
33823
34028
|
providers: {
|
|
34029
|
+
antigravity: {
|
|
34030
|
+
name: "Antigravity",
|
|
34031
|
+
defaultModel: "gemini-3.7-flash",
|
|
34032
|
+
source: "live POST https://daily-cloudcode-pa.googleapis.com/v1internal:fetchAvailableModels read with the credential the Antigravity CLI (agy 1.1.18) owns, 2026-08-22; the same read reported defaultAgentModelId gemini-3.7-flash-high and a deprecatedModelIds entry mapping gemini-3.1-pro-high to gemini-pro-agent, and a live streamGenerateContent probe on that date confirmed gemini-3.1-pro-high is refused with INVALID_ARGUMENT while gemini-pro-agent answers. Effort spelling was measured per model on one fixed prompt: gemini-3.7-flash-tiered honours generationConfig.thinkingConfig.thinkingLevel (343 / 407 / 434 reasoning tokens at low / medium / high) so its ladder is a request field, while Gemini 3.1 Pro encodes the rung in the wire id. thinkingLevel accepts low, medium, and high only: minimal and max are both refused. Claude and GPT-OSS models are served by the same subscription but are deliberately not exposed here",
|
|
34033
|
+
models: [
|
|
34034
|
+
{
|
|
34035
|
+
modelId: "gemini-3.7-flash",
|
|
34036
|
+
name: "Gemini-3.7-Flash",
|
|
34037
|
+
capabilityClass: "light",
|
|
34038
|
+
providerModelId: "gemini-3.7-flash-tiered",
|
|
34039
|
+
contextWindow: 1048576,
|
|
34040
|
+
effort: {
|
|
34041
|
+
supported: true,
|
|
34042
|
+
levels: [
|
|
34043
|
+
"low",
|
|
34044
|
+
"medium",
|
|
34045
|
+
"high"
|
|
34046
|
+
]
|
|
34047
|
+
}
|
|
34048
|
+
},
|
|
34049
|
+
{
|
|
34050
|
+
modelId: "gemini-3.1-pro",
|
|
34051
|
+
name: "Gemini-3.1-Pro",
|
|
34052
|
+
capabilityClass: "flagship",
|
|
34053
|
+
providerModelId: "gemini-3.1-pro-low",
|
|
34054
|
+
contextWindow: 1048576,
|
|
34055
|
+
effort: {
|
|
34056
|
+
supported: true,
|
|
34057
|
+
levels: [
|
|
34058
|
+
"low",
|
|
34059
|
+
"high"
|
|
34060
|
+
],
|
|
34061
|
+
upstreamModelIds: {
|
|
34062
|
+
low: "gemini-3.1-pro-low",
|
|
34063
|
+
high: "gemini-pro-agent"
|
|
34064
|
+
}
|
|
34065
|
+
}
|
|
34066
|
+
}
|
|
34067
|
+
]
|
|
34068
|
+
},
|
|
33824
34069
|
codex: {
|
|
33825
34070
|
name: "Codex",
|
|
33826
34071
|
defaultModel: "gpt-5.6-sol",
|
|
@@ -34230,7 +34475,7 @@ var models_default = {
|
|
|
34230
34475
|
{
|
|
34231
34476
|
modelId: "composer-2.5",
|
|
34232
34477
|
name: "Composer-2.5",
|
|
34233
|
-
capabilityClass: "
|
|
34478
|
+
capabilityClass: "standard",
|
|
34234
34479
|
quotaScope: "auto",
|
|
34235
34480
|
contextWindow: 2e5,
|
|
34236
34481
|
benchmarkKey: "composer-2.5"
|
|
@@ -34238,9 +34483,11 @@ var models_default = {
|
|
|
34238
34483
|
{
|
|
34239
34484
|
modelId: "composer-2.5-fast",
|
|
34240
34485
|
name: "Composer-2.5-Fast",
|
|
34241
|
-
capabilityClass: "
|
|
34486
|
+
capabilityClass: "standard",
|
|
34487
|
+
variantOf: "composer-2.5",
|
|
34242
34488
|
quotaScope: "auto",
|
|
34243
|
-
contextWindow: 2e5
|
|
34489
|
+
contextWindow: 2e5,
|
|
34490
|
+
benchmarkKey: "composer-2.5"
|
|
34244
34491
|
},
|
|
34245
34492
|
{
|
|
34246
34493
|
modelId: "grok-4.5",
|
|
@@ -34262,7 +34509,8 @@ var models_default = {
|
|
|
34262
34509
|
{
|
|
34263
34510
|
modelId: "grok-4.5-fast",
|
|
34264
34511
|
name: "Grok-4.5-Fast",
|
|
34265
|
-
capabilityClass: "
|
|
34512
|
+
capabilityClass: "flagship",
|
|
34513
|
+
variantOf: "grok-4.5",
|
|
34266
34514
|
quotaScope: "auto",
|
|
34267
34515
|
contextWindow: 256e3,
|
|
34268
34516
|
effort: {
|
|
@@ -34273,7 +34521,8 @@ var models_default = {
|
|
|
34273
34521
|
"high"
|
|
34274
34522
|
],
|
|
34275
34523
|
upstreamModelIdTemplate: "cursor-grok-4.5-{effort}-fast"
|
|
34276
|
-
}
|
|
34524
|
+
},
|
|
34525
|
+
benchmarkKey: "grok-4.5"
|
|
34277
34526
|
},
|
|
34278
34527
|
{
|
|
34279
34528
|
modelId: "grok-4.6",
|
|
@@ -34296,7 +34545,8 @@ var models_default = {
|
|
|
34296
34545
|
{
|
|
34297
34546
|
modelId: "grok-4.6-fast",
|
|
34298
34547
|
name: "Grok-4.6-Fast",
|
|
34299
|
-
capabilityClass: "
|
|
34548
|
+
capabilityClass: "flagship",
|
|
34549
|
+
variantOf: "grok-4.6",
|
|
34300
34550
|
quotaScope: "auto",
|
|
34301
34551
|
contextWindow: 256e3,
|
|
34302
34552
|
effort: {
|
|
@@ -34308,7 +34558,8 @@ var models_default = {
|
|
|
34308
34558
|
"xhigh"
|
|
34309
34559
|
],
|
|
34310
34560
|
upstreamModelIdTemplate: "cursor-grok-4.6-{effort}-fast"
|
|
34311
|
-
}
|
|
34561
|
+
},
|
|
34562
|
+
benchmarkKey: "grok-4.6"
|
|
34312
34563
|
},
|
|
34313
34564
|
{
|
|
34314
34565
|
modelId: "claude-opus-5",
|
|
@@ -34693,7 +34944,7 @@ var models_default = {
|
|
|
34693
34944
|
{
|
|
34694
34945
|
modelId: "grok-composer-2.5-fast",
|
|
34695
34946
|
name: "Grok-Composer-2.5-Fast",
|
|
34696
|
-
capabilityClass: "
|
|
34947
|
+
capabilityClass: "standard",
|
|
34697
34948
|
wire: "responses",
|
|
34698
34949
|
contextWindow: 2e5
|
|
34699
34950
|
}
|
|
@@ -34810,7 +35061,7 @@ var models_default = {
|
|
|
34810
35061
|
}
|
|
34811
35062
|
}
|
|
34812
35063
|
};
|
|
34813
|
-
var GATEWAY_PROVIDERS = ["codex", "xai", "cursor", "opencode", "kimi"];
|
|
35064
|
+
var GATEWAY_PROVIDERS = ["codex", "xai", "cursor", "opencode", "antigravity", "kimi"];
|
|
34814
35065
|
var GATEWAY_MODEL_WIRES = ["anthropic", "responses", "chat-completions"];
|
|
34815
35066
|
var GATEWAY_REASONING_EFFORTS = [
|
|
34816
35067
|
"low",
|
|
@@ -34888,6 +35139,14 @@ var GatewayModelEntrySchema = external_exports.object({
|
|
|
34888
35139
|
benchmarkKey: external_exports.string().min(1).optional(),
|
|
34889
35140
|
description: external_exports.string().min(1).optional(),
|
|
34890
35141
|
providerModelId: external_exports.string().min(1).optional(),
|
|
35142
|
+
/**
|
|
35143
|
+
* The catalog entry this one is a serving variant of, when the provider gives
|
|
35144
|
+
* the variant its own wire id and `providerModelId` is therefore unavailable
|
|
35145
|
+
* as the lineage link. Pure provenance: it names a sibling `modelId` in the
|
|
35146
|
+
* same provider and never reaches a request, so the variant keeps sending its
|
|
35147
|
+
* own upstream id while inheriting the base's class and benchmark evidence.
|
|
35148
|
+
*/
|
|
35149
|
+
variantOf: external_exports.string().min(1).optional(),
|
|
34891
35150
|
serviceTier: external_exports.literal("priority").optional(),
|
|
34892
35151
|
cursorMaxMode: external_exports.literal(true).optional(),
|
|
34893
35152
|
quotaScope: external_exports.enum(GATEWAY_QUOTA_SCOPES).optional(),
|
|
@@ -34910,7 +35169,8 @@ var GatewayModelsRegistrySchema = external_exports.object({
|
|
|
34910
35169
|
cursor: GatewayProviderSchema,
|
|
34911
35170
|
kimi: GatewayProviderSchema,
|
|
34912
35171
|
opencode: GatewayProviderSchema,
|
|
34913
|
-
xai: GatewayProviderSchema
|
|
35172
|
+
xai: GatewayProviderSchema,
|
|
35173
|
+
antigravity: GatewayProviderSchema
|
|
34914
35174
|
}).strict(),
|
|
34915
35175
|
pricing: GatewayPricingRegistrySchema
|
|
34916
35176
|
}).strict();
|
|
@@ -34936,7 +35196,6 @@ var registry2 = (() => {
|
|
|
34936
35196
|
return parsed;
|
|
34937
35197
|
})();
|
|
34938
35198
|
var GATEWAY_MODELS_UPDATED_AT = registry2.updatedAt;
|
|
34939
|
-
registry2.pricing.observedAt;
|
|
34940
35199
|
Object.freeze(
|
|
34941
35200
|
Object.fromEntries(
|
|
34942
35201
|
Object.entries(registry2.pricing.models).map(([modelId, pricing]) => [
|
|
@@ -35125,8 +35384,24 @@ function validateRegistry(value) {
|
|
|
35125
35384
|
if (!isRoutingAlias && !model.capabilityClass) {
|
|
35126
35385
|
throw new Error(`Gateway model is missing a capability class: ${provider}/${model.modelId}`);
|
|
35127
35386
|
}
|
|
35128
|
-
|
|
35129
|
-
|
|
35387
|
+
const catalogEntry = (modelId) => modelId === void 0 ? void 0 : definition.models.find((candidate) => candidate.modelId === modelId);
|
|
35388
|
+
const providerLinkedBase = isRoutingAlias ? void 0 : catalogEntry(model.providerModelId);
|
|
35389
|
+
if (model.variantOf && providerLinkedBase && model.providerModelId !== model.variantOf) {
|
|
35390
|
+
throw new Error(`Gateway service-tier sibling names two different bases: ${provider}/${model.modelId}`);
|
|
35391
|
+
}
|
|
35392
|
+
if (model.variantOf === model.modelId) {
|
|
35393
|
+
throw new Error(`Gateway service-tier sibling names itself as its base: ${provider}/${model.modelId}`);
|
|
35394
|
+
}
|
|
35395
|
+
const baseModelId = isRoutingAlias ? void 0 : model.variantOf ?? model.providerModelId;
|
|
35396
|
+
if (baseModelId) {
|
|
35397
|
+
const base = catalogEntry(baseModelId);
|
|
35398
|
+
if (model.variantOf && !base) {
|
|
35399
|
+
throw new Error(`Gateway service-tier sibling names an unknown base: ${provider}/${model.modelId} -> ${model.variantOf}`);
|
|
35400
|
+
}
|
|
35401
|
+
const baseLink = base && base.modelId !== base.providerModelId ? base.variantOf ?? base.providerModelId : base?.variantOf;
|
|
35402
|
+
if (base && catalogEntry(baseLink)) {
|
|
35403
|
+
throw new Error(`Gateway service-tier sibling names another sibling as its base: ${provider}/${model.modelId}`);
|
|
35404
|
+
}
|
|
35130
35405
|
if (base && base.capabilityClass !== model.capabilityClass) {
|
|
35131
35406
|
throw new Error(`Gateway service-tier sibling class differs from its base: ${provider}/${model.modelId}`);
|
|
35132
35407
|
}
|
|
@@ -35167,8 +35442,8 @@ function validateRegistry(value) {
|
|
|
35167
35442
|
}
|
|
35168
35443
|
}
|
|
35169
35444
|
if (exactModelIds) {
|
|
35170
|
-
if (provider !== "cursor") {
|
|
35171
|
-
throw new Error(`Gateway effort model id overrides are only supported by Cursor: ${provider}/${model.modelId}`);
|
|
35445
|
+
if (provider !== "cursor" && provider !== "antigravity") {
|
|
35446
|
+
throw new Error(`Gateway effort model id overrides are only supported by Cursor and Antigravity: ${provider}/${model.modelId}`);
|
|
35172
35447
|
}
|
|
35173
35448
|
for (const effort of Object.keys(exactModelIds)) {
|
|
35174
35449
|
if (!model.effort.levels.includes(effort)) {
|
|
@@ -35269,6 +35544,18 @@ process.platform === "win32" ? constants.O_RDONLY : constants.O_RDONLY | constan
|
|
|
35269
35544
|
platform: process.platform,
|
|
35270
35545
|
homedir: os8.homedir,
|
|
35271
35546
|
env: process.env});
|
|
35547
|
+
var HOUR_MS = 36e5;
|
|
35548
|
+
var WEEK_MS = 7 * 24 * HOUR_MS;
|
|
35549
|
+
var SESSION_MS = 5 * HOUR_MS;
|
|
35550
|
+
var BUCKETS = Object.freeze({
|
|
35551
|
+
"gemini-5h": { id: "session", label: "Gemini", durationMs: SESSION_MS, reported: true },
|
|
35552
|
+
"gemini-weekly": { id: "weekly", label: "Gemini", durationMs: WEEK_MS, reported: true },
|
|
35553
|
+
"3p-5h": { id: "session", label: "Claude & GPT", durationMs: SESSION_MS, reported: false },
|
|
35554
|
+
"3p-weekly": { id: "weekly", label: "Claude & GPT", durationMs: WEEK_MS, reported: false }
|
|
35555
|
+
});
|
|
35556
|
+
Object.freeze(
|
|
35557
|
+
Object.keys(BUCKETS).filter((bucketId) => BUCKETS[bucketId]?.reported === true)
|
|
35558
|
+
);
|
|
35272
35559
|
var CURSOR_GREP_RECEIPT_PREFIX = "FLEET_CURSOR_GREP_V2:";
|
|
35273
35560
|
var CURSOR_GREP_RECEIPT_SCRIPT = String.raw`
|
|
35274
35561
|
const {spawn}=require("node:child_process");
|
|
@@ -37154,7 +37441,7 @@ async function canonicalizeTheaterPath(cwd) {
|
|
|
37154
37441
|
function canonicalizeTheaterPathSync(cwd) {
|
|
37155
37442
|
const resolved = path18__default.resolve(cwd);
|
|
37156
37443
|
try {
|
|
37157
|
-
return
|
|
37444
|
+
return fs10__default.realpathSync.native(resolved);
|
|
37158
37445
|
} catch {
|
|
37159
37446
|
return resolved;
|
|
37160
37447
|
}
|
|
@@ -37174,8 +37461,8 @@ var DIRECTORY_ENTRY_CAP = 500;
|
|
|
37174
37461
|
var WINDOWS_DRIVE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
|
|
37175
37462
|
async function listTheaterFolders(requestedPath, deps = {}) {
|
|
37176
37463
|
const platform = deps.platform ?? process.platform;
|
|
37177
|
-
const stat4 = deps.stat ??
|
|
37178
|
-
const opendir = deps.opendir ??
|
|
37464
|
+
const stat4 = deps.stat ?? fs10__default.promises.stat;
|
|
37465
|
+
const opendir = deps.opendir ?? fs10__default.promises.opendir;
|
|
37179
37466
|
const targetPath = normalizeListPath(requestedPath, platform, deps);
|
|
37180
37467
|
const roots = await listRoots(platform, stat4);
|
|
37181
37468
|
const targetStat = await statDirectory(targetPath, stat4);
|
|
@@ -37286,7 +37573,7 @@ var GRANT_ID_BYTES = 24;
|
|
|
37286
37573
|
var DEFAULT_GRANT_TTL_MS2 = 6e4;
|
|
37287
37574
|
function createFolderGrantStore(deps = {}) {
|
|
37288
37575
|
const randomId = deps.randomId ?? (() => crypto5.randomBytes(GRANT_ID_BYTES).toString("base64url"));
|
|
37289
|
-
const statSync2 = deps.statSync ??
|
|
37576
|
+
const statSync2 = deps.statSync ?? fs10__default.statSync;
|
|
37290
37577
|
const ttlMs = deps.ttlMs ?? DEFAULT_GRANT_TTL_MS2;
|
|
37291
37578
|
const now = deps.now ?? Date.now;
|
|
37292
37579
|
const grants = /* @__PURE__ */ new Map();
|
|
@@ -37312,7 +37599,7 @@ function createFolderGrantStore(deps = {}) {
|
|
|
37312
37599
|
}
|
|
37313
37600
|
return { issue: issue3, consume };
|
|
37314
37601
|
}
|
|
37315
|
-
function validateAbsoluteDirectory(cwd, statSync2 =
|
|
37602
|
+
function validateAbsoluteDirectory(cwd, statSync2 = fs10__default.statSync) {
|
|
37316
37603
|
if (typeof cwd !== "string" || cwd.length === 0 || cwd.includes("\0")) throw new Error("invalid_folder");
|
|
37317
37604
|
if (isWindowsAmbiguousGrantPath(cwd) || !path18__default.isAbsolute(cwd)) throw new Error("invalid_folder");
|
|
37318
37605
|
const normalized = path18__default.resolve(cwd);
|
|
@@ -37696,13 +37983,13 @@ function isJsonRequest(request) {
|
|
|
37696
37983
|
return accept.includes("application/json") || requestedWith.toLowerCase() === "xmlhttprequest";
|
|
37697
37984
|
}
|
|
37698
37985
|
function formatHostForUrl(host) {
|
|
37699
|
-
return
|
|
37986
|
+
return net3.isIP(host) === 6 ? `[${host}]` : host;
|
|
37700
37987
|
}
|
|
37701
37988
|
function canonicalizeAllowedHost(host) {
|
|
37702
37989
|
const unbracketed = stripIpv6Brackets2(host).toLowerCase();
|
|
37703
37990
|
if (unbracketed.includes("%")) return null;
|
|
37704
37991
|
if (isIpv4MappedAddress(unbracketed)) return null;
|
|
37705
|
-
if (
|
|
37992
|
+
if (net3.isIP(unbracketed) === 6) {
|
|
37706
37993
|
try {
|
|
37707
37994
|
return stripIpv6Brackets2(new URL(`http://[${unbracketed}]:1`).hostname).toLowerCase();
|
|
37708
37995
|
} catch {
|
|
@@ -37716,7 +38003,7 @@ function enumerateWildcardAccessHosts(interfaces) {
|
|
|
37716
38003
|
for (const entries of Object.values(interfaces)) {
|
|
37717
38004
|
for (const entry of entries ?? []) {
|
|
37718
38005
|
if (entry.internal) continue;
|
|
37719
|
-
if (
|
|
38006
|
+
if (net3.isIP(entry.address) === 0) continue;
|
|
37720
38007
|
hosts.push(entry.address);
|
|
37721
38008
|
}
|
|
37722
38009
|
}
|
|
@@ -37750,7 +38037,7 @@ function parseHostHeader(value) {
|
|
|
37750
38037
|
const host = canonicalizeAllowedHost(parts[0] ?? "");
|
|
37751
38038
|
const port = Number(parts[1] ?? "");
|
|
37752
38039
|
if (!host || !Number.isInteger(port)) return null;
|
|
37753
|
-
if (
|
|
38040
|
+
if (net3.isIP(host) === 6) return null;
|
|
37754
38041
|
return { host, port };
|
|
37755
38042
|
}
|
|
37756
38043
|
function readRawHeaderValues(rawHeaders, name) {
|
|
@@ -38308,8 +38595,8 @@ function migrateAgentCliIds(state) {
|
|
|
38308
38595
|
function backupDurableStateBeforeAgentCliIdMigration(stateFilePath) {
|
|
38309
38596
|
const backupPath = `${stateFilePath}${BACKUP_FILE_SUFFIX}`;
|
|
38310
38597
|
try {
|
|
38311
|
-
if (!
|
|
38312
|
-
|
|
38598
|
+
if (!fs10__default.existsSync(stateFilePath) || fs10__default.existsSync(backupPath)) return;
|
|
38599
|
+
fs10__default.copyFileSync(stateFilePath, backupPath);
|
|
38313
38600
|
} catch (error51) {
|
|
38314
38601
|
console.warn(`[fleet-console] Agent CLI id migration backup skipped: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
38315
38602
|
}
|
|
@@ -38356,11 +38643,11 @@ function migrateLegacyCaptures(deps) {
|
|
|
38356
38643
|
function migrateLegacyCapturesStrict(deps) {
|
|
38357
38644
|
if (!path18__default.isAbsolute(deps.consoleDataDir)) return;
|
|
38358
38645
|
const capturesDir = path18__default.join(deps.consoleDataDir, LEGACY_CAPTURES_DIR_NAME);
|
|
38359
|
-
if (!
|
|
38646
|
+
if (!fs10__default.existsSync(capturesDir)) return;
|
|
38360
38647
|
let migrated = false;
|
|
38361
38648
|
let retained = false;
|
|
38362
38649
|
try {
|
|
38363
|
-
const entries =
|
|
38650
|
+
const entries = fs10__default.readdirSync(capturesDir);
|
|
38364
38651
|
for (const entry of entries) {
|
|
38365
38652
|
if (!entry.endsWith(".json")) continue;
|
|
38366
38653
|
const operationId = entry.slice(0, -".json".length);
|
|
@@ -38389,7 +38676,7 @@ function migrateLegacyCapturesStrict(deps) {
|
|
|
38389
38676
|
}
|
|
38390
38677
|
if ((!migrated || saved) && !retained) {
|
|
38391
38678
|
try {
|
|
38392
|
-
|
|
38679
|
+
fs10__default.rmSync(capturesDir, { recursive: true, force: true });
|
|
38393
38680
|
} catch (error51) {
|
|
38394
38681
|
console.warn(`[fleet-console] Legacy captures directory removal failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
|
|
38395
38682
|
}
|
|
@@ -38400,7 +38687,7 @@ function processCaptureFile(deps, capturesDir, operationId, entry) {
|
|
|
38400
38687
|
if (operation) {
|
|
38401
38688
|
if (hasProviderSession(operation.payload)) return { migrated: false, retained: false };
|
|
38402
38689
|
const filePath = path18__default.join(capturesDir, entry);
|
|
38403
|
-
const parsed = JSON.parse(
|
|
38690
|
+
const parsed = JSON.parse(fs10__default.readFileSync(filePath, "utf8"));
|
|
38404
38691
|
const providerSession = sanitizeProviderSession(parsed);
|
|
38405
38692
|
if (!providerSession) return { migrated: false, retained: false };
|
|
38406
38693
|
deps.operations.patch(operationId, {
|
|
@@ -38438,7 +38725,7 @@ var ENDPOINT_FILE = "listener.json";
|
|
|
38438
38725
|
var STORE_VERSION2 = 2;
|
|
38439
38726
|
function createRemoteEndpointStore(consoleDir, deps = {}) {
|
|
38440
38727
|
const storage = createRemoteStorage(consoleDir, deps);
|
|
38441
|
-
const readFile7 = deps.readFile ?? ((file2) =>
|
|
38728
|
+
const readFile7 = deps.readFile ?? ((file2) => fs10__default.readFileSync(file2, "utf8"));
|
|
38442
38729
|
let endpoint = read();
|
|
38443
38730
|
function read() {
|
|
38444
38731
|
try {
|
|
@@ -38478,168 +38765,6 @@ function sameEndpoint(left, right) {
|
|
|
38478
38765
|
function isBindablePort2(value) {
|
|
38479
38766
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 && value <= 65535;
|
|
38480
38767
|
}
|
|
38481
|
-
|
|
38482
|
-
// access-protocol/index.ts
|
|
38483
|
-
var ACCESS_LINK_SCHEME = "fleet:";
|
|
38484
|
-
var ACCESS_LINK_HOST = "join";
|
|
38485
|
-
var ACCESS_LINK_PREFIX = "fleet://join?code=";
|
|
38486
|
-
var ACCESS_LINK_VERSION = 1;
|
|
38487
|
-
var ACCESS_JOIN_PATH = "/api/v1/join";
|
|
38488
|
-
var MAX_ACCESS_LABEL_LENGTH = 48;
|
|
38489
|
-
var MAX_ACCESS_LINK_LENGTH = 4096;
|
|
38490
|
-
var ACCESS_TOKEN = /^[A-Za-z0-9_-]{16,512}$/u;
|
|
38491
|
-
var CERTIFICATE_FINGERPRINT = /^[0-9A-F]{64}$/u;
|
|
38492
|
-
var PAYLOAD_KEYS = ["v", "endpoint", "token", "fingerprint", "label"];
|
|
38493
|
-
var BASE64_URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
38494
|
-
var BASE64_URL_DECODE = createBase64UrlDecodeTable();
|
|
38495
|
-
function encodeAccessLink(payload) {
|
|
38496
|
-
const envelope = {
|
|
38497
|
-
v: ACCESS_LINK_VERSION,
|
|
38498
|
-
endpoint: payload.endpoint,
|
|
38499
|
-
token: payload.token,
|
|
38500
|
-
fingerprint: normalizeFingerprint(payload.fingerprint),
|
|
38501
|
-
label: sanitizeAccessLabel(payload.label)
|
|
38502
|
-
};
|
|
38503
|
-
return `${ACCESS_LINK_PREFIX}${toBase64Url(new TextEncoder().encode(JSON.stringify(envelope)))}`;
|
|
38504
|
-
}
|
|
38505
|
-
function parseAccessLink(input) {
|
|
38506
|
-
if (typeof input !== "string") throw invalidLink();
|
|
38507
|
-
const candidate = input.trim();
|
|
38508
|
-
if (candidate.length === 0 || candidate.length > MAX_ACCESS_LINK_LENGTH) throw invalidLink();
|
|
38509
|
-
if (containsDisallowedLinkWhitespace(candidate)) throw invalidLink();
|
|
38510
|
-
let url2;
|
|
38511
|
-
try {
|
|
38512
|
-
url2 = new URL(candidate);
|
|
38513
|
-
} catch {
|
|
38514
|
-
throw invalidLink();
|
|
38515
|
-
}
|
|
38516
|
-
if (url2.protocol !== ACCESS_LINK_SCHEME || url2.username || url2.password || url2.hash) throw invalidLink();
|
|
38517
|
-
if (url2.hostname !== ACCESS_LINK_HOST || url2.port !== "" || url2.pathname !== "") throw invalidLink();
|
|
38518
|
-
const keys = [...url2.searchParams.keys()];
|
|
38519
|
-
if (keys.length !== 1 || keys[0] !== "code") throw invalidLink();
|
|
38520
|
-
return readPayload(decodePayload(url2.searchParams.get("code") ?? ""));
|
|
38521
|
-
}
|
|
38522
|
-
function decodePayload(code) {
|
|
38523
|
-
if (!/^[A-Za-z0-9_-]+$/u.test(code)) throw invalidLink();
|
|
38524
|
-
let text;
|
|
38525
|
-
try {
|
|
38526
|
-
text = new TextDecoder("utf-8", { fatal: true }).decode(fromBase64Url(code));
|
|
38527
|
-
} catch {
|
|
38528
|
-
throw invalidLink();
|
|
38529
|
-
}
|
|
38530
|
-
try {
|
|
38531
|
-
return JSON.parse(text);
|
|
38532
|
-
} catch {
|
|
38533
|
-
throw invalidLink();
|
|
38534
|
-
}
|
|
38535
|
-
}
|
|
38536
|
-
function readPayload(value) {
|
|
38537
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) throw invalidLink();
|
|
38538
|
-
const entry = value;
|
|
38539
|
-
const keys = Object.keys(entry);
|
|
38540
|
-
if (keys.length !== PAYLOAD_KEYS.length || !PAYLOAD_KEYS.every((key) => keys.includes(key))) throw invalidLink();
|
|
38541
|
-
if (entry.v !== ACCESS_LINK_VERSION) throw invalidLink();
|
|
38542
|
-
if (typeof entry.endpoint !== "string" || typeof entry.token !== "string" || typeof entry.fingerprint !== "string" || typeof entry.label !== "string") throw invalidLink();
|
|
38543
|
-
const endpoint = readEndpoint(entry.endpoint);
|
|
38544
|
-
const token = entry.token;
|
|
38545
|
-
const fingerprint = normalizeFingerprint(entry.fingerprint);
|
|
38546
|
-
if (!ACCESS_TOKEN.test(token) || !CERTIFICATE_FINGERPRINT.test(fingerprint)) throw invalidLink();
|
|
38547
|
-
const label = sanitizeAccessLabel(entry.label);
|
|
38548
|
-
if (label.length === 0) throw invalidLink();
|
|
38549
|
-
return {
|
|
38550
|
-
origin: endpoint.origin,
|
|
38551
|
-
hostname: pinHostname(endpoint.hostname),
|
|
38552
|
-
port: endpoint.port,
|
|
38553
|
-
label,
|
|
38554
|
-
consoleUrl: new URL("/console/", endpoint.origin).toString(),
|
|
38555
|
-
joinUrl: new URL(ACCESS_JOIN_PATH, endpoint.origin).toString(),
|
|
38556
|
-
token,
|
|
38557
|
-
fingerprint
|
|
38558
|
-
};
|
|
38559
|
-
}
|
|
38560
|
-
function readEndpoint(value) {
|
|
38561
|
-
let url2;
|
|
38562
|
-
try {
|
|
38563
|
-
url2 = new URL(value);
|
|
38564
|
-
} catch {
|
|
38565
|
-
throw invalidLink();
|
|
38566
|
-
}
|
|
38567
|
-
if (url2.protocol !== "https:" || url2.username || url2.password || url2.search || url2.hash) throw invalidLink();
|
|
38568
|
-
if (url2.pathname !== "/" && url2.pathname !== "") throw invalidLink();
|
|
38569
|
-
if (url2.hostname.length === 0) throw invalidLink();
|
|
38570
|
-
const port = url2.port === "" ? 443 : Number(url2.port);
|
|
38571
|
-
if (!Number.isSafeInteger(port) || port < 1 || port > 65535) throw invalidLink();
|
|
38572
|
-
return { origin: url2.origin, hostname: url2.hostname, port };
|
|
38573
|
-
}
|
|
38574
|
-
function pinHostname(hostname5) {
|
|
38575
|
-
const unwrapped = hostname5.startsWith("[") && hostname5.endsWith("]") ? hostname5.slice(1, -1) : hostname5;
|
|
38576
|
-
return unwrapped.toLowerCase();
|
|
38577
|
-
}
|
|
38578
|
-
function normalizeFingerprint(value) {
|
|
38579
|
-
return value.replace(/[^0-9a-fA-F]/gu, "").toUpperCase();
|
|
38580
|
-
}
|
|
38581
|
-
function sanitizeAccessLabel(value) {
|
|
38582
|
-
return Array.from(value).filter((character) => !isDisallowedAccessLabelCharacter(character.codePointAt(0))).join("").replace(/\s+/gu, " ").trim().slice(0, MAX_ACCESS_LABEL_LENGTH);
|
|
38583
|
-
}
|
|
38584
|
-
function containsDisallowedLinkWhitespace(value) {
|
|
38585
|
-
for (const character of value) {
|
|
38586
|
-
const codePoint = character.codePointAt(0);
|
|
38587
|
-
if (codePoint <= 31 || codePoint === 127 || isWhitespaceCharacter(character)) return true;
|
|
38588
|
-
}
|
|
38589
|
-
return false;
|
|
38590
|
-
}
|
|
38591
|
-
function isWhitespaceCharacter(character) {
|
|
38592
|
-
return character.trim().length === 0;
|
|
38593
|
-
}
|
|
38594
|
-
function isDisallowedAccessLabelCharacter(codePoint) {
|
|
38595
|
-
return codePoint <= 31 || codePoint >= 127 && codePoint <= 159 || codePoint >= 8203 && codePoint <= 8207 || codePoint === 8232 || codePoint === 8233 || codePoint >= 8234 && codePoint <= 8238 || codePoint >= 8294 && codePoint <= 8297;
|
|
38596
|
-
}
|
|
38597
|
-
function toBase64Url(bytes) {
|
|
38598
|
-
let encoded = "";
|
|
38599
|
-
for (let index = 0; index < bytes.length; index += 3) {
|
|
38600
|
-
const first = bytes[index];
|
|
38601
|
-
const second = bytes[index + 1];
|
|
38602
|
-
const third = bytes[index + 2];
|
|
38603
|
-
encoded += BASE64_URL_ALPHABET[first >> 2];
|
|
38604
|
-
encoded += BASE64_URL_ALPHABET[(first & 3) << 4 | (second ?? 0) >> 4];
|
|
38605
|
-
if (second !== void 0) encoded += BASE64_URL_ALPHABET[(second & 15) << 2 | (third ?? 0) >> 6];
|
|
38606
|
-
if (third !== void 0) encoded += BASE64_URL_ALPHABET[third & 63];
|
|
38607
|
-
}
|
|
38608
|
-
return encoded;
|
|
38609
|
-
}
|
|
38610
|
-
function fromBase64Url(value) {
|
|
38611
|
-
if (value.length % 4 === 1) throw invalidLink();
|
|
38612
|
-
const bytes = new Uint8Array(Math.floor(value.length * 6 / 8));
|
|
38613
|
-
let buffer = 0;
|
|
38614
|
-
let bits = 0;
|
|
38615
|
-
let offset = 0;
|
|
38616
|
-
for (const character of value) {
|
|
38617
|
-
const decoded = BASE64_URL_DECODE[character.charCodeAt(0)] ?? -1;
|
|
38618
|
-
if (decoded < 0) throw invalidLink();
|
|
38619
|
-
buffer = buffer << 6 | decoded;
|
|
38620
|
-
bits += 6;
|
|
38621
|
-
if (bits >= 8) {
|
|
38622
|
-
bits -= 8;
|
|
38623
|
-
bytes[offset] = buffer >> bits & 255;
|
|
38624
|
-
offset += 1;
|
|
38625
|
-
}
|
|
38626
|
-
}
|
|
38627
|
-
if (bits > 0 && (buffer & (1 << bits) - 1) !== 0) throw invalidLink();
|
|
38628
|
-
return bytes;
|
|
38629
|
-
}
|
|
38630
|
-
function createBase64UrlDecodeTable() {
|
|
38631
|
-
const table = new Int16Array(128);
|
|
38632
|
-
table.fill(-1);
|
|
38633
|
-
for (let index = 0; index < BASE64_URL_ALPHABET.length; index += 1) {
|
|
38634
|
-
table[BASE64_URL_ALPHABET.charCodeAt(index)] = index;
|
|
38635
|
-
}
|
|
38636
|
-
return table;
|
|
38637
|
-
}
|
|
38638
|
-
function invalidLink() {
|
|
38639
|
-
return new Error("pairing_target_invalid");
|
|
38640
|
-
}
|
|
38641
|
-
|
|
38642
|
-
// core/host/remote-identity.ts
|
|
38643
38768
|
var CERTIFICATE_FILE = "identity-cert.pem";
|
|
38644
38769
|
var KEY_FILE = "identity-key.pem";
|
|
38645
38770
|
var META_FILE = "identity.json";
|
|
@@ -38647,7 +38772,7 @@ var VALIDITY_DAYS = 825;
|
|
|
38647
38772
|
var RENEW_BEFORE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
38648
38773
|
function createRemoteIdentityStore(consoleDir, deps = {}) {
|
|
38649
38774
|
const storage = createRemoteStorage(consoleDir, deps);
|
|
38650
|
-
const readFile7 = deps.readFile ?? ((file2) =>
|
|
38775
|
+
const readFile7 = deps.readFile ?? ((file2) => fs10__default.readFileSync(file2, "utf8"));
|
|
38651
38776
|
const generate = deps.generate ?? generateSelfSignedCertificate;
|
|
38652
38777
|
const now = deps.now ?? Date.now;
|
|
38653
38778
|
function read() {
|
|
@@ -38717,7 +38842,7 @@ var MAX_HOSTS = 64;
|
|
|
38717
38842
|
var HANDOFF_TTL_MS = 5 * 60 * 1e3;
|
|
38718
38843
|
function createRemoteHostStore(consoleDir, deps = {}) {
|
|
38719
38844
|
const storage = createRemoteStorage(consoleDir, deps);
|
|
38720
|
-
const readFile7 = deps.readFile ?? ((file2) =>
|
|
38845
|
+
const readFile7 = deps.readFile ?? ((file2) => fs10__default.readFileSync(file2, "utf8"));
|
|
38721
38846
|
const now = deps.now ?? Date.now;
|
|
38722
38847
|
const randomId = deps.randomId ?? (() => crypto5.randomUUID());
|
|
38723
38848
|
const pending = /* @__PURE__ */ new Map();
|
|
@@ -38868,32 +38993,6 @@ function normalizeRemoteJoinSource(address) {
|
|
|
38868
38993
|
const mapped = /^::ffff:(\d{1,3}(?:\.\d{1,3}){3})$/iu.exec(address);
|
|
38869
38994
|
return mapped === null ? address : mapped[1];
|
|
38870
38995
|
}
|
|
38871
|
-
var REMOTE_PROBE_TIMEOUT_MS = 6e3;
|
|
38872
|
-
function probeRemoteIdentity(hostname5, port, expected, timeoutMs = REMOTE_PROBE_TIMEOUT_MS) {
|
|
38873
|
-
return new Promise((resolve3) => {
|
|
38874
|
-
const settle = (result) => {
|
|
38875
|
-
socket.destroy();
|
|
38876
|
-
resolve3(result);
|
|
38877
|
-
};
|
|
38878
|
-
const socket = tls.connect({
|
|
38879
|
-
host: hostname5,
|
|
38880
|
-
port,
|
|
38881
|
-
rejectUnauthorized: false,
|
|
38882
|
-
// IP 리터럴에는 SNI를 붙이지 않는다 — 규격상 SNI는 이름에만 쓴다.
|
|
38883
|
-
...net2.isIP(hostname5) === 0 ? { servername: hostname5 } : {}
|
|
38884
|
-
}, () => {
|
|
38885
|
-
const certificate = socket.getPeerX509Certificate();
|
|
38886
|
-
if (!certificate) {
|
|
38887
|
-
settle({ state: "unreachable" });
|
|
38888
|
-
return;
|
|
38889
|
-
}
|
|
38890
|
-
const presented = normalizeFingerprint(certificate.fingerprint256);
|
|
38891
|
-
settle(presented === normalizeFingerprint(expected) ? { state: "match" } : { state: "mismatch", presented });
|
|
38892
|
-
});
|
|
38893
|
-
socket.setTimeout(timeoutMs, () => settle({ state: "unreachable" }));
|
|
38894
|
-
socket.on("error", () => settle({ state: "unreachable" }));
|
|
38895
|
-
});
|
|
38896
|
-
}
|
|
38897
38996
|
var WSL_ROOT = "\\\\wsl.localhost";
|
|
38898
38997
|
var WSL_TMP = "tmp";
|
|
38899
38998
|
var LOCK_FILE = "console.lock";
|
|
@@ -38906,7 +39005,7 @@ function isUsableDistroName(name) {
|
|
|
38906
39005
|
var WSL_LIST_TIMEOUT_MS = 3e3;
|
|
38907
39006
|
var REACHABLE_TIMEOUT_MS = 700;
|
|
38908
39007
|
async function listLocalConsoles(deps = {}) {
|
|
38909
|
-
const fileSystem = deps.fileSystem ??
|
|
39008
|
+
const fileSystem = deps.fileSystem ?? fs10__default;
|
|
38910
39009
|
const isAlive = deps.isAlive ?? processIsAlive;
|
|
38911
39010
|
const entries = [];
|
|
38912
39011
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -39016,7 +39115,7 @@ function portAnswers(origin) {
|
|
|
39016
39115
|
resolve3(false);
|
|
39017
39116
|
return;
|
|
39018
39117
|
}
|
|
39019
|
-
const socket =
|
|
39118
|
+
const socket = net3.connect({ host: url2.hostname, port: Number(url2.port) }, () => {
|
|
39020
39119
|
socket.destroy();
|
|
39021
39120
|
resolve3(true);
|
|
39022
39121
|
});
|
|
@@ -39073,14 +39172,14 @@ function parseFleetPluginManifest(value) {
|
|
|
39073
39172
|
};
|
|
39074
39173
|
}
|
|
39075
39174
|
function discoverPluginRoot(root, builtInDistRoot, external) {
|
|
39076
|
-
if (!
|
|
39077
|
-
const entries =
|
|
39175
|
+
if (!fs10__default.existsSync(root)) return [];
|
|
39176
|
+
const entries = fs10__default.readdirSync(root, { withFileTypes: true });
|
|
39078
39177
|
const plugins = [];
|
|
39079
39178
|
for (const entry of entries) {
|
|
39080
39179
|
if (!entry.isDirectory() || entry.name === "shared") continue;
|
|
39081
39180
|
const pluginRoot = path18__default.join(root, entry.name);
|
|
39082
39181
|
const manifestPath = path18__default.join(pluginRoot, "plugin.json");
|
|
39083
|
-
if (!
|
|
39182
|
+
if (!fs10__default.existsSync(manifestPath)) continue;
|
|
39084
39183
|
const manifest = readManifest(manifestPath);
|
|
39085
39184
|
if (!manifest) continue;
|
|
39086
39185
|
const clientEntry = resolveOptionalManifestEntry(pluginRoot, manifest.client, "client");
|
|
@@ -39092,14 +39191,14 @@ function discoverPluginRoot(root, builtInDistRoot, external) {
|
|
|
39092
39191
|
return plugins;
|
|
39093
39192
|
}
|
|
39094
39193
|
function discoverDistPluginRoot(root) {
|
|
39095
|
-
if (!
|
|
39096
|
-
const entries =
|
|
39194
|
+
if (!fs10__default.existsSync(root)) return [];
|
|
39195
|
+
const entries = fs10__default.readdirSync(root, { withFileTypes: true });
|
|
39097
39196
|
const plugins = [];
|
|
39098
39197
|
for (const entry of entries) {
|
|
39099
39198
|
if (!entry.isDirectory() || entry.name === "shared") continue;
|
|
39100
39199
|
const pluginRoot = path18__default.join(root, entry.name);
|
|
39101
39200
|
const manifestPath = path18__default.join(pluginRoot, "plugin.json");
|
|
39102
|
-
const manifest =
|
|
39201
|
+
const manifest = fs10__default.existsSync(manifestPath) ? readManifest(manifestPath) : readDistPluginManifest(entry.name);
|
|
39103
39202
|
if (!manifest) continue;
|
|
39104
39203
|
const clientEntry = resolveOptionalManifestEntry(pluginRoot, manifest.client, "client");
|
|
39105
39204
|
if (clientEntry === false) continue;
|
|
@@ -39111,7 +39210,7 @@ function discoverDistPluginRoot(root) {
|
|
|
39111
39210
|
}
|
|
39112
39211
|
function readManifest(manifestPath) {
|
|
39113
39212
|
try {
|
|
39114
|
-
const manifest = parseFleetPluginManifest(JSON.parse(
|
|
39213
|
+
const manifest = parseFleetPluginManifest(JSON.parse(fs10__default.readFileSync(manifestPath, "utf8")));
|
|
39115
39214
|
if (!manifest) console.warn(`[fleet-console] Plugin manifest skipped: invalid manifest at ${manifestPath}`);
|
|
39116
39215
|
return manifest;
|
|
39117
39216
|
} catch (error51) {
|
|
@@ -39126,10 +39225,10 @@ function resolveRoutesEntry(pluginRoot, manifest, builtInDistRoot) {
|
|
|
39126
39225
|
if (manifestRoute2) return manifestRoute2;
|
|
39127
39226
|
}
|
|
39128
39227
|
const manifestRoute = path18__default.join(pluginRoot, "routes.ts");
|
|
39129
|
-
if (
|
|
39228
|
+
if (fs10__default.existsSync(manifestRoute)) return manifestRoute;
|
|
39130
39229
|
if (!builtInDistRoot) return null;
|
|
39131
39230
|
const builtRoute = path18__default.join(builtInDistRoot, manifest.id, "routes.mjs");
|
|
39132
|
-
return
|
|
39231
|
+
return fs10__default.existsSync(builtRoute) ? builtRoute : null;
|
|
39133
39232
|
}
|
|
39134
39233
|
function resolveDistRoutesEntry(pluginRoot, manifest) {
|
|
39135
39234
|
const routesEntry = resolveOptionalManifestEntry(pluginRoot, manifest.routes ?? "routes.mjs", "routes");
|
|
@@ -39143,9 +39242,9 @@ function resolveOptionalManifestEntry(pluginRoot, entryPath, label) {
|
|
|
39143
39242
|
return false;
|
|
39144
39243
|
}
|
|
39145
39244
|
const candidate = path18__default.resolve(pluginRoot, entryPath);
|
|
39146
|
-
if (!
|
|
39147
|
-
const rootRealpath =
|
|
39148
|
-
const entryRealpath =
|
|
39245
|
+
if (!fs10__default.existsSync(candidate)) return null;
|
|
39246
|
+
const rootRealpath = fs10__default.realpathSync.native(pluginRoot);
|
|
39247
|
+
const entryRealpath = fs10__default.realpathSync.native(candidate);
|
|
39149
39248
|
if (!isSubpath(rootRealpath, entryRealpath)) {
|
|
39150
39249
|
console.warn(`[fleet-console] Plugin ${label} entry skipped: path escapes plugin root ${entryPath}`);
|
|
39151
39250
|
return false;
|
|
@@ -40073,7 +40172,7 @@ function tryServeStaticConsole(req, res, pathname, consoleRoot, getActiveTheme)
|
|
|
40073
40172
|
return true;
|
|
40074
40173
|
}
|
|
40075
40174
|
try {
|
|
40076
|
-
const data =
|
|
40175
|
+
const data = fs10__default.readFileSync(absolutePath);
|
|
40077
40176
|
const contentType = MIME_TYPES[path18__default.extname(absolutePath)] ?? "application/octet-stream";
|
|
40078
40177
|
res.writeHead(200, withSecurityHeaders2({ "Content-Type": contentType }));
|
|
40079
40178
|
if (req.method === "HEAD") {
|
|
@@ -40094,7 +40193,7 @@ function tryServeStaticConsole(req, res, pathname, consoleRoot, getActiveTheme)
|
|
|
40094
40193
|
}
|
|
40095
40194
|
function serveFallbackIndex(req, res, consoleRoot, getActiveTheme) {
|
|
40096
40195
|
try {
|
|
40097
|
-
const data =
|
|
40196
|
+
const data = fs10__default.readFileSync(path18__default.join(consoleRoot, "index.html"));
|
|
40098
40197
|
res.writeHead(200, withSecurityHeaders2({ "Content-Type": MIME_TYPES[".html"] }));
|
|
40099
40198
|
if (req.method === "HEAD") {
|
|
40100
40199
|
res.end();
|
|
@@ -40141,7 +40240,7 @@ function consoleUpdateProgressPath(dataDir) {
|
|
|
40141
40240
|
return path18__default.join(dataDir, CONSOLE_UPDATE_PROGRESS_FILE);
|
|
40142
40241
|
}
|
|
40143
40242
|
function readConsoleUpdateProgress(dataDir, deps = {}) {
|
|
40144
|
-
const readFile7 = deps.readFile ?? ((filePath) =>
|
|
40243
|
+
const readFile7 = deps.readFile ?? ((filePath) => fs10__default.readFileSync(filePath, "utf8"));
|
|
40145
40244
|
const now = deps.now ?? Date.now;
|
|
40146
40245
|
let raw;
|
|
40147
40246
|
try {
|
|
@@ -40201,10 +40300,10 @@ function isConsoleUpdatePhase(value) {
|
|
|
40201
40300
|
}
|
|
40202
40301
|
function writeConsoleUpdateProgress(dataDir, record4, deps = {}) {
|
|
40203
40302
|
const makeDir = deps.makeDir ?? ((dirPath, options) => {
|
|
40204
|
-
|
|
40303
|
+
fs10__default.mkdirSync(dirPath, options);
|
|
40205
40304
|
});
|
|
40206
40305
|
const writeFile5 = deps.writeFile ?? ((filePath, content, options) => {
|
|
40207
|
-
|
|
40306
|
+
fs10__default.writeFileSync(filePath, content, { mode: options.mode });
|
|
40208
40307
|
});
|
|
40209
40308
|
makeDir(dataDir, { recursive: true, mode: 448 });
|
|
40210
40309
|
writeFile5(consoleUpdateProgressPath(dataDir), JSON.stringify(record4, null, 2), { mode: PROGRESS_FILE_MODE });
|
|
@@ -40222,7 +40321,7 @@ function createConsoleUpdateApplyService(deps = {}) {
|
|
|
40222
40321
|
const childEnv = env.FLEET_CONSOLE_NO_SYSTEM_CA === "1" ? env : withNodeSystemCa(env);
|
|
40223
40322
|
const execPath = deps.execPath ?? process4.execPath;
|
|
40224
40323
|
const makeDir = deps.makeDir ?? ((dirPath, options) => {
|
|
40225
|
-
|
|
40324
|
+
fs10__default.mkdirSync(dirPath, options);
|
|
40226
40325
|
});
|
|
40227
40326
|
const now = deps.now ?? Date.now;
|
|
40228
40327
|
const processPid = deps.processPid ?? process4.pid;
|
|
@@ -40231,7 +40330,7 @@ function createConsoleUpdateApplyService(deps = {}) {
|
|
|
40231
40330
|
const spawnWorker = deps.spawnWorker ?? defaultSpawnWorker;
|
|
40232
40331
|
const tmpDir = deps.tmpDir ?? os4__default.tmpdir();
|
|
40233
40332
|
const writeFile5 = deps.writeFile ?? ((filePath, content, options) => {
|
|
40234
|
-
|
|
40333
|
+
fs10__default.writeFileSync(filePath, content, { mode: options.mode });
|
|
40235
40334
|
});
|
|
40236
40335
|
async function start(request) {
|
|
40237
40336
|
if (isManagedRuntimePackageRoot(request.currentPackageRoot)) throw new Error("managed_runtime_update_requires_relaunch");
|
|
@@ -40654,7 +40753,7 @@ function readEndpointPort(endpoint) {
|
|
|
40654
40753
|
function isManagedRuntimePackageRoot(packageRoot) {
|
|
40655
40754
|
if (path18__default.basename(packageRoot) !== "latest" || path18__default.basename(path18__default.dirname(packageRoot)) !== "console") return false;
|
|
40656
40755
|
try {
|
|
40657
|
-
return isDesktopResourceRootMarkerValid(
|
|
40756
|
+
return isDesktopResourceRootMarkerValid(fs10__default.readFileSync(path18__default.join(packageRoot, DESKTOP_RESOURCE_ROOT_MARKER), "utf8"));
|
|
40658
40757
|
} catch {
|
|
40659
40758
|
return false;
|
|
40660
40759
|
}
|
|
@@ -40705,7 +40804,7 @@ function defaultSpawnWorker(execPath, args, options) {
|
|
|
40705
40804
|
}
|
|
40706
40805
|
function resolveDefaultServerModulePath() {
|
|
40707
40806
|
const builtPath = fileURLToPath(new URL("../dist/cli.mjs", import.meta.url));
|
|
40708
|
-
if (
|
|
40807
|
+
if (fs10__default.existsSync(builtPath)) return builtPath;
|
|
40709
40808
|
const sourcePath = fileURLToPath(import.meta.url);
|
|
40710
40809
|
if (sourcePath.endsWith(".ts")) {
|
|
40711
40810
|
return sourcePath.replace(/update-apply\.ts$/, "cli.ts");
|
|
@@ -41151,8 +41250,8 @@ function createConsoleServer(deps = {}) {
|
|
|
41151
41250
|
unregisterTheaterWorkspaces: (theaterId) => codex.unregisterTheaterWorkspaces(theaterId),
|
|
41152
41251
|
validateTheaterRestore: async (theater) => {
|
|
41153
41252
|
try {
|
|
41154
|
-
const restoredRealpath = await
|
|
41155
|
-
const stat4 = await
|
|
41253
|
+
const restoredRealpath = await fs10__default.promises.realpath(theater.path);
|
|
41254
|
+
const stat4 = await fs10__default.promises.stat(restoredRealpath);
|
|
41156
41255
|
if (!stat4.isDirectory() || restoredRealpath !== theater.realpath || workspaceHash(restoredRealpath) !== theater.id) {
|
|
41157
41256
|
throw new Error("restore_conflict");
|
|
41158
41257
|
}
|
|
@@ -42942,7 +43041,7 @@ function resolveBuiltInPluginDiscoveryRoots(packageRoot) {
|
|
|
42942
43041
|
const packageRootRepo = path18__default.resolve(packageRoot, "..", "..");
|
|
42943
43042
|
const sourceRoot = path18__default.join(packageRootRepo, "runtime", "fleet-plugins");
|
|
42944
43043
|
return {
|
|
42945
|
-
...
|
|
43044
|
+
...fs10__default.existsSync(sourceRoot) ? { builtInSourceRoot: sourceRoot } : {},
|
|
42946
43045
|
builtInDistRoot: path18__default.join(packageRoot, "dist", "fleet-plugins")
|
|
42947
43046
|
};
|
|
42948
43047
|
}
|
|
@@ -43141,7 +43240,7 @@ function isAllowedTerminalOrigin(req, expectedOrigin) {
|
|
|
43141
43240
|
async function readPluginStorageJson(dataDir, pluginId, key) {
|
|
43142
43241
|
const file2 = resolvePluginStorageFile(dataDir, pluginId, key);
|
|
43143
43242
|
try {
|
|
43144
|
-
return JSON.parse(await
|
|
43243
|
+
return JSON.parse(await fs10__default.promises.readFile(file2, "utf8"));
|
|
43145
43244
|
} catch (error51) {
|
|
43146
43245
|
if (isNodeError(error51) && error51.code === "ENOENT") return null;
|
|
43147
43246
|
throw error51;
|
|
@@ -43149,8 +43248,8 @@ async function readPluginStorageJson(dataDir, pluginId, key) {
|
|
|
43149
43248
|
}
|
|
43150
43249
|
async function writePluginStorageJson(dataDir, pluginId, key, value) {
|
|
43151
43250
|
const file2 = resolvePluginStorageFile(dataDir, pluginId, key);
|
|
43152
|
-
await
|
|
43153
|
-
await
|
|
43251
|
+
await fs10__default.promises.mkdir(path18__default.dirname(file2), { recursive: true });
|
|
43252
|
+
await fs10__default.promises.writeFile(file2, JSON.stringify(value), "utf8");
|
|
43154
43253
|
}
|
|
43155
43254
|
function resolvePluginStorageFile(dataDir, pluginId, key) {
|
|
43156
43255
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(pluginId) || !/^[a-z0-9][a-z0-9._-]*$/i.test(key)) {
|
|
@@ -43161,18 +43260,6 @@ function resolvePluginStorageFile(dataDir, pluginId, key) {
|
|
|
43161
43260
|
function isNodeError(error51) {
|
|
43162
43261
|
return error51 instanceof Error && "code" in error51;
|
|
43163
43262
|
}
|
|
43164
|
-
function createConsoleStalePolicy(deps = {}) {
|
|
43165
|
-
const fsImpl = deps.fs ?? fs9__default;
|
|
43166
|
-
function isBuildStale(lock, buildFile) {
|
|
43167
|
-
try {
|
|
43168
|
-
return lock.startedAt < fsImpl.statSync(buildFile).mtimeMs;
|
|
43169
|
-
} catch (err) {
|
|
43170
|
-
if (err.code === "ENOENT") return false;
|
|
43171
|
-
throw err;
|
|
43172
|
-
}
|
|
43173
|
-
}
|
|
43174
|
-
return { isBuildStale };
|
|
43175
|
-
}
|
|
43176
43263
|
|
|
43177
43264
|
// core/host/console-lifecycle.ts
|
|
43178
43265
|
var FIXED_HOST = "127.0.0.1";
|
|
@@ -43467,7 +43554,7 @@ ${await runConsoleStatus()}
|
|
|
43467
43554
|
}
|
|
43468
43555
|
function resolveDefaultServerModulePath2() {
|
|
43469
43556
|
const builtPath = new URL("../dist/cli.mjs", import.meta.url).pathname;
|
|
43470
|
-
if (
|
|
43557
|
+
if (fs10__default.existsSync(builtPath)) return builtPath;
|
|
43471
43558
|
return fileURLToPath(import.meta.url);
|
|
43472
43559
|
}
|
|
43473
43560
|
function readHookSessionId(env) {
|
|
@@ -43526,7 +43613,7 @@ function readStdinBestEffort() {
|
|
|
43526
43613
|
function isCliDirectRun(argv1, moduleUrl = import.meta.url) {
|
|
43527
43614
|
if (!argv1) return false;
|
|
43528
43615
|
try {
|
|
43529
|
-
return
|
|
43616
|
+
return fs10__default.realpathSync(path18__default.resolve(argv1)) === fs10__default.realpathSync(fileURLToPath(moduleUrl));
|
|
43530
43617
|
} catch {
|
|
43531
43618
|
return false;
|
|
43532
43619
|
}
|