@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.
Files changed (67) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +13 -0
  3. package/dist/cli.mjs +437 -350
  4. package/dist/client/assets/{_baseUniq--GYoaiDn.js → _baseUniq-D_AjNlwO.js} +1 -1
  5. package/dist/client/assets/{arc-ioTPutEb.js → arc-DiscagS3.js} +1 -1
  6. package/dist/client/assets/{architectureDiagram-Q4EWVU46-DLfH6cdt.js → architectureDiagram-Q4EWVU46-PGPwULb9.js} +1 -1
  7. package/dist/client/assets/{blockDiagram-DXYQGD6D-ZM6X_dlD.js → blockDiagram-DXYQGD6D-DLexJaxZ.js} +1 -1
  8. package/dist/client/assets/{c4Diagram-AHTNJAMY-DDPTnZGS.js → c4Diagram-AHTNJAMY-D9Ye73ny.js} +1 -1
  9. package/dist/client/assets/channel-CR5OWwKU.js +1 -0
  10. package/dist/client/assets/{chunk-4BX2VUAB-0ShpcAto.js → chunk-4BX2VUAB-B7YgJYL4.js} +1 -1
  11. package/dist/client/assets/{chunk-4TB4RGXK-CvMAl5bA.js → chunk-4TB4RGXK-CEEQcTWi.js} +1 -1
  12. package/dist/client/assets/{chunk-55IACEB6-CgV8t6TS.js → chunk-55IACEB6-B8AcnGT7.js} +1 -1
  13. package/dist/client/assets/{chunk-EDXVE4YY-DQkbYjs9.js → chunk-EDXVE4YY-DjZ88S2h.js} +1 -1
  14. package/dist/client/assets/{chunk-FMBD7UC4-D4Pm3UM-.js → chunk-FMBD7UC4-io3C2TDz.js} +1 -1
  15. package/dist/client/assets/{chunk-OYMX7WX6-BrWIgOQ6.js → chunk-OYMX7WX6-s0DPD-0B.js} +1 -1
  16. package/dist/client/assets/{chunk-QZHKN3VN-BC-GEuDl.js → chunk-QZHKN3VN-DGcrSXIn.js} +1 -1
  17. package/dist/client/assets/{chunk-YZCP3GAM-Dst--QPc.js → chunk-YZCP3GAM-Dp1DewA_.js} +1 -1
  18. package/dist/client/assets/classDiagram-6PBFFD2Q-BxfrF-vv.js +1 -0
  19. package/dist/client/assets/classDiagram-v2-HSJHXN6E-BxfrF-vv.js +1 -0
  20. package/dist/client/assets/clone-BH8tX1wM.js +1 -0
  21. package/dist/client/assets/{cose-bilkent-S5V4N54A-D87Ru6Nw.js → cose-bilkent-S5V4N54A-D9PZkL8M.js} +1 -1
  22. package/dist/client/assets/{dagre-KV5264BT-CUG8AIPS.js → dagre-KV5264BT-M-8Bl0QN.js} +1 -1
  23. package/dist/client/assets/{diagram-5BDNPKRD-DrhhXUdy.js → diagram-5BDNPKRD-CbFVI18N.js} +1 -1
  24. package/dist/client/assets/{diagram-G4DWMVQ6-DgGQFVlD.js → diagram-G4DWMVQ6-Bofydoge.js} +1 -1
  25. package/dist/client/assets/{diagram-MMDJMWI5-DEyFyzNg.js → diagram-MMDJMWI5-BZQV1jqh.js} +1 -1
  26. package/dist/client/assets/{diagram-TYMM5635-ari8AKd5.js → diagram-TYMM5635-v_pX67fP.js} +1 -1
  27. package/dist/client/assets/{erDiagram-SMLLAGMA-Aywt-vx8.js → erDiagram-SMLLAGMA-DA8k24I7.js} +1 -1
  28. package/dist/client/assets/{flowDiagram-DWJPFMVM-FO46vDh_.js → flowDiagram-DWJPFMVM-CA3Jm5mj.js} +1 -1
  29. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-C0m3r6C5.js → ganttDiagram-T4ZO3ILL-B6YPlixu.js} +1 -1
  30. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-CTUKGfIc.js → gitGraphDiagram-UUTBAWPF-3BjoRhTq.js} +1 -1
  31. package/dist/client/assets/{graph-PzhNFXt_.js → graph-CjQR1bpo.js} +1 -1
  32. package/dist/client/assets/index-B21kBRWF.js +467 -0
  33. package/dist/client/assets/{index-Bcc3Exng.css → index-DKMT7UVt.css} +1 -1
  34. package/dist/client/assets/{infoDiagram-42DDH7IO-CFry6eYn.js → infoDiagram-42DDH7IO-Cz8NXcwy.js} +1 -1
  35. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-BBJvVjTh.js → ishikawaDiagram-UXIWVN3A-dJiEc4oW.js} +1 -1
  36. package/dist/client/assets/{journeyDiagram-VCZTEJTY-glHJeITG.js → journeyDiagram-VCZTEJTY-D0e9gSNl.js} +1 -1
  37. package/dist/client/assets/{kanban-definition-6JOO6SKY-Dp7IjAmS.js → kanban-definition-6JOO6SKY-DJ-tyN1D.js} +1 -1
  38. package/dist/client/assets/{layout-PhtOMDDE.js → layout-By8oq65c.js} +1 -1
  39. package/dist/client/assets/{linear-B3pjuRWl.js → linear-Bgvt1y1F.js} +1 -1
  40. package/dist/client/assets/{mermaid.core-DDurtDWt.js → mermaid.core-BzUsxrJd.js} +4 -4
  41. package/dist/client/assets/{min-ZS3oLuaq.js → min-C5LKMAsm.js} +1 -1
  42. package/dist/client/assets/{mindmap-definition-QFDTVHPH-D67iQI4K.js → mindmap-definition-QFDTVHPH-BVEgUjPO.js} +1 -1
  43. package/dist/client/assets/{pieDiagram-DEJITSTG-B95nftHb.js → pieDiagram-DEJITSTG-H6ERErU1.js} +1 -1
  44. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-BbBVDSwm.js → quadrantDiagram-34T5L4WZ-B3Y2XYCJ.js} +1 -1
  45. package/dist/client/assets/{requirementDiagram-MS252O5E-Dbtcs04o.js → requirementDiagram-MS252O5E-NgcHrVQM.js} +1 -1
  46. package/dist/client/assets/{sankeyDiagram-XADWPNL6-BuqmxYyX.js → sankeyDiagram-XADWPNL6-DtmwsCxU.js} +1 -1
  47. package/dist/client/assets/{sequenceDiagram-FGHM5R23-DmLihX3U.js → sequenceDiagram-FGHM5R23-Rd0S2w1n.js} +1 -1
  48. package/dist/client/assets/{stateDiagram-FHFEXIEX-D3Z_iYXj.js → stateDiagram-FHFEXIEX-Cpag_fk7.js} +1 -1
  49. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Cbjujcp-.js +1 -0
  50. package/dist/client/assets/{timeline-definition-GMOUNBTQ-witmATQr.js → timeline-definition-GMOUNBTQ-C8yS2XLP.js} +1 -1
  51. package/dist/client/assets/{vennDiagram-DHZGUBPP-BDI4z0F-.js → vennDiagram-DHZGUBPP-Bj7SvZFm.js} +1 -1
  52. package/dist/client/assets/{wardley-RL74JXVD-oYmBD5eO.js → wardley-RL74JXVD-DZhhw2v9.js} +1 -1
  53. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-DhnyRjSq.js → wardleyDiagram-NUSXRM2D-DgpBbIN3.js} +1 -1
  54. package/dist/client/assets/{xychartDiagram-5P7HB3ND-DUY-bU_6.js → xychartDiagram-5P7HB3ND-CUq82Sal.js} +1 -1
  55. package/dist/client/index.html +2 -2
  56. package/dist/fleet-plugins/ledger/routes.mjs +103 -16
  57. package/dist/fleet-plugins/quota/routes.mjs +662 -148
  58. package/dist/fleet-plugins/scuttlebutt/routes.mjs +103 -16
  59. package/dist/fleet-plugins/terminal/routes.mjs +1394 -488
  60. package/dist/fleet.mjs +3468 -1329
  61. package/package.json +1 -1
  62. package/dist/client/assets/channel-BvAoE0IP.js +0 -1
  63. package/dist/client/assets/classDiagram-6PBFFD2Q-BeVFxENS.js +0 -1
  64. package/dist/client/assets/classDiagram-v2-HSJHXN6E-BeVFxENS.js +0 -1
  65. package/dist/client/assets/clone-TnYsvJuQ.js +0 -1
  66. package/dist/client/assets/index-DkOT93yC.js +0 -467
  67. 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 fs9 from 'node:fs';
