@dotobokuri/fleet-cli 1.5.1 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -141,8 +141,8 @@ var init_resolve_bin = __esm({
141
141
  // src/release.ts
142
142
  import { createRequire as createRequire2 } from "module";
143
143
  function readFleetCliRelease() {
144
- const requireFromHere = createRequire2(import.meta.url);
145
- const pkg = requireFromHere("../package.json");
144
+ const requireFromHere2 = createRequire2(import.meta.url);
145
+ const pkg = requireFromHere2("../package.json");
146
146
  const version3 = pkg.version ?? "";
147
147
  if (pkg.private === true) {
148
148
  return { channel: "local", version: version3 };
@@ -374,16 +374,58 @@ var init_check = __esm({
374
374
  }
375
375
  });
376
376
 
377
+ // src/update/stop-console.ts
378
+ import { spawn as spawn4 } from "child_process";
379
+ import { createRequire as createRequire3 } from "module";
380
+ async function stopRunningConsoleBeforeUpdate(io) {
381
+ let cliPath;
382
+ try {
383
+ cliPath = requireFromHere.resolve(CONSOLE_CLI_SPECIFIER);
384
+ } catch {
385
+ return;
386
+ }
387
+ io.stdout.write("Stopping the running Fleet Console to release file locks before update...\n");
388
+ await runConsoleStop2(cliPath, io);
389
+ }
390
+ function runConsoleStop2(cliPath, io) {
391
+ return new Promise((resolve2) => {
392
+ let settled = false;
393
+ const child = spawn4(process.execPath, [cliPath, "stop"], { stdio: "ignore" });
394
+ const timer = setTimeout(() => {
395
+ io.stderr.write("Fleet Console did not stop within the timeout; continuing with the update.\n");
396
+ child.kill();
397
+ finish();
398
+ }, STOP_TIMEOUT_MS);
399
+ const finish = () => {
400
+ if (settled) return;
401
+ settled = true;
402
+ clearTimeout(timer);
403
+ resolve2();
404
+ };
405
+ child.on("error", finish);
406
+ child.on("exit", finish);
407
+ });
408
+ }
409
+ var CONSOLE_CLI_SPECIFIER, STOP_TIMEOUT_MS, requireFromHere;
410
+ var init_stop_console = __esm({
411
+ "src/update/stop-console.ts"() {
412
+ "use strict";
413
+ CONSOLE_CLI_SPECIFIER = "@dotobokuri/fleet-console/cli";
414
+ STOP_TIMEOUT_MS = 15e3;
415
+ requireFromHere = createRequire3(import.meta.url);
416
+ }
417
+ });
418
+
377
419
  // src/update/installer.ts
378
420
  var installer_exports = {};
379
421
  __export(installer_exports, {
380
422
  __installerTestHooks: () => __installerTestHooks,
381
423
  runFleetUpdate: () => runFleetUpdate
382
424
  });
383
- import { spawn as spawn4 } from "child_process";
425
+ import { spawn as spawn5 } from "child_process";
384
426
  import { execFileSync } from "child_process";
385
427
  import { accessSync, constants as constants10, realpathSync as realpathSync8 } from "fs";
386
- import { createRequire as createRequire3 } from "module";
428
+ import { createRequire as createRequire4 } from "module";
387
429
  import path25 from "path";
388
430
  async function runFleetUpdate(io) {
389
431
  const release2 = readFleetCliRelease();
@@ -412,6 +454,7 @@ async function runFleetUpdate(io) {
412
454
  io.stdout.write(`Updating Fleet packages with ${target.manager.command} (${versionOrChannel})...
413
455
  `);
414
456
  }
457
+ await stopRunningConsoleBeforeUpdate(io);
415
458
  const status = await installFleetPackages(target.manager, versionOrChannel, io);
416
459
  if (status !== 0) {
417
460
  io.stderr.write(`Fleet update did not complete. You can run this manually:
@@ -469,11 +512,11 @@ function detectGlobalRoot(command3, packageRoot, io) {
469
512
  return void 0;
470
513
  }
471
514
  function getCurrentPackageRoot() {
472
- const requireFromHere = createRequire3(import.meta.url);
515
+ const requireFromHere2 = createRequire4(import.meta.url);
473
516
  for (const candidate of PACKAGE_JSON_CANDIDATES) {
474
517
  try {
475
- const packageJsonPath = requireFromHere.resolve(candidate);
476
- const pkg = requireFromHere(packageJsonPath);
518
+ const packageJsonPath = requireFromHere2.resolve(candidate);
519
+ const pkg = requireFromHere2(packageJsonPath);
477
520
  if (pkg.name === FLEET_CLI_PACKAGE_NAME) {
478
521
  return normalizePath(realpathSync8(path25.dirname(packageJsonPath)));
479
522
  }
@@ -483,7 +526,7 @@ function getCurrentPackageRoot() {
483
526
  return void 0;
484
527
  }
485
528
  function installFleetPackages(manager, versionOrChannel, io) {
486
- const child = spawn4(manager.resolved.bin, [...manager.resolved.prefixArgs, "i", "-g", ...PACKAGE_NAMES.map((name) => `${name}@${versionOrChannel}`)], {
529
+ const child = spawn5(manager.resolved.bin, [...manager.resolved.prefixArgs, "i", "-g", "--force", ...PACKAGE_NAMES.map((name) => `${name}@${versionOrChannel}`)], {
487
530
  stdio: "inherit"
488
531
  });
489
532
  return new Promise((resolve2) => {
@@ -577,6 +620,7 @@ var init_installer = __esm({
577
620
  init_resolve_bin();
578
621
  init_release();
579
622
  init_check();
623
+ init_stop_console();
580
624
  PACKAGE_NAMES = ["@dotobokuri/fleet-cli", "@dotobokuri/fleet-console"];
581
625
  FLEET_CLI_PACKAGE_NAME = "@dotobokuri/fleet-cli";
582
626
  PACKAGE_JSON_CANDIDATES = ["../package.json", "../../package.json"];
@@ -588,10 +632,10 @@ var init_installer = __esm({
588
632
  });
589
633
 
590
634
  // src/index.ts
591
- import { spawn as spawn5 } from "child_process";
635
+ import { spawn as spawn6 } from "child_process";
592
636
  import path26, { dirname as dirname6 } from "path";
593
637
  import { fileURLToPath as fileURLToPath2 } from "url";
594
- import { createRequire as createRequire4 } from "module";
638
+ import { createRequire as createRequire5 } from "module";
595
639
 
596
640
  // ../../packages/fleet-infra/dist/chunk-IUYHSUHV.js
597
641
  init_chunk_UH3Q34DS();
@@ -39165,9 +39209,9 @@ function createConsoleLock(deps = {}) {
39165
39209
  return { ensureLockDir, readLock, writeLock, removeLock, assertLockModes, assertTrustedLock };
39166
39210
  }
39167
39211
  function readFleetConsoleRelease() {
39168
- const requireFromHere = createRequire(import.meta.url);
39169
- const packageJsonPath = requireFromHere.resolve("../package.json");
39170
- const pkg = requireFromHere(packageJsonPath);
39212
+ const requireFromHere2 = createRequire(import.meta.url);
39213
+ const packageJsonPath = requireFromHere2.resolve("../package.json");
39214
+ const pkg = requireFromHere2(packageJsonPath);
39171
39215
  const packageRoot = path9__default.dirname(packageJsonPath);
39172
39216
  const version22 = pkg.version ?? "";
39173
39217
  if (pkg.private === true) {
@@ -39942,10 +39986,10 @@ function mergeDefs2(...defs) {
39942
39986
  function cloneDef2(schema) {
39943
39987
  return mergeDefs2(schema._zod.def);
39944
39988
  }
39945
- function getElementAtPath2(obj, path182) {
39946
- if (!path182)
39989
+ function getElementAtPath2(obj, path192) {
39990
+ if (!path192)
39947
39991
  return obj;
39948
- return path182.reduce((acc, key) => acc?.[key], obj);
39992
+ return path192.reduce((acc, key) => acc?.[key], obj);
39949
39993
  }
39950
39994
  function promiseAllObject2(promisesObj) {
39951
39995
  const keys = Object.keys(promisesObj);
@@ -40354,11 +40398,11 @@ function explicitlyAborted2(x, startIndex = 0) {
40354
40398
  }
40355
40399
  return false;
40356
40400
  }
40357
- function prefixIssues2(path182, issues) {
40401
+ function prefixIssues2(path192, issues) {
40358
40402
  return issues.map((iss) => {
40359
40403
  var _a32;
40360
40404
  (_a32 = iss).path ?? (_a32.path = []);
40361
- iss.path.unshift(path182);
40405
+ iss.path.unshift(path192);
40362
40406
  return iss;
40363
40407
  });
40364
40408
  }
@@ -40503,16 +40547,16 @@ function flattenError2(error512, mapper = (issue22) => issue22.message) {
40503
40547
  }
40504
40548
  function formatError3(error512, mapper = (issue22) => issue22.message) {
40505
40549
  const fieldErrors = { _errors: [] };
40506
- const processError = (error522, path182 = []) => {
40550
+ const processError = (error522, path192 = []) => {
40507
40551
  for (const issue22 of error522.issues) {
40508
40552
  if (issue22.code === "invalid_union" && issue22.errors.length) {
40509
- issue22.errors.map((issues) => processError({ issues }, [...path182, ...issue22.path]));
40553
+ issue22.errors.map((issues) => processError({ issues }, [...path192, ...issue22.path]));
40510
40554
  } else if (issue22.code === "invalid_key") {
40511
- processError({ issues: issue22.issues }, [...path182, ...issue22.path]);
40555
+ processError({ issues: issue22.issues }, [...path192, ...issue22.path]);
40512
40556
  } else if (issue22.code === "invalid_element") {
40513
- processError({ issues: issue22.issues }, [...path182, ...issue22.path]);
40557
+ processError({ issues: issue22.issues }, [...path192, ...issue22.path]);
40514
40558
  } else {
40515
- const fullpath = [...path182, ...issue22.path];
40559
+ const fullpath = [...path192, ...issue22.path];
40516
40560
  if (fullpath.length === 0) {
40517
40561
  fieldErrors._errors.push(mapper(issue22));
40518
40562
  } else {
@@ -40539,17 +40583,17 @@ function formatError3(error512, mapper = (issue22) => issue22.message) {
40539
40583
  }
40540
40584
  function treeifyError2(error512, mapper = (issue22) => issue22.message) {
40541
40585
  const result = { errors: [] };
40542
- const processError = (error522, path182 = []) => {
40586
+ const processError = (error522, path192 = []) => {
40543
40587
  var _a32, _b;
40544
40588
  for (const issue22 of error522.issues) {
40545
40589
  if (issue22.code === "invalid_union" && issue22.errors.length) {
40546
- issue22.errors.map((issues) => processError({ issues }, [...path182, ...issue22.path]));
40590
+ issue22.errors.map((issues) => processError({ issues }, [...path192, ...issue22.path]));
40547
40591
  } else if (issue22.code === "invalid_key") {
40548
- processError({ issues: issue22.issues }, [...path182, ...issue22.path]);
40592
+ processError({ issues: issue22.issues }, [...path192, ...issue22.path]);
40549
40593
  } else if (issue22.code === "invalid_element") {
40550
- processError({ issues: issue22.issues }, [...path182, ...issue22.path]);
40594
+ processError({ issues: issue22.issues }, [...path192, ...issue22.path]);
40551
40595
  } else {
40552
- const fullpath = [...path182, ...issue22.path];
40596
+ const fullpath = [...path192, ...issue22.path];
40553
40597
  if (fullpath.length === 0) {
40554
40598
  result.errors.push(mapper(issue22));
40555
40599
  continue;
@@ -40581,8 +40625,8 @@ function treeifyError2(error512, mapper = (issue22) => issue22.message) {
40581
40625
  }
40582
40626
  function toDotPath2(_path) {
40583
40627
  const segs = [];
40584
- const path182 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
40585
- for (const seg of path182) {
40628
+ const path192 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
40629
+ for (const seg of path192) {
40586
40630
  if (typeof seg === "number")
40587
40631
  segs.push(`[${seg}]`);
40588
40632
  else if (typeof seg === "symbol")
@@ -53103,13 +53147,13 @@ function resolveRef2(ref, ctx) {
53103
53147
  if (!ref.startsWith("#")) {
53104
53148
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
53105
53149
  }
53106
- const path182 = ref.slice(1).split("/").filter(Boolean);
53107
- if (path182.length === 0) {
53150
+ const path192 = ref.slice(1).split("/").filter(Boolean);
53151
+ if (path192.length === 0) {
53108
53152
  return ctx.rootSchema;
53109
53153
  }
53110
53154
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
53111
- if (path182[0] === defsKey) {
53112
- const key = path182[1];
53155
+ if (path192[0] === defsKey) {
53156
+ const key = path192[1];
53113
53157
  if (!key || !ctx.defs[key]) {
53114
53158
  throw new Error(`Reference not found: ${ref}`);
53115
53159
  }
@@ -72323,6 +72367,75 @@ async function runNativeCommand(bin, args) {
72323
72367
  const result = await execFileAsync(bin, [...args], { timeout: DIALOG_TIMEOUT_MS });
72324
72368
  return { stdout: result.stdout, stderr: result.stderr };
72325
72369
  }
72370
+ var DEFAULT_WINDOWS_PATHEXT2 = ".COM;.EXE;.BAT;.CMD";
72371
+ var WINDOWS_PATH_SEPARATOR2 = ";";
72372
+ var WINDOWS_SHIM_EXTENSIONS2 = /* @__PURE__ */ new Set([".cmd", ".bat"]);
72373
+ var CMD_EXPANSION_SENSITIVE_PATTERN2 = /[%^]/;
72374
+ function resolvePathBinary2(command22, env, options2 = {}) {
72375
+ const platform2 = options2.platform ?? process.platform;
72376
+ const isWindows22 = platform2 === "win32";
72377
+ const pathValue = isWindows22 ? env.Path ?? env.PATH ?? "" : env.PATH ?? "";
72378
+ const pathExts = isWindows22 ? parsePathExt2(env.PATHEXT) : [""];
72379
+ const resolved = findOnPath2(command22, pathValue, pathExts, platform2, options2.exists ?? fs4__default.existsSync);
72380
+ return resolved ? wrapWindowsShim2(resolved, env, platform2) : void 0;
72381
+ }
72382
+ function wrapWindowsShim2(resolved, env, platform2) {
72383
+ if (platform2 !== "win32" || !WINDOWS_SHIM_EXTENSIONS2.has(path9__default.extname(resolved).toLowerCase())) {
72384
+ return { bin: resolved, prefixArgs: [] };
72385
+ }
72386
+ rejectCmdExpansionSensitiveShim2(resolved);
72387
+ return {
72388
+ bin: env.ComSpec ?? "cmd.exe",
72389
+ prefixArgs: ["/d", "/s", "/c", "call", forceWindowsArgQuoting2(resolved)]
72390
+ };
72391
+ }
72392
+ function rejectCmdExpansionSensitiveShim2(resolved) {
72393
+ if (CMD_EXPANSION_SENSITIVE_PATTERN2.test(resolved)) {
72394
+ throw new Error(`Refusing to run Windows shim path with cmd.exe expansion-sensitive characters (% or ^): ${resolved}`);
72395
+ }
72396
+ }
72397
+ function forceWindowsArgQuoting2(value) {
72398
+ return `${value} `;
72399
+ }
72400
+ function findOnPath2(bin, pathValue, pathExts, platform2, exists) {
72401
+ const pathSeparator = platform2 === "win32" ? WINDOWS_PATH_SEPARATOR2 : path9__default.delimiter;
72402
+ if (hasPathSeparator2(bin, platform2) || path9__default.isAbsolute(bin)) {
72403
+ return resolveWithExtensions2(bin, pathExts, platform2, exists);
72404
+ }
72405
+ for (const entry of pathValue.split(pathSeparator)) {
72406
+ const searchDir = entry.length === 0 ? "." : entry;
72407
+ const candidate = resolveWithExtensions2(path9__default.join(searchDir, bin), pathExts, platform2, exists);
72408
+ if (candidate) {
72409
+ return candidate;
72410
+ }
72411
+ }
72412
+ return void 0;
72413
+ }
72414
+ function resolveWithExtensions2(candidate, pathExts, platform2, exists) {
72415
+ if (platform2 !== "win32" || path9__default.extname(candidate).length > 0) {
72416
+ return exists(candidate) ? candidate : void 0;
72417
+ }
72418
+ for (const ext of pathExts) {
72419
+ if (ext.length === 0) {
72420
+ continue;
72421
+ }
72422
+ const withExt = `${candidate}${ext}`;
72423
+ if (exists(withExt)) {
72424
+ return withExt;
72425
+ }
72426
+ }
72427
+ return exists(candidate) ? candidate : void 0;
72428
+ }
72429
+ function hasPathSeparator2(value, platform2) {
72430
+ if (value.includes("/")) {
72431
+ return true;
72432
+ }
72433
+ return platform2 === "win32" && value.includes("\\");
72434
+ }
72435
+ function parsePathExt2(pathExt) {
72436
+ const raw = pathExt && pathExt.trim().length > 0 ? pathExt : DEFAULT_WINDOWS_PATHEXT2;
72437
+ return raw.split(WINDOWS_PATH_SEPARATOR2).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
72438
+ }
72326
72439
  var DEFAULT_TERMINAL_CWD_FALLBACK = os22__default.homedir;
72327
72440
  var TERMINAL_TERM = "xterm-256color";
72328
72441
  var FLEET_HEADLESS_NATIVE_FLAGS = ["--headless", "--native"];
@@ -72333,16 +72446,26 @@ function createDefaultTerminalLaunchResolver(deps = {}) {
72333
72446
  const execPath = deps.execPath ?? process4.execPath;
72334
72447
  const homedir22 = deps.homedir ?? DEFAULT_TERMINAL_CWD_FALLBACK;
72335
72448
  const exists = deps.exists ?? fs4__default.existsSync;
72449
+ const platform2 = deps.platform ?? process4.platform;
72336
72450
  const release2 = deps.release ?? readFleetConsoleRelease();
72337
72451
  return (selectedCwd, context) => {
72338
72452
  const cwd = selectedCwd || baseCwd || homedir22();
72339
72453
  if (context?.kind === "shell") {
72340
- return { bin: resolveUserShell(env), args: [], cwd, env: buildShellLaunchEnv(env) };
72454
+ const shell = resolveWindowsLaunchBinary(resolveUserShell(env, platform2), [], env, exists, platform2, "user shell");
72455
+ return { bin: shell.bin, args: shell.args, cwd, env: buildShellLaunchEnv(env) };
72341
72456
  }
72342
72457
  const launchEnv = buildLaunchEnv(env, cwd, context?.sessionId);
72343
72458
  const override = parseTerminalCommand(env.FLEET_TERMINAL_CMD);
72344
72459
  if (override) {
72345
- return { ...override, cwd, env: launchEnv };
72460
+ const resolvedOverride = resolveWindowsLaunchBinary(
72461
+ override.bin,
72462
+ override.args,
72463
+ env,
72464
+ exists,
72465
+ platform2,
72466
+ "FLEET_TERMINAL_CMD"
72467
+ );
72468
+ return { ...resolvedOverride, cwd, env: launchEnv };
72346
72469
  }
72347
72470
  if (release2.channel === "local") {
72348
72471
  const localCli = resolveSiblingFleetCliEntry(release2.packageRoot, exists);
@@ -72353,7 +72476,15 @@ function createDefaultTerminalLaunchResolver(deps = {}) {
72353
72476
  }
72354
72477
  return { bin: execPath, args: [localCli, ...FLEET_HEADLESS_NATIVE_FLAGS], cwd, env: launchEnv };
72355
72478
  }
72356
- return { bin: "fleet", args: [...FLEET_HEADLESS_NATIVE_FLAGS], cwd, env: launchEnv };
72479
+ const stableFleet = resolveWindowsLaunchBinary(
72480
+ "fleet",
72481
+ [...FLEET_HEADLESS_NATIVE_FLAGS],
72482
+ env,
72483
+ exists,
72484
+ platform2,
72485
+ "fleet stable terminal binary"
72486
+ );
72487
+ return { ...stableFleet, cwd, env: launchEnv };
72357
72488
  };
72358
72489
  }
72359
72490
  function startTerminalShell(launch, size) {
@@ -72366,11 +72497,21 @@ function startTerminalShell(launch, size) {
72366
72497
  name: TERMINAL_TERM
72367
72498
  });
72368
72499
  }
72369
- function resolveUserShell(env) {
72500
+ function resolveUserShell(env, platform2) {
72370
72501
  if (env.SHELL) return env.SHELL;
72371
- if (process4.platform === "win32") return env.ComSpec || "powershell.exe";
72502
+ if (platform2 === "win32") return env.ComSpec || "powershell.exe";
72372
72503
  return "/bin/bash";
72373
72504
  }
72505
+ function resolveWindowsLaunchBinary(bin, args, env, exists, platform2, label) {
72506
+ if (platform2 !== "win32") {
72507
+ return { bin, args };
72508
+ }
72509
+ const resolved = resolvePathBinary2(bin, env, { exists, platform: platform2 });
72510
+ if (!resolved) {
72511
+ throw new Error(`${label} "${bin}" was not found on PATH; provide an absolute path or install it before launching a terminal session.`);
72512
+ }
72513
+ return { bin: resolved.bin, args: [...resolved.prefixArgs, ...args] };
72514
+ }
72374
72515
  function resolveSiblingFleetCliEntry(consolePackageRoot, exists = fs4__default.existsSync) {
72375
72516
  const candidate = expectedSiblingFleetCliEntry(consolePackageRoot);
72376
72517
  return exists(candidate) ? candidate : null;
@@ -83150,7 +83291,7 @@ async function dispatchUpdateCommand(argv2, io) {
83150
83291
 
83151
83292
  // src/index.ts
83152
83293
  var HELP_HINT2 = "Run 'fleet --help' for usage.";
83153
- var require4 = createRequire4(import.meta.url);
83294
+ var require4 = createRequire5(import.meta.url);
83154
83295
  var FLEET_ENTRY_PATH = fileURLToPath2(import.meta.url);
83155
83296
  var PLUGIN_ASSETS_DIR = path26.join(dirname6(dirname6(FLEET_ENTRY_PATH)), "assets");
83156
83297
  var PLUGIN_TSX_LOADER_PATH = resolveOptionalPackage("tsx");
@@ -83242,7 +83383,7 @@ function resolveOptionalPackage(id) {
83242
83383
  }
83243
83384
  async function relayToPackageCli(specifier, args) {
83244
83385
  const cliPath = require4.resolve(specifier);
83245
- const child = spawn5(process.execPath, [cliPath, ...args], {
83386
+ const child = spawn6(process.execPath, [cliPath, ...args], {
83246
83387
  stdio: "inherit",
83247
83388
  cwd: process.env.INIT_CWD || process.cwd()
83248
83389
  });