@dotobokuri/fleet-console 1.5.2 → 1.5.3

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 (61) hide show
  1. package/dist/cli-bin.mjs +290 -98
  2. package/dist/cli.mjs +290 -98
  3. package/dist/client/assets/{_baseUniq-DZtdSbAI.js → _baseUniq-D0ScniwI.js} +1 -1
  4. package/dist/client/assets/{arc-DtGJnR7c.js → arc-BVncG7ke.js} +1 -1
  5. package/dist/client/assets/{architectureDiagram-Q4EWVU46-LArxXm6l.js → architectureDiagram-Q4EWVU46-ClShr277.js} +1 -1
  6. package/dist/client/assets/{blockDiagram-DXYQGD6D-QIMR_huT.js → blockDiagram-DXYQGD6D-CrivdCAG.js} +1 -1
  7. package/dist/client/assets/{c4Diagram-AHTNJAMY-CZtY_K-W.js → c4Diagram-AHTNJAMY-B7PCIQAH.js} +1 -1
  8. package/dist/client/assets/channel-BQxlgV4A.js +1 -0
  9. package/dist/client/assets/{chunk-4BX2VUAB-BGzO5-sq.js → chunk-4BX2VUAB-DXeu-dM9.js} +1 -1
  10. package/dist/client/assets/{chunk-4TB4RGXK-WdZ6ouQ-.js → chunk-4TB4RGXK-BLl_OCcS.js} +1 -1
  11. package/dist/client/assets/{chunk-55IACEB6-DWqU4cvi.js → chunk-55IACEB6-Dw15rh74.js} +1 -1
  12. package/dist/client/assets/{chunk-EDXVE4YY-DKVvBdal.js → chunk-EDXVE4YY-D-RaYxb6.js} +1 -1
  13. package/dist/client/assets/{chunk-FMBD7UC4-hFxQ1nPT.js → chunk-FMBD7UC4-BURzGCgv.js} +1 -1
  14. package/dist/client/assets/{chunk-OYMX7WX6-CODPvRHn.js → chunk-OYMX7WX6-RlVYpHiY.js} +1 -1
  15. package/dist/client/assets/{chunk-QZHKN3VN-DZEyU080.js → chunk-QZHKN3VN-Cwh5KNNT.js} +1 -1
  16. package/dist/client/assets/{chunk-YZCP3GAM-CbT2_Nto.js → chunk-YZCP3GAM-CiQn7QhX.js} +1 -1
  17. package/dist/client/assets/classDiagram-6PBFFD2Q-DKVGUl6t.js +1 -0
  18. package/dist/client/assets/classDiagram-v2-HSJHXN6E-DKVGUl6t.js +1 -0
  19. package/dist/client/assets/clone-BWF9pDhJ.js +1 -0
  20. package/dist/client/assets/{cose-bilkent-S5V4N54A-XzqSqD-C.js → cose-bilkent-S5V4N54A-BjrkHodW.js} +1 -1
  21. package/dist/client/assets/{dagre-KV5264BT-CgF9Z5iF.js → dagre-KV5264BT-C2l7dBaN.js} +1 -1
  22. package/dist/client/assets/{diagram-5BDNPKRD-oKxvNLqy.js → diagram-5BDNPKRD-DLbWU7o6.js} +1 -1
  23. package/dist/client/assets/{diagram-G4DWMVQ6-D0Tf7aYg.js → diagram-G4DWMVQ6-CHa3wC_6.js} +1 -1
  24. package/dist/client/assets/{diagram-MMDJMWI5-XTM7fwZ-.js → diagram-MMDJMWI5-unre4XlN.js} +1 -1
  25. package/dist/client/assets/{diagram-TYMM5635-DEOQIgV5.js → diagram-TYMM5635-Cdt0vfut.js} +1 -1
  26. package/dist/client/assets/{erDiagram-SMLLAGMA-Cx909qfM.js → erDiagram-SMLLAGMA-BYzXAxxJ.js} +1 -1
  27. package/dist/client/assets/{flowDiagram-DWJPFMVM-CHyV1yID.js → flowDiagram-DWJPFMVM-CNV2iyQR.js} +1 -1
  28. package/dist/client/assets/{ganttDiagram-T4ZO3ILL-BTzCi2HJ.js → ganttDiagram-T4ZO3ILL-DThuKZ5c.js} +1 -1
  29. package/dist/client/assets/{gitGraphDiagram-UUTBAWPF-CEulcOho.js → gitGraphDiagram-UUTBAWPF-aQ8ynpC0.js} +1 -1
  30. package/dist/client/assets/{graph-DVXKTCe8.js → graph-C8-VhfUV.js} +1 -1
  31. package/dist/client/assets/{index-CwNYg7kD.js → index-BWz6DiTE.js} +150 -150
  32. package/dist/client/assets/index-DyIWJOIv.css +1 -0
  33. package/dist/client/assets/{infoDiagram-42DDH7IO-EHnanSdn.js → infoDiagram-42DDH7IO-Do5t0VWS.js} +1 -1
  34. package/dist/client/assets/{ishikawaDiagram-UXIWVN3A-DxlZOIcm.js → ishikawaDiagram-UXIWVN3A-DIe1b4HJ.js} +1 -1
  35. package/dist/client/assets/{journeyDiagram-VCZTEJTY-Dl4o2ry6.js → journeyDiagram-VCZTEJTY-BwHcjLfa.js} +1 -1
  36. package/dist/client/assets/{kanban-definition-6JOO6SKY-wW9OL1Nm.js → kanban-definition-6JOO6SKY-B-zHtqTS.js} +1 -1
  37. package/dist/client/assets/{layout-LYsLWyYG.js → layout-CtVjuQFw.js} +1 -1
  38. package/dist/client/assets/{linear-CQknB12x.js → linear-rOcX3Xk5.js} +1 -1
  39. package/dist/client/assets/{mermaid.core-iv2IeunS.js → mermaid.core-BJTjy7aS.js} +4 -4
  40. package/dist/client/assets/{min-kPNBJbij.js → min-BUMqT8iZ.js} +1 -1
  41. package/dist/client/assets/{mindmap-definition-QFDTVHPH-D0mgmaro.js → mindmap-definition-QFDTVHPH-DW7Wysk_.js} +1 -1
  42. package/dist/client/assets/{pieDiagram-DEJITSTG-BuyDCQjg.js → pieDiagram-DEJITSTG-DY0ruViO.js} +1 -1
  43. package/dist/client/assets/{quadrantDiagram-34T5L4WZ-CWWBRKlz.js → quadrantDiagram-34T5L4WZ-CCEy2zsl.js} +1 -1
  44. package/dist/client/assets/{requirementDiagram-MS252O5E-BIgPKlbk.js → requirementDiagram-MS252O5E-D6PFLt6T.js} +1 -1
  45. package/dist/client/assets/{sankeyDiagram-XADWPNL6-q2RMkD0h.js → sankeyDiagram-XADWPNL6-B07GNfPe.js} +1 -1
  46. package/dist/client/assets/{sequenceDiagram-FGHM5R23-oD9DHVCm.js → sequenceDiagram-FGHM5R23-CdYYCcr6.js} +1 -1
  47. package/dist/client/assets/{stateDiagram-FHFEXIEX-fSJWdemp.js → stateDiagram-FHFEXIEX-DC3oywwW.js} +1 -1
  48. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-D0vnD8Cl.js +1 -0
  49. package/dist/client/assets/{timeline-definition-GMOUNBTQ-DGqMN4UU.js → timeline-definition-GMOUNBTQ-D85mj2bC.js} +1 -1
  50. package/dist/client/assets/{vennDiagram-DHZGUBPP-BX6MaNWJ.js → vennDiagram-DHZGUBPP-Co2lMv4A.js} +1 -1
  51. package/dist/client/assets/{wardley-RL74JXVD-DaYQb95X.js → wardley-RL74JXVD-3QSiNklf.js} +1 -1
  52. package/dist/client/assets/{wardleyDiagram-NUSXRM2D-tB4_TAZs.js → wardleyDiagram-NUSXRM2D-CHETmdOb.js} +1 -1
  53. package/dist/client/assets/{xychartDiagram-5P7HB3ND-CMd9bJvb.js → xychartDiagram-5P7HB3ND-ByAvOHKb.js} +1 -1
  54. package/dist/client/index.html +2 -2
  55. package/package.json +1 -1
  56. package/dist/client/assets/channel-B00fySL1.js +0 -1
  57. package/dist/client/assets/classDiagram-6PBFFD2Q-YQ7U8SzS.js +0 -1
  58. package/dist/client/assets/classDiagram-v2-HSJHXN6E-YQ7U8SzS.js +0 -1
  59. package/dist/client/assets/clone-BAW9t59_.js +0 -1
  60. package/dist/client/assets/index-rZEjC7rF.css +0 -1
  61. package/dist/client/assets/stateDiagram-v2-QKLJ7IA2-Dhn8tFKg.js +0 -1