3
- import fs9__default, { realpathSync, accessSync, constants as constants$1, existsSync, lstatSync } from 'node:fs';
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 net2 from 'node:net';
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 ?? fs9__default;
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, fs9__default.constants.O_CREAT | fs9__default.constants.O_EXCL | fs9__default.constants.O_WRONLY, LOCK_FILE_MODE);
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 = fs9.constants.O_NOFOLLOW ?? 0;
424
+ var NOFOLLOW_FLAG = fs10.constants.O_NOFOLLOW ?? 0;
413
425
  function safeLstat(targetPath) {
414
426
  try {
415
- return fs9.lstatSync(targetPath);
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
- fs9.chmodSync(dirPath, SECURE_DIR_MODE);
441
+ fs10.chmodSync(dirPath, SECURE_DIR_MODE);
430
442
  return;
431
443
  }
432
- fs9.mkdirSync(dirPath, { recursive: true, mode: SECURE_DIR_MODE });
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
- fs9.chmodSync(dirPath, SECURE_DIR_MODE);
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
- fs9.writeFileSync(tempPath, content, { encoding: "utf-8", flag: "wx", mode });
475
+ fs10.writeFileSync(tempPath, content, { encoding: "utf-8", flag: "wx", mode });
464
476
  tempCreated = true;
465
477
  if (doFsync) {
466
- const fd = fs9.openSync(tempPath, "r");
478
+ const fd = fs10.openSync(tempPath, "r");
467
479
  try {
468
480
  fsyncSyncBestEffort(fd);
469
481
  } finally {
470
- fs9.closeSync(fd);
482
+ fs10.closeSync(fd);
471
483
  }
472
484
  }
473
- fs9.renameSync(tempPath, filePath);
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
- fs9.unlinkSync(tempPath);
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 = fs9.readdirSync(dir);
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 = fs9.lstatSync(tempPath);
517
+ const stat4 = fs10.lstatSync(tempPath);
506
518
  if (stat4?.isFile() && !stat4.isSymbolicLink() && now - stat4.mtimeMs >= minAgeMs) {
507
- fs9.unlinkSync(tempPath);
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
- fs9.fsyncSync(fd);
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
- fs9.mkdirSync(deps.lockDir, { mode: 448 });
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
- fs9.rmSync(lockDir, { recursive: true, force: true });
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
- fs9.renameSync(lockDir, quarantineDir);
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
- fs9.rmSync(quarantineDir, { recursive: true, force: true });
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 = fs9.lstatSync(lockDir);
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
- fs9.writeFileSync(ownerPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
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(fs9.readFileSync(ownerPath, "utf-8")));
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
- fs9.renameSync(quarantineDir, lockDir);
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 = fs9.openSync(filePath, fs9.constants.O_RDONLY | NOFOLLOW_FLAG);
683
- if (!fs9.fstatSync(fd).isFile()) {
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(fs9.readFileSync(fd, "utf-8"));
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
- fs9.closeSync(fd);
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 (!fs9.existsSync(authPath)) return;
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 (!fs9.existsSync(authPath)) {
731
+ if (!fs10.existsSync(authPath)) {
720
732
  return void 0;
721
733
  }
722
- fd = fs9.openSync(authPath, fs9.constants.O_RDONLY | NOFOLLOW_FLAG);
723
- if (!fs9.fstatSync(fd).isFile()) {
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(fs9.readFileSync(fd, "utf-8"));
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
- fs9.closeSync(fd);
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 (!fs9.existsSync(authPath)) {
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 = fs9.existsSync(authPath) ? readAuthStoreFile(authPath) : {};
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 = fs9.lstatSync(filePath);
849
+ const stat4 = fs10.lstatSync(filePath);
838
850
  if (!stat4 || !stat4.isFile() || stat4.isSymbolicLink()) {
839
851
  return sanitize(void 0);
840
852
  }
841
- fd = fs9.openSync(filePath, fs9.constants.O_RDONLY | NOFOLLOW_FLAG);
842
- if (!fs9.fstatSync(fd).isFile()) {
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(fs9.readFileSync(fd, "utf-8")));
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
- fs9.closeSync(fd);
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
- fs9.mkdirSync(dir, { recursive: true });
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 fs9.realpathSync.native(path18.resolve(cwd));
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(fs9.readFileSync(identityPath, "utf8"));
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 = fs9__default.realpathSync(root);
1104
- const expectedRoot = fs9__default.realpathSync(expectedPackageRoot);
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 = fs9__default.readFileSync(markerPath, "utf8");
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 = fs9__default.realpathSync(root);
1127
+ resolvedRoot = fs10__default.realpathSync(root);
1116
1128
  } catch {
1117
1129
  throw new Error("desktop_development_resource_root_invalid");
1118
1130
  }
1119
- const expectedRoot = fs9__default.realpathSync(resolveDesktopProtocolPackageRoot());
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
- fs9.renameSync(staging2, destination);
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
- fs9.renameSync(staging, destination);
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 = fs9.lstatSync(target);
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 fs9.readdirSync(target, { withFileTypes: true })) {
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 = fs9.lstatSync(markerPath);
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(fs9.readFileSync(markerPath, "utf8"));
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
- fs9.mkdirSync(destination, { recursive: true });
11818
- for (const entry of fs9.readdirSync(source, { withFileTypes: true })) {
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 = fs9.lstatSync(from);
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
- fs9.symlinkSync(target, to, "file");
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
- fs9.copyFileSync(from, to);
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 = fs9.readlinkSync(linkPath);
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 = fs9.realpathSync(treeRoot);
11849
- canonicalTarget = fs9.realpathSync(linkPath);
11850
- targetStat = fs9.statSync(linkPath);
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") fs9.rmSync(target, { recursive: true, force: false });
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) fs9.rmSync(path18__default.join(workspacePath, name), { recursive: true, force: false });
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 fs9.readdirSync(workspacePath, { withFileTypes: true })) {
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 = fs9.lstatSync(residuePath);
11894
+ const residue = fs10.lstatSync(residuePath);
11883
11895
  if (MARKER_TEMP_REGEXP.test(entry.name) && residue.isFile() && !residue.isSymbolicLink()) {
11884
- fs9.unlinkSync(residuePath);
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
- fs9.writeFileSync(temporary, contents, { mode: 384 });
11910
+ fs10.writeFileSync(temporary, contents, { mode: 384 });
11899
11911
  syncFile(temporary);
11900
- fs9.renameSync(temporary, target);
11912
+ fs10.renameSync(temporary, target);
11901
11913
  }
11902
11914
  function fsyncBestEffort(fd) {
11903
11915
  try {
11904
- fs9.fsyncSync(fd);
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 = fs9.openSync(target, "r");
11923
+ const fd = fs10.openSync(target, "r");
11912
11924
  try {
11913
11925
  fsyncBestEffort(fd);
11914
11926
  } finally {
11915
- fs9.closeSync(fd);
11927
+ fs10.closeSync(fd);
11916
11928
  }
11917
11929
  }
11918
11930
  function syncDirectory(target) {
11919
11931
  if (!shouldSyncDirectoryForTest(process.platform)) return;
11920
- const fd = fs9.openSync(target, "r");
11932
+ const fd = fs10.openSync(target, "r");
11921
11933
  try {
11922
11934
  fsyncBestEffort(fd);
11923
11935
  } finally {
11924
- fs9.closeSync(fd);
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) => fs9__default.readFileSync(file2, "utf8"));
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 ?? fs9__default;
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) => fs9__default.readFileSync(file2, "utf8"));
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}//${net2.isIP(normalizedHost) === 6 ? `[${normalizedHost}]` : normalizedHost}:${serverPort}`);
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 (net2.isIP(unbracketed) === 6) {
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-21T00:00:00Z",
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: "flagship",
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: "light",
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: "light",
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: "light",
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: "light",
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
- if (!isRoutingAlias && model.providerModelId) {
35129
- const base = definition.models.find((candidate) => candidate.modelId === model.providerModelId);
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 fs9__default.realpathSync.native(resolved);
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 ?? fs9__default.promises.stat;
37178
- const opendir = deps.opendir ?? fs9__default.promises.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 ?? fs9__default.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 = fs9__default.statSync) {
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 net2.isIP(host) === 6 ? `[${host}]` : host;
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 (net2.isIP(unbracketed) === 6) {
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 (net2.isIP(entry.address) === 0) continue;
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 (net2.isIP(host) === 6) return null;
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 (!fs9__default.existsSync(stateFilePath) || fs9__default.existsSync(backupPath)) return;
38312
- fs9__default.copyFileSync(stateFilePath, backupPath);
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 (!fs9__default.existsSync(capturesDir)) return;
38646
+ if (!fs10__default.existsSync(capturesDir)) return;
38360
38647
  let migrated = false;
38361
38648
  let retained = false;
38362
38649
  try {
38363
- const entries = fs9__default.readdirSync(capturesDir);
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
- fs9__default.rmSync(capturesDir, { recursive: true, force: true });
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(fs9__default.readFileSync(filePath, "utf8"));
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) => fs9__default.readFileSync(file2, "utf8"));
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) => fs9__default.readFileSync(file2, "utf8"));
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) => fs9__default.readFileSync(file2, "utf8"));
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 ?? fs9__default;
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 = net2.connect({ host: url2.hostname, port: Number(url2.port) }, () => {
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 (!fs9__default.existsSync(root)) return [];
39077
- const entries = fs9__default.readdirSync(root, { withFileTypes: true });
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 (!fs9__default.existsSync(manifestPath)) continue;
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 (!fs9__default.existsSync(root)) return [];
39096
- const entries = fs9__default.readdirSync(root, { withFileTypes: true });
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 = fs9__default.existsSync(manifestPath) ? readManifest(manifestPath) : readDistPluginManifest(entry.name);
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(fs9__default.readFileSync(manifestPath, "utf8")));
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 (fs9__default.existsSync(manifestRoute)) return manifestRoute;
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 fs9__default.existsSync(builtRoute) ? builtRoute : null;
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 (!fs9__default.existsSync(candidate)) return null;
39147
- const rootRealpath = fs9__default.realpathSync.native(pluginRoot);
39148
- const entryRealpath = fs9__default.realpathSync.native(candidate);
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 = fs9__default.readFileSync(absolutePath);
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 = fs9__default.readFileSync(path18__default.join(consoleRoot, "index.html"));
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) => fs9__default.readFileSync(filePath, "utf8"));
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
- fs9__default.mkdirSync(dirPath, options);
40303
+ fs10__default.mkdirSync(dirPath, options);
40205
40304
  });
40206
40305
  const writeFile5 = deps.writeFile ?? ((filePath, content, options) => {
40207
- fs9__default.writeFileSync(filePath, content, { mode: options.mode });
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
- fs9__default.mkdirSync(dirPath, options);
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
- fs9__default.writeFileSync(filePath, content, { mode: options.mode });
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(fs9__default.readFileSync(path18__default.join(packageRoot, DESKTOP_RESOURCE_ROOT_MARKER), "utf8"));
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 (fs9__default.existsSync(builtPath)) return builtPath;
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 fs9__default.promises.realpath(theater.path);
41155
- const stat4 = await fs9__default.promises.stat(restoredRealpath);
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
- ...fs9__default.existsSync(sourceRoot) ? { builtInSourceRoot: sourceRoot } : {},
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 fs9__default.promises.readFile(file2, "utf8"));
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 fs9__default.promises.mkdir(path18__default.dirname(file2), { recursive: true });
43153
- await fs9__default.promises.writeFile(file2, JSON.stringify(value), "utf8");
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 (fs9__default.existsSync(builtPath)) return builtPath;
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 fs9__default.realpathSync(path18__default.resolve(argv1)) === fs9__default.realpathSync(fileURLToPath(moduleUrl));
43616
+ return fs10__default.realpathSync(path18__default.resolve(argv1)) === fs10__default.realpathSync(fileURLToPath(moduleUrl));
43530
43617
  } catch {
43531
43618
  return false;
43532
43619
  }