package/dist/cli-bin.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { execFile, spawn, execSync } from 'child_process';
3
3
  import * as fs4 from 'fs';
4
- import fs4__default, { realpathSync, lstatSync } from 'fs';
4
+ import fs4__default, { existsSync, realpathSync, lstatSync } from 'fs';
5
5
  import * as path9 from 'path';
6
6
  import path9__default, { join, resolve, relative, dirname } from 'path';
7
7
  import process4 from 'process';
@@ -1094,10 +1094,10 @@ function mergeDefs(...defs) {
1094
1094
  function cloneDef(schema) {
1095
1095
  return mergeDefs(schema._zod.def);
1096
1096
  }
1097
- function getElementAtPath(obj, path19) {
1098
- if (!path19)
1097
+ function getElementAtPath(obj, path18) {
1098
+ if (!path18)
1099
1099
  return obj;
1100
- return path19.reduce((acc, key) => acc?.[key], obj);
1100
+ return path18.reduce((acc, key) => acc?.[key], obj);
1101
1101
  }
1102
1102
  function promiseAllObject(promisesObj) {
1103
1103
  const keys = Object.keys(promisesObj);
@@ -1506,11 +1506,11 @@ function explicitlyAborted(x, startIndex = 0) {
1506
1506
  }
1507
1507
  return false;
1508
1508
  }
1509
- function prefixIssues(path19, issues) {
1509
+ function prefixIssues(path18, issues) {
1510
1510
  return issues.map((iss) => {
1511
1511
  var _a3;
1512
1512
  (_a3 = iss).path ?? (_a3.path = []);
1513
- iss.path.unshift(path19);
1513
+ iss.path.unshift(path18);
1514
1514
  return iss;
1515
1515
  });
1516
1516
  }
@@ -1657,16 +1657,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1657
1657
  }
1658
1658
  function formatError(error51, mapper = (issue2) => issue2.message) {
1659
1659
  const fieldErrors = { _errors: [] };
1660
- const processError = (error52, path19 = []) => {
1660
+ const processError = (error52, path18 = []) => {
1661
1661
  for (const issue2 of error52.issues) {
1662
1662
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1663
- issue2.errors.map((issues) => processError({ issues }, [...path19, ...issue2.path]));
1663
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
1664
1664
  } else if (issue2.code === "invalid_key") {
1665
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
1665
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1666
1666
  } else if (issue2.code === "invalid_element") {
1667
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
1667
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1668
1668
  } else {
1669
- const fullpath = [...path19, ...issue2.path];
1669
+ const fullpath = [...path18, ...issue2.path];
1670
1670
  if (fullpath.length === 0) {
1671
1671
  fieldErrors._errors.push(mapper(issue2));
1672
1672
  } else {
@@ -1693,17 +1693,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1693
1693
  }
1694
1694
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1695
1695
  const result = { errors: [] };
1696
- const processError = (error52, path19 = []) => {
1696
+ const processError = (error52, path18 = []) => {
1697
1697
  var _a3, _b;
1698
1698
  for (const issue2 of error52.issues) {
1699
1699
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1700
- issue2.errors.map((issues) => processError({ issues }, [...path19, ...issue2.path]));
1700
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
1701
1701
  } else if (issue2.code === "invalid_key") {
1702
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
1702
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1703
1703
  } else if (issue2.code === "invalid_element") {
1704
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
1704
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
1705
1705
  } else {
1706
- const fullpath = [...path19, ...issue2.path];
1706
+ const fullpath = [...path18, ...issue2.path];
1707
1707
  if (fullpath.length === 0) {
1708
1708
  result.errors.push(mapper(issue2));
1709
1709
  continue;
@@ -1735,8 +1735,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
1735
1735
  }
1736
1736
  function toDotPath(_path) {
1737
1737
  const segs = [];
1738
- const path19 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1739
- for (const seg of path19) {
1738
+ const path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
1739
+ for (const seg of path18) {
1740
1740
  if (typeof seg === "number")
1741
1741
  segs.push(`[${seg}]`);
1742
1742
  else if (typeof seg === "symbol")
@@ -14400,13 +14400,13 @@ function resolveRef(ref, ctx) {
14400
14400
  if (!ref.startsWith("#")) {
14401
14401
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14402
14402
  }
14403
- const path19 = ref.slice(1).split("/").filter(Boolean);
14404
- if (path19.length === 0) {
14403
+ const path18 = ref.slice(1).split("/").filter(Boolean);
14404
+ if (path18.length === 0) {
14405
14405
  return ctx.rootSchema;
14406
14406
  }
14407
14407
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14408
- if (path19[0] === defsKey) {
14409
- const key = path19[1];
14408
+ if (path18[0] === defsKey) {
14409
+ const key = path18[1];
14410
14410
  if (!key || !ctx.defs[key]) {
14411
14411
  throw new Error(`Reference not found: ${ref}`);
14412
14412
  }
@@ -21349,6 +21349,75 @@ function assertNoAuthorizationHeader(config2) {
21349
21349
  throw new Error(`Builtin external MCP server "${config2.name}" must not define headers.`);
21350
21350
  }
21351
21351
  }
21352
+ var DEFAULT_WINDOWS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
21353
+ var WINDOWS_PATH_SEPARATOR = ";";
21354
+ var WINDOWS_SHIM_EXTENSIONS = /* @__PURE__ */ new Set([".cmd", ".bat"]);
21355
+ var CMD_EXPANSION_SENSITIVE_PATTERN = /[%^]/;
21356
+ function resolvePathBinary(command2, env, options = {}) {
21357
+ const platform = options.platform ?? process.platform;
21358
+ const isWindows2 = platform === "win32";
21359
+ const pathValue = isWindows2 ? env.Path ?? env.PATH ?? "" : env.PATH ?? "";
21360
+ const pathExts = isWindows2 ? parsePathExt(env.PATHEXT) : [""];
21361
+ const resolved = findOnPath(command2, pathValue, pathExts, platform);
21362
+ return resolved ? wrapWindowsShim(resolved, env, platform) : void 0;
21363
+ }
21364
+ function wrapWindowsShim(resolved, env, platform) {
21365
+ if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path9__default.extname(resolved).toLowerCase())) {
21366
+ return { bin: resolved, prefixArgs: [] };
21367
+ }
21368
+ rejectCmdExpansionSensitiveShim(resolved);
21369
+ return {
21370
+ bin: env.ComSpec ?? "cmd.exe",
21371
+ prefixArgs: ["/d", "/s", "/c", "call", forceWindowsArgQuoting(resolved)]
21372
+ };
21373
+ }
21374
+ function rejectCmdExpansionSensitiveShim(resolved) {
21375
+ if (CMD_EXPANSION_SENSITIVE_PATTERN.test(resolved)) {
21376
+ throw new Error(`Refusing to run Windows shim path with cmd.exe expansion-sensitive characters (% or ^): ${resolved}`);
21377
+ }
21378
+ }
21379
+ function forceWindowsArgQuoting(value) {
21380
+ return `${value} `;
21381
+ }
21382
+ function findOnPath(bin, pathValue, pathExts, platform) {
21383
+ const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path9__default.delimiter;
21384
+ if (hasPathSeparator(bin, platform) || path9__default.isAbsolute(bin)) {
21385
+ return resolveWithExtensions(bin, pathExts, platform);
21386
+ }
21387
+ for (const entry of pathValue.split(pathSeparator)) {
21388
+ const searchDir = entry.length === 0 ? "." : entry;
21389
+ const candidate = resolveWithExtensions(path9__default.join(searchDir, bin), pathExts, platform);
21390
+ if (candidate) {
21391
+ return candidate;
21392
+ }
21393
+ }
21394
+ return void 0;
21395
+ }
21396
+ function resolveWithExtensions(candidate, pathExts, platform) {
21397
+ if (platform !== "win32" || path9__default.extname(candidate).length > 0) {
21398
+ return existsSync(candidate) ? candidate : void 0;
21399
+ }
21400
+ for (const ext of pathExts) {
21401
+ if (ext.length === 0) {
21402
+ continue;
21403
+ }
21404
+ const withExt = `${candidate}${ext}`;
21405
+ if (existsSync(withExt)) {
21406
+ return withExt;
21407
+ }
21408
+ }
21409
+ return existsSync(candidate) ? candidate : void 0;
21410
+ }
21411
+ function hasPathSeparator(value, platform) {
21412
+ if (value.includes("/")) {
21413
+ return true;
21414
+ }
21415
+ return platform === "win32" && value.includes("\\");
21416
+ }
21417
+ function parsePathExt(pathExt) {
21418
+ const raw = pathExt && pathExt.trim().length > 0 ? pathExt : DEFAULT_WINDOWS_PATHEXT;
21419
+ return raw.split(WINDOWS_PATH_SEPARATOR).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
21420
+ }
21352
21421
  var DEAD_SESSION_PATTERNS = [
21353
21422
  /session not found/i,
21354
21423
  /unknown session/i,
@@ -22060,6 +22129,146 @@ async function disconnect(poolKey) {
22060
22129
  async function executeWithPool(opts) {
22061
22130
  return engineExecuteWithPool(opts);
22062
22131
  }
22132
+ var NPM_REGISTRY_BASE_URL = "https://registry.npmjs.org/";
22133
+ var REGISTRY_TIMEOUT_MS = 3e3;
22134
+ var MAX_REGISTRY_RESPONSE_BYTES = 1024 * 1024;
22135
+ var VERSION_PATTERN = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/;
22136
+ async function fetchLatestVersion(packageName, channel) {
22137
+ const controller = new AbortController();
22138
+ const timer = setTimeout(() => controller.abort(), REGISTRY_TIMEOUT_MS);
22139
+ timer.unref?.();
22140
+ try {
22141
+ const response = await fetch(`${NPM_REGISTRY_BASE_URL}${encodeNpmPackageName(packageName)}`, {
22142
+ headers: {
22143
+ Accept: "application/vnd.npm.install-v1+json"
22144
+ },
22145
+ signal: controller.signal
22146
+ });
22147
+ if (!response.ok) {
22148
+ return void 0;
22149
+ }
22150
+ const metadata = await readJsonWithByteLimit(response, controller);
22151
+ if (metadata === void 0) {
22152
+ return void 0;
22153
+ }
22154
+ const latest = metadata["dist-tags"]?.[channel ?? "latest"];
22155
+ return typeof latest === "string" && latest.length > 0 ? latest : void 0;
22156
+ } catch {
22157
+ return void 0;
22158
+ } finally {
22159
+ clearTimeout(timer);
22160
+ }
22161
+ }
22162
+ function isVersionGreater(left, right) {
22163
+ const leftVersion = parseVersion(left);
22164
+ const rightVersion = parseVersion(right);
22165
+ if (leftVersion === void 0 || rightVersion === void 0) {
22166
+ return false;
22167
+ }
22168
+ return compareVersions(leftVersion, rightVersion) > 0;
22169
+ }
22170
+ function encodeNpmPackageName(packageName) {
22171
+ if (!packageName.startsWith("@")) {
22172
+ return encodeURIComponent(packageName);
22173
+ }
22174
+ const separatorIndex = packageName.indexOf("/");
22175
+ if (separatorIndex === -1) {
22176
+ return encodeURIComponent(packageName);
22177
+ }
22178
+ const scope = packageName.slice(1, separatorIndex);
22179
+ const name = packageName.slice(separatorIndex + 1);
22180
+ return `@${encodeURIComponent(scope)}%2f${encodeURIComponent(name)}`;
22181
+ }
22182
+ async function readJsonWithByteLimit(response, controller) {
22183
+ const body = response.body;
22184
+ if (body === null) {
22185
+ return void 0;
22186
+ }
22187
+ const reader = body.getReader();
22188
+ const chunks = [];
22189
+ let totalBytes = 0;
22190
+ try {
22191
+ while (true) {
22192
+ const { done, value } = await reader.read();
22193
+ if (done) {
22194
+ break;
22195
+ }
22196
+ totalBytes += value.byteLength;
22197
+ if (totalBytes > MAX_REGISTRY_RESPONSE_BYTES) {
22198
+ controller.abort();
22199
+ return void 0;
22200
+ }
22201
+ chunks.push(value);
22202
+ }
22203
+ return JSON.parse(new TextDecoder().decode(joinChunks(chunks, totalBytes)));
22204
+ } catch {
22205
+ return void 0;
22206
+ } finally {
22207
+ reader.releaseLock();
22208
+ }
22209
+ }
22210
+ function joinChunks(chunks, totalBytes) {
22211
+ const joined = new Uint8Array(totalBytes);
22212
+ let offset = 0;
22213
+ for (const chunk of chunks) {
22214
+ joined.set(chunk, offset);
22215
+ offset += chunk.byteLength;
22216
+ }
22217
+ return joined;
22218
+ }
22219
+ function parseVersion(version2) {
22220
+ const match = VERSION_PATTERN.exec(version2.trim());
22221
+ if (match === null) {
22222
+ return void 0;
22223
+ }
22224
+ return {
22225
+ major: Number(match[1]),
22226
+ minor: Number(match[2]),
22227
+ patch: Number(match[3]),
22228
+ pre: match[4]?.split(".") ?? []
22229
+ };
22230
+ }
22231
+ function compareVersions(left, right) {
22232
+ const base = compareNumbers(left.major, right.major) || compareNumbers(left.minor, right.minor) || compareNumbers(left.patch, right.patch);
22233
+ if (base !== 0) {
22234
+ return base;
22235
+ }
22236
+ if (left.pre.length === 0 || right.pre.length === 0) {
22237
+ return compareNumbers(right.pre.length, left.pre.length);
22238
+ }
22239
+ for (let index = 0; index < Math.max(left.pre.length, right.pre.length); index += 1) {
22240
+ const leftPart = left.pre[index];
22241
+ const rightPart = right.pre[index];
22242
+ if (leftPart === void 0 || rightPart === void 0) {
22243
+ return compareNumbers(left.pre.length, right.pre.length);
22244
+ }
22245
+ const compared = comparePrereleasePart(leftPart, rightPart);
22246
+ if (compared !== 0) {
22247
+ return compared;
22248
+ }
22249
+ }
22250
+ return 0;
22251
+ }
22252
+ function comparePrereleasePart(left, right) {
22253
+ const leftNumber = parseNumericPart(left);
22254
+ const rightNumber = parseNumericPart(right);
22255
+ if (leftNumber !== void 0 && rightNumber !== void 0) {
22256
+ return compareNumbers(leftNumber, rightNumber);
22257
+ }
22258
+ if (leftNumber !== void 0) {
22259
+ return -1;
22260
+ }
22261
+ if (rightNumber !== void 0) {
22262
+ return 1;
22263
+ }
22264
+ return left.localeCompare(right);
22265
+ }
22266
+ function parseNumericPart(value) {
22267
+ return /^\d+$/.test(value) ? Number(value) : void 0;
22268
+ }
22269
+ function compareNumbers(left, right) {
22270
+ return left === right ? 0 : left > right ? 1 : -1;
22271
+ }
22063
22272
  var SECURE_DIR_MODE = 448;
22064
22273
  var SECURE_FILE_MODE = 384;
22065
22274
  var NOFOLLOW_FLAG = fs4.constants.O_NOFOLLOW ?? 0;
@@ -34199,77 +34408,6 @@ async function runNativeCommand(bin, args) {
34199
34408
  const result = await execFileAsync(bin, [...args], { timeout: DIALOG_TIMEOUT_MS });
34200
34409
  return { stdout: result.stdout, stderr: result.stderr };
34201
34410
  }
34202
- var DEFAULT_WINDOWS_PATHEXT = ".COM;.EXE;.BAT;.CMD";
34203
- var WINDOWS_PATH_SEPARATOR = ";";
34204
- var WINDOWS_SHIM_EXTENSIONS = /* @__PURE__ */ new Set([".cmd", ".bat"]);
34205
- var CMD_EXPANSION_SENSITIVE_PATTERN = /[%^]/;
34206
- function resolvePathBinary(command2, env, options = {}) {
34207
- const platform = options.platform ?? process.platform;
34208
- const isWindows2 = platform === "win32";
34209
- const pathValue = isWindows2 ? env.Path ?? env.PATH ?? "" : env.PATH ?? "";
34210
- const pathExts = isWindows2 ? parsePathExt(env.PATHEXT) : [""];
34211
- const resolved = findOnPath(command2, pathValue, pathExts, platform, options.exists ?? fs4__default.existsSync);
34212
- return resolved ? wrapWindowsShim(resolved, env, platform) : void 0;
34213
- }
34214
- function wrapWindowsShim(resolved, env, platform) {
34215
- if (platform !== "win32" || !WINDOWS_SHIM_EXTENSIONS.has(path9__default.extname(resolved).toLowerCase())) {
34216
- return { bin: resolved, prefixArgs: [] };
34217
- }
34218
- rejectCmdExpansionSensitiveShim(resolved);
34219
- return {
34220
- bin: env.ComSpec ?? "cmd.exe",
34221
- prefixArgs: ["/d", "/s", "/c", "call", forceWindowsArgQuoting(resolved)]
34222
- };
34223
- }
34224
- function rejectCmdExpansionSensitiveShim(resolved) {
34225
- if (CMD_EXPANSION_SENSITIVE_PATTERN.test(resolved)) {
34226
- throw new Error(`Refusing to run Windows shim path with cmd.exe expansion-sensitive characters (% or ^): ${resolved}`);
34227
- }
34228
- }
34229
- function forceWindowsArgQuoting(value) {
34230
- return `${value} `;
34231
- }
34232
- function findOnPath(bin, pathValue, pathExts, platform, exists) {
34233
- const pathSeparator = platform === "win32" ? WINDOWS_PATH_SEPARATOR : path9__default.delimiter;
34234
- if (hasPathSeparator(bin, platform) || path9__default.isAbsolute(bin)) {
34235
- return resolveWithExtensions(bin, pathExts, platform, exists);
34236
- }
34237
- for (const entry of pathValue.split(pathSeparator)) {
34238
- const searchDir = entry.length === 0 ? "." : entry;
34239
- const candidate = resolveWithExtensions(path9__default.join(searchDir, bin), pathExts, platform, exists);
34240
- if (candidate) {
34241
- return candidate;
34242
- }
34243
- }
34244
- return void 0;
34245
- }
34246
- function resolveWithExtensions(candidate, pathExts, platform, exists) {
34247
- if (platform !== "win32" || path9__default.extname(candidate).length > 0) {
34248
- return exists(candidate) ? candidate : void 0;
34249
- }
34250
- for (const ext of pathExts) {
34251
- if (ext.length === 0) {
34252
- continue;
34253
- }
34254
- const withExt = `${candidate}${ext}`;
34255
- if (exists(withExt)) {
34256
- return withExt;
34257
- }
34258
- }
34259
- return exists(candidate) ? candidate : void 0;
34260
- }
34261
- function hasPathSeparator(value, platform) {
34262
- if (value.includes("/")) {
34263
- return true;
34264
- }
34265
- return platform === "win32" && value.includes("\\");
34266
- }
34267
- function parsePathExt(pathExt) {
34268
- const raw = pathExt && pathExt.trim().length > 0 ? pathExt : DEFAULT_WINDOWS_PATHEXT;
34269
- return raw.split(WINDOWS_PATH_SEPARATOR).map((entry) => entry.trim()).filter((entry) => entry.length > 0);
34270
- }
34271
-
34272
- // src/terminal/launch.ts
34273
34411
  var DEFAULT_TERMINAL_CWD_FALLBACK = os22__default.homedir;
34274
34412
  var TERMINAL_TERM = "xterm-256color";
34275
34413
  var FLEET_HEADLESS_NATIVE_FLAGS = ["--headless", "--native"];
@@ -34285,7 +34423,7 @@ function createDefaultTerminalLaunchResolver(deps = {}) {
34285
34423
  return (selectedCwd, context) => {
34286
34424
  const cwd = selectedCwd || baseCwd || homedir2();
34287
34425
  if (context?.kind === "shell") {
34288
- const shell = resolveWindowsLaunchBinary(resolveUserShell(env, platform), [], env, exists, platform, "user shell");
34426
+ const shell = resolveWindowsLaunchBinary(resolveUserShell(env, platform), [], env, platform, "user shell");
34289
34427
  return { bin: shell.bin, args: shell.args, cwd, env: buildShellLaunchEnv(env) };
34290
34428
  }
34291
34429
  const launchEnv = buildLaunchEnv(env, cwd, context?.sessionId);
@@ -34295,7 +34433,6 @@ function createDefaultTerminalLaunchResolver(deps = {}) {
34295
34433
  override.bin,
34296
34434
  override.args,
34297
34435
  env,
34298
- exists,
34299
34436
  platform,
34300
34437
  "FLEET_TERMINAL_CMD"
34301
34438
  );
@@ -34314,7 +34451,6 @@ function createDefaultTerminalLaunchResolver(deps = {}) {
34314
34451
  "fleet",
34315
34452
  [...FLEET_HEADLESS_NATIVE_FLAGS],
34316
34453
  env,
34317
- exists,
34318
34454
  platform,
34319
34455
  "fleet stable terminal binary"
34320
34456
  );
@@ -34336,11 +34472,11 @@ function resolveUserShell(env, platform) {
34336
34472
  if (platform === "win32") return env.ComSpec || "powershell.exe";
34337
34473
  return "/bin/bash";
34338
34474
  }
34339
- function resolveWindowsLaunchBinary(bin, args, env, exists, platform, label) {
34475
+ function resolveWindowsLaunchBinary(bin, args, env, platform, label) {
34340
34476
  if (platform !== "win32") {
34341
34477
  return { bin, args };
34342
34478
  }
34343
- const resolved = resolvePathBinary(bin, env, { exists, platform });
34479
+ const resolved = resolvePathBinary(bin, env, { platform });
34344
34480
  if (!resolved) {
34345
34481
  throw new Error(`${label} "${bin}" was not found on PATH; provide an absolute path or install it before launching a terminal session.`);
34346
34482
  }
@@ -34607,6 +34743,59 @@ var TheaterRegistry = class {
34607
34743
  }
34608
34744
  };
34609
34745
 
34746
+ // src/update-check.ts
34747
+ var FLEET_CONSOLE_PACKAGE_NAME = "@dotobokuri/fleet-console";
34748
+ var UPDATE_CHECK_TTL_MS = 60 * 60 * 1e3;
34749
+ var NO_UPDATE_STATUS = { updateAvailable: false };
34750
+ function createConsoleUpdateCheckService(deps = {}) {
34751
+ const readRelease = deps.readRelease ?? readFleetConsoleRelease;
34752
+ const fetchLatest = deps.fetchLatest ?? fetchLatestVersion;
34753
+ const isGreater = deps.isGreater ?? isVersionGreater;
34754
+ const now = deps.now ?? Date.now;
34755
+ const ttlMs = deps.ttlMs ?? UPDATE_CHECK_TTL_MS;
34756
+ let cached2 = null;
34757
+ let inFlight = null;
34758
+ const getStatus = () => {
34759
+ const current = cached2;
34760
+ if (current && now() - current.checkedAt < ttlMs) {
34761
+ return current.status;
34762
+ }
34763
+ void refresh();
34764
+ return current?.status ?? NO_UPDATE_STATUS;
34765
+ };
34766
+ const refresh = async () => {
34767
+ const current = cached2;
34768
+ if (current && now() - current.checkedAt < ttlMs) {
34769
+ return current.status;
34770
+ }
34771
+ if (inFlight) {
34772
+ return inFlight;
34773
+ }
34774
+ inFlight = resolveUpdateStatus().then((status) => {
34775
+ cached2 = { status, checkedAt: now() };
34776
+ return status;
34777
+ }).catch(() => {
34778
+ cached2 = { status: NO_UPDATE_STATUS, checkedAt: now() };
34779
+ return NO_UPDATE_STATUS;
34780
+ }).finally(() => {
34781
+ inFlight = null;
34782
+ });
34783
+ return inFlight;
34784
+ };
34785
+ const resolveUpdateStatus = async () => {
34786
+ const release = readRelease();
34787
+ if (release.channel === "local") {
34788
+ return NO_UPDATE_STATUS;
34789
+ }
34790
+ const latestVersion = await fetchLatest(FLEET_CONSOLE_PACKAGE_NAME);
34791
+ if (!latestVersion || !isGreater(latestVersion, release.version)) {
34792
+ return NO_UPDATE_STATUS;
34793
+ }
34794
+ return { updateAvailable: true, latestVersion };
34795
+ };
34796
+ return { getStatus, refresh };
34797
+ }
34798
+
34610
34799
  // src/server.ts
34611
34800
  var DEFAULT_HOST = "127.0.0.1";
34612
34801
  var DEFAULT_PORT = 0;
@@ -34623,6 +34812,7 @@ function createConsoleServer(deps = {}) {
34623
34812
  registerDefaultCarriers(carrierRegistry);
34624
34813
  const lock = createConsoleLock({ hostname: () => host });
34625
34814
  const observability = createConsoleObservabilityStore();
34815
+ const updateCheck = deps.updateCheck ?? createConsoleUpdateCheckService();
34626
34816
  const theaters = new TheaterRegistry();
34627
34817
  const terminalTickets = createTerminalTicketRegistry();
34628
34818
  const folderGrants = createFolderGrantStore();
@@ -34990,6 +35180,7 @@ function createConsoleServer(deps = {}) {
34990
35180
  jobs: observability.listWorkspaces().reduce((count, workspace) => count + observability.listJobs(workspace.tenantId).length, 0),
34991
35181
  version: version2,
34992
35182
  channel,
35183
+ ...updateCheck.getStatus(),
34993
35184
  port: lockHandle?.payload.port ?? port,
34994
35185
  wikiServerStatus: resolveWikiServerStatus(theaterId)
34995
35186
  };
@@ -35106,6 +35297,7 @@ function createConsoleServer(deps = {}) {
35106
35297
  });
35107
35298
  });
35108
35299
  if (!activeEndpoint) throw new Error("Console endpoint unavailable");
35300
+ void updateCheck.refresh();
35109
35301
  return activeEndpoint;
35110
35302
  },
35111
35303
  async stop() {