@dotobokuri/fleet-cli 1.0.1 → 1.0.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
@@ -72,7 +72,7 @@ function readFleetCliRelease() {
72
72
  if (pkg.private === true) {
73
73
  return { channel: "local", version: version2 };
74
74
  }
75
- return { channel: version2.includes("-") ? "canary" : "stable", version: version2 };
75
+ return { channel: "stable", version: version2 };
76
76
  }
77
77
  var init_release = __esm({
78
78
  "src/release.ts"() {
@@ -265,8 +265,8 @@ var init_semver = __esm({
265
265
  });
266
266
 
267
267
  // src/update/check.ts
268
- function resolveUpdateChannel(version2) {
269
- return version2.includes("-") ? "canary" : "latest";
268
+ function resolveUpdateChannel(_version) {
269
+ return "latest";
270
270
  }
271
271
  async function checkForUpdate(release2) {
272
272
  if (release2 === void 0 || release2.version.length === 0 || release2.channel === "local") {
@@ -342,15 +342,15 @@ function detectGlobalPackageManager() {
342
342
  const pnpm = detectGlobalRoot("pnpm", packageRoot);
343
343
  return pnpm ?? { manager: void 0, reason: "local" };
344
344
  }
345
- function detectGlobalRoot(command2, packageRoot) {
345
+ function detectGlobalRoot(command3, packageRoot) {
346
346
  try {
347
- const globalRoot = execFileSync(command2, ["root", "-g"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
347
+ const globalRoot = execFileSync(command3, ["root", "-g"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
348
348
  const resolvedRoot = normalizePath(realpathSync2(path24.resolve(globalRoot)));
349
349
  if (isPathInside2(normalizePath(packageRoot), resolvedRoot)) {
350
350
  if (!canWrite(resolvedRoot)) {
351
351
  return { manager: void 0, reason: "permission" };
352
352
  }
353
- return { manager: { command: command2, globalRoot: resolvedRoot }, reason: void 0 };
353
+ return { manager: { command: command3, globalRoot: resolvedRoot }, reason: void 0 };
354
354
  }
355
355
  const expectedPkgDir = path24.join(globalRoot, FLEET_CLI_PACKAGE_NAME);
356
356
  try {
@@ -359,7 +359,7 @@ function detectGlobalRoot(command2, packageRoot) {
359
359
  if (!canWrite(resolvedRoot)) {
360
360
  return { manager: void 0, reason: "permission" };
361
361
  }
362
- return { manager: { command: command2, globalRoot: resolvedRoot }, reason: void 0 };
362
+ return { manager: { command: command3, globalRoot: resolvedRoot }, reason: void 0 };
363
363
  }
364
364
  } catch {
365
365
  }
@@ -382,8 +382,8 @@ function getCurrentPackageRoot() {
382
382
  }
383
383
  return void 0;
384
384
  }
385
- function installFleetPackages(command2, versionOrChannel) {
386
- const child = spawn4(command2, ["i", "-g", ...PACKAGE_NAMES.map((name) => `${name}@${versionOrChannel}`)], {
385
+ function installFleetPackages(command3, versionOrChannel) {
386
+ const child = spawn4(command3, ["i", "-g", ...PACKAGE_NAMES.map((name) => `${name}@${versionOrChannel}`)], {
387
387
  stdio: "inherit"
388
388
  });
389
389
  return new Promise((resolve) => {
@@ -409,8 +409,8 @@ function writeManualInstallMessage(io, channel, reason) {
409
409
  io.stdout.write(`${formatInstallCommand("pnpm", channel)}
410
410
  `);
411
411
  }
412
- function formatInstallCommand(command2, channel) {
413
- return `${command2} i -g ${PACKAGE_NAMES.map((name) => `${name}@${channel}`).join(" ")}`;
412
+ function formatInstallCommand(command3, channel) {
413
+ return `${command3} i -g ${PACKAGE_NAMES.map((name) => `${name}@${channel}`).join(" ")}`;
414
414
  }
415
415
  function isPathInside2(child, parent) {
416
416
  return child === parent || child.startsWith(`${parent}${path24.sep}`);
@@ -853,7 +853,7 @@ async function runAuthLoginFlow(argv2, io) {
853
853
  return 0;
854
854
  }
855
855
  function getAuthCliOptions() {
856
- return AUTH_CLI_OPTIONS.map((option2) => option2.value);
856
+ return AUTH_CLI_OPTIONS.map((option3) => option3.value);
857
857
  }
858
858
  function parseAuthCliId(value) {
859
859
  if (value === "claude-zai" || value === "claude-kimi") return value;
@@ -880,21 +880,21 @@ Usage:
880
880
  fleet auth logout [claude-zai|claude-kimi]
881
881
  `;
882
882
  async function dispatchAuthCommand(argv2, io) {
883
- const command2 = argv2[1];
884
- if (!command2 || command2 === "--help" || command2 === "-h") {
883
+ const command3 = argv2[1];
884
+ if (!command3 || command3 === "--help" || command3 === "-h") {
885
885
  io.stdout.write(AUTH_HELP_TEXT);
886
886
  return 0;
887
887
  }
888
- if (command2 === "login") {
888
+ if (command3 === "login") {
889
889
  return runAuthLoginFlow(argv2.slice(2), io);
890
890
  }
891
- if (command2 === "list") {
891
+ if (command3 === "list") {
892
892
  return listAuthProviders(io);
893
893
  }
894
- if (command2 === "logout") {
894
+ if (command3 === "logout") {
895
895
  return logoutAuthProvider(argv2.slice(2), io);
896
896
  }
897
- io.stderr.write(`Unknown fleet auth command: ${command2}
897
+ io.stderr.write(`Unknown fleet auth command: ${command3}
898
898
  `);
899
899
  io.stdout.write(AUTH_HELP_TEXT);
900
900
  return 1;
@@ -976,6 +976,9 @@ function disableSgrMouse() {
976
976
  return `${ANSI_DISABLE_SGR_MOUSE}${ANSI_DISABLE_VT200_MOUSE}`;
977
977
  }
978
978
 
979
+ // ../../packages/fleet-tui/dist/core/color.js
980
+ var DIM_COLOR = "\x1B[38;5;244m";
981
+
979
982
  // ../../packages/fleet-tui/dist/core/input-stream.js
980
983
  function attachInputStream(ui) {
981
984
  const stdin = process.stdin;
@@ -5073,7 +5076,7 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
5073
5076
  defineLazy(inst._zod, "optout", () => def.options.some((o) => o._zod.optout === "optional") ? "optional" : void 0);
5074
5077
  defineLazy(inst._zod, "values", () => {
5075
5078
  if (def.options.every((o) => o._zod.values)) {
5076
- return new Set(def.options.flatMap((option2) => Array.from(option2._zod.values)));
5079
+ return new Set(def.options.flatMap((option3) => Array.from(option3._zod.values)));
5077
5080
  }
5078
5081
  return void 0;
5079
5082
  });
@@ -5091,8 +5094,8 @@ var $ZodUnion = /* @__PURE__ */ $constructor("$ZodUnion", (inst, def) => {
5091
5094
  }
5092
5095
  let async = false;
5093
5096
  const results = [];
5094
- for (const option2 of def.options) {
5095
- const result = option2._zod.run({
5097
+ for (const option3 of def.options) {
5098
+ const result = option3._zod.run({
5096
5099
  value: payload.value,
5097
5100
  issues: []
5098
5101
  }, ctx);
@@ -5146,8 +5149,8 @@ var $ZodXor = /* @__PURE__ */ $constructor("$ZodXor", (inst, def) => {
5146
5149
  }
5147
5150
  let async = false;
5148
5151
  const results = [];
5149
- for (const option2 of def.options) {
5150
- const result = option2._zod.run({
5152
+ for (const option3 of def.options) {
5153
+ const result = option3._zod.run({
5151
5154
  value: payload.value,
5152
5155
  issues: []
5153
5156
  }, ctx);
@@ -5171,10 +5174,10 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
5171
5174
  const _super = inst._zod.parse;
5172
5175
  defineLazy(inst._zod, "propValues", () => {
5173
5176
  const propValues = {};
5174
- for (const option2 of def.options) {
5175
- const pv = option2._zod.propValues;
5177
+ for (const option3 of def.options) {
5178
+ const pv = option3._zod.propValues;
5176
5179
  if (!pv || Object.keys(pv).length === 0)
5177
- throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option2)}"`);
5180
+ throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option3)}"`);
5178
5181
  for (const [k, v] of Object.entries(pv)) {
5179
5182
  if (!propValues[k])
5180
5183
  propValues[k] = /* @__PURE__ */ new Set();
@@ -13573,8 +13576,8 @@ function isTransforming(_schema, _ctx) {
13573
13576
  return false;
13574
13577
  }
13575
13578
  if (def.type === "union") {
13576
- for (const option2 of def.options) {
13577
- if (isTransforming(option2, ctx))
13579
+ for (const option3 of def.options) {
13580
+ if (isTransforming(option3, ctx))
13578
13581
  return true;
13579
13582
  }
13580
13583
  return false;
@@ -18908,8 +18911,8 @@ function quoteForCmd(token) {
18908
18911
  }
18909
18912
  return `"${token.replace(/"/g, '""')}"`;
18910
18913
  }
18911
- function buildWindowsCmdArgs(command2, args) {
18912
- const line = [command2, ...args].map(quoteForCmd).join(" ");
18914
+ function buildWindowsCmdArgs(command3, args) {
18915
+ const line = [command3, ...args].map(quoteForCmd).join(" ");
18913
18916
  return ["/S", "/C", `"${line}"`];
18914
18917
  }
18915
18918
 
@@ -19631,6 +19634,8 @@ var models_default = {
19631
19634
  defaultModel: "auto",
19632
19635
  models: [
19633
19636
  { modelId: "auto", name: "Auto", effort: { supported: false } },
19637
+ { modelId: "composer-2.5-fast", name: "Composer 2.5 Fast", description: "Cursor Composer 2.5 (fast variant, default upstream)", effort: { supported: false } },
19638
+ { modelId: "composer-2.5", name: "Composer 2.5", description: "Cursor Composer 2.5 (standard variant)", effort: { supported: false } },
19634
19639
  { modelId: "gemini-3.1-pro", name: "Gemini 3.1 Pro", effort: { supported: false } },
19635
19640
  { modelId: "gemini-3-flash", name: "Gemini 3 Flash", effort: { supported: false } },
19636
19641
  { modelId: "gemini-3.5-flash", name: "Gemini 3.5 Flash", effort: { supported: false } },
@@ -19933,20 +19938,20 @@ function createSpawnConfig(cli, options2) {
19933
19938
  };
19934
19939
  }
19935
19940
  if (backend.appServerArgs) {
19936
- const command3 = options2.cliPath ?? backend.cliCommand;
19941
+ const command4 = options2.cliPath ?? backend.cliCommand;
19937
19942
  return {
19938
- command: command3,
19943
+ command: command4,
19939
19944
  args: [...backend.appServerArgs],
19940
19945
  useNpx: false
19941
19946
  };
19942
19947
  }
19943
- const command2 = options2.cliPath ?? backend.cliCommand;
19948
+ const command3 = options2.cliPath ?? backend.cliCommand;
19944
19949
  const args = backend.acpArgs ? [...backend.acpArgs] : [];
19945
19950
  if (cli === "cursor" && options2.model) {
19946
19951
  args.unshift("--model", resolveCursorSpawnModel(options2.model, options2.effort));
19947
19952
  }
19948
19953
  return {
19949
- command: command2,
19954
+ command: command3,
19950
19955
  args,
19951
19956
  useNpx: false
19952
19957
  };
@@ -20043,16 +20048,16 @@ var CliDetector = class {
20043
20048
  if (!forceRefresh && this.cache.size > 0) {
20044
20049
  return Array.from(this.cache.values());
20045
20050
  }
20046
- const results = await Promise.all(CLI_DETECT_LIST.map(async ({ id, command: command2, protocols }) => {
20047
- const available = await this.isCliAvailable(command2);
20051
+ const results = await Promise.all(CLI_DETECT_LIST.map(async ({ id, command: command3, protocols }) => {
20052
+ const available = await this.isCliAvailable(command3);
20048
20053
  const result = {
20049
20054
  cli: id,
20050
- path: available ? await this.getCliPath(command2) : command2,
20055
+ path: available ? await this.getCliPath(command3) : command3,
20051
20056
  available,
20052
20057
  protocols
20053
20058
  };
20054
20059
  if (available) {
20055
- result.version = await this.detectVersion(command2);
20060
+ result.version = await this.detectVersion(command3);
20056
20061
  }
20057
20062
  return result;
20058
20063
  }));
@@ -20125,15 +20130,15 @@ var CliDetector = class {
20125
20130
  * @param command - CLI 커맨드 이름
20126
20131
  * @returns 사용 가능 여부
20127
20132
  */
20128
- async isCliAvailable(command2) {
20133
+ async isCliAvailable(command3) {
20129
20134
  const whichCommand = isWindows() ? "where" : "which";
20130
20135
  try {
20131
- await this.execCommand(whichCommand, [command2], 3e3);
20136
+ await this.execCommand(whichCommand, [command3], 3e3);
20132
20137
  return true;
20133
20138
  } catch {
20134
20139
  if (isWindows()) {
20135
20140
  try {
20136
- await this.execCommand("powershell", ["-NoProfile", "-Command", `Get-Command -All ${command2}`], 5e3);
20141
+ await this.execCommand("powershell", ["-NoProfile", "-Command", `Get-Command -All ${command3}`], 5e3);
20137
20142
  return true;
20138
20143
  } catch {
20139
20144
  return false;
@@ -20148,9 +20153,9 @@ var CliDetector = class {
20148
20153
  * @param command - CLI 커맨드 이름
20149
20154
  * @returns 버전 문자열 또는 undefined
20150
20155
  */
20151
- async detectVersion(command2) {
20156
+ async detectVersion(command3) {
20152
20157
  try {
20153
- const output = await this.execCommand(command2, ["--version"], 5e3);
20158
+ const output = await this.execCommand(command3, ["--version"], 5e3);
20154
20159
  const match = output.match(/(\d+\.\d+\.\d+)/);
20155
20160
  return match ? match[1] : output;
20156
20161
  } catch {
@@ -20163,21 +20168,21 @@ var CliDetector = class {
20163
20168
  * @param command - CLI 커맨드 이름
20164
20169
  * @returns 전체 경로 또는 커맨드 이름
20165
20170
  */
20166
- async getCliPath(command2) {
20171
+ async getCliPath(command3) {
20167
20172
  const whichCommand = isWindows() ? "where" : "which";
20168
20173
  try {
20169
- const result = await this.execCommand(whichCommand, [command2], 3e3);
20174
+ const result = await this.execCommand(whichCommand, [command3], 3e3);
20170
20175
  return result.split(/\r?\n/)[0].trim();
20171
20176
  } catch {
20172
- return command2;
20177
+ return command3;
20173
20178
  }
20174
20179
  }
20175
20180
  /**
20176
20181
  * 외부 명령 실행 결과(stdout)를 문자열로 반환합니다.
20177
20182
  */
20178
- async execCommand(command2, args, timeout) {
20183
+ async execCommand(command3, args, timeout) {
20179
20184
  return new Promise((resolve, reject) => {
20180
- execFile(command2, args, {
20185
+ execFile(command3, args, {
20181
20186
  encoding: "utf-8",
20182
20187
  timeout,
20183
20188
  windowsHide: true
@@ -20819,8 +20824,8 @@ var CodexAppServerConnection = class extends BaseConnection {
20819
20824
  } else if (notification.item.type === "mcpToolCall") {
20820
20825
  this.emit("toolCall", `${notification.item.server}/${notification.item.tool}`, "in_progress", this.requireThreadId(), notification.item);
20821
20826
  } else if (notification.item.type === "commandExecution") {
20822
- const command2 = typeof notification.item.command === "string" ? notification.item.command : "commandExecution";
20823
- this.emit("toolCall", command2, "in_progress", this.requireThreadId(), notification.item);
20827
+ const command3 = typeof notification.item.command === "string" ? notification.item.command : "commandExecution";
20828
+ this.emit("toolCall", command3, "in_progress", this.requireThreadId(), notification.item);
20824
20829
  }
20825
20830
  break;
20826
20831
  }
@@ -20843,8 +20848,8 @@ var CodexAppServerConnection = class extends BaseConnection {
20843
20848
  } else if (notification.item.type === "mcpToolCall") {
20844
20849
  this.emit("toolCallUpdate", `${notification.item.server}/${notification.item.tool}`, "completed", this.requireThreadId(), notification.item);
20845
20850
  } else if (notification.item.type === "commandExecution") {
20846
- const command2 = typeof notification.item.command === "string" ? notification.item.command : "commandExecution";
20847
- this.emit("toolCallUpdate", command2, "completed", this.requireThreadId(), notification.item);
20851
+ const command3 = typeof notification.item.command === "string" ? notification.item.command : "commandExecution";
20852
+ this.emit("toolCallUpdate", command3, "completed", this.requireThreadId(), notification.item);
20848
20853
  }
20849
20854
  break;
20850
20855
  }
@@ -20927,10 +20932,10 @@ var CodexAppServerConnection = class extends BaseConnection {
20927
20932
  bridgeApproval(jsonRpcId, method, info) {
20928
20933
  const decisions = info.availableDecisions ?? ["accept", "decline"];
20929
20934
  const permissionOptions = decisions.map((decision, index) => this.toPermissionOption(decision, index));
20930
- const decisionMap = new Map(permissionOptions.map(({ decision, option: option2 }) => [option2.optionId, decision]));
20935
+ const decisionMap = new Map(permissionOptions.map(({ decision, option: option3 }) => [option3.optionId, decision]));
20931
20936
  const syntheticParams = {
20932
20937
  sessionId: this.sessionId ?? "",
20933
- options: permissionOptions.map(({ option: option2 }) => option2),
20938
+ options: permissionOptions.map(({ option: option3 }) => option3),
20934
20939
  toolCall: {
20935
20940
  toolCallId: `${info.toolName}:${jsonRpcId}`,
20936
20941
  title: info.toolName,
@@ -21366,7 +21371,7 @@ var UnifiedCodexAgentClient = class extends EventEmitter3 {
21366
21371
  async connectAppServer(options2) {
21367
21372
  const backend = getBackendConfig("codex");
21368
21373
  const cleanEnv = cleanEnvironment(process.env, options2.env);
21369
- const command2 = options2.cliPath ?? backend.cliCommand;
21374
+ const command3 = options2.cliPath ?? backend.cliCommand;
21370
21375
  const baseArgs = backend.appServerArgs ?? ["app-server", "--listen", "stdio://"];
21371
21376
  const developerInstructions = options2.systemPrompt ?? null;
21372
21377
  const modeMapping = this.resolveMode(options2.yoloMode === false ? "default" : "yolo");
@@ -21376,7 +21381,7 @@ var UnifiedCodexAgentClient = class extends EventEmitter3 {
21376
21381
  ];
21377
21382
  const mcpServerNames = this.resolveMcpServerNames(options2.configOverrides, options2.mcpServers);
21378
21383
  const connection = new CodexAppServerConnection({
21379
- command: command2,
21384
+ command: command3,
21380
21385
  args,
21381
21386
  cwd: options2.cwd,
21382
21387
  env: cleanEnv,
@@ -34170,8 +34175,8 @@ function createFleetPtyApi(options2, localUiOptions) {
34170
34175
  getDesiredHeight: (maxRows) => regions.current().component.desiredHeight?.(maxRows),
34171
34176
  getSections: () => [...mountedSections],
34172
34177
  hasActiveOverlay: () => !regions.isDefault(),
34173
- mountSection: (section2) => {
34174
- mountedSections.push(section2);
34178
+ mountSection: (section3) => {
34179
+ mountedSections.push(section3);
34175
34180
  defaultRegion.component.invalidate();
34176
34181
  },
34177
34182
  popOverlay: () => {
@@ -34617,6 +34622,7 @@ function computeResizeRequest(options2, size, reason) {
34617
34622
 
34618
34623
  // src/controls/render.ts
34619
34624
  var RENDER_THROTTLE_MS = 16;
34625
+ var CLAUDE_CODE_AGENT_IDS = /* @__PURE__ */ new Set(["claude", "claude-zai", "claude-kimi"]);
34620
34626
  var STANDARD_MOUSE_PROTOCOL_STATE = {
34621
34627
  activeEncoding: "default",
34622
34628
  activeProtocol: "none",
@@ -34683,7 +34689,7 @@ function createFleetPtyViewport(fleetPty) {
34683
34689
  }
34684
34690
  function createCursorPolicySync(options2) {
34685
34691
  return () => {
34686
- if (!options2.cursorSync || options2.isModeToggleSuppressed() || options2.hasActiveMissionControlPanel() || options2.fleetPty.hasActiveOverlay()) {
34692
+ if (!options2.cursorSync || options2.isModeToggleSuppressed() || options2.hasActiveMissionControlPanel() || options2.fleetPty.hasActiveOverlay() || shouldAutoDisableCursorSync(options2.getActiveAgentProfileId?.(), options2.cursorSyncExplicitlyEnabled === true)) {
34687
34693
  options2.ui.setCursorAnchorTarget(void 0);
34688
34694
  return;
34689
34695
  }
@@ -34691,6 +34697,9 @@ function createCursorPolicySync(options2) {
34691
34697
  options2.ui.setCursorAnchorTarget(mode === "MIRROR" || mode === "DEDICATED" ? options2.ptyView : void 0);
34692
34698
  };
34693
34699
  }
34700
+ function shouldAutoDisableCursorSync(profileId, cursorSyncExplicitlyEnabled = false) {
34701
+ return process.platform === "win32" && !cursorSyncExplicitlyEnabled && profileId !== void 0 && CLAUDE_CODE_AGENT_IDS.has(profileId);
34702
+ }
34694
34703
 
34695
34704
  // src/controls/terminal-view.ts
34696
34705
  import xterm from "@xterm/headless";
@@ -34846,7 +34855,8 @@ function projectLogicalCursor(terminal, width) {
34846
34855
  visible: false
34847
34856
  };
34848
34857
  }
34849
- const column = Math.min(projectLineColumn(line, cursor.x, terminal.cols), width - 1);
34858
+ const cursorIndex = getProjectedCursorIndex(line, cursor.x, terminal.cols);
34859
+ const column = Math.min(projectLineColumn(line, cursorIndex, terminal.cols), width - 1);
34850
34860
  return {
34851
34861
  column,
34852
34862
  row,
@@ -34857,7 +34867,8 @@ function renderLine2(line, cols) {
34857
34867
  let rendered = "";
34858
34868
  let activeStyle = DEFAULT_STYLE;
34859
34869
  let hasStyle = false;
34860
- for (let index = 0; index < cols; index += 1) {
34870
+ const effectiveCols = getProjectedCursorIndex(line, cols, cols);
34871
+ for (let index = 0; index < effectiveCols; index += 1) {
34861
34872
  const cell = line.getCell(index);
34862
34873
  if (!cell || cell.getWidth() === 0) {
34863
34874
  continue;
@@ -34887,6 +34898,25 @@ function projectLineColumn(line, cursorX, cols) {
34887
34898
  }
34888
34899
  return Math.max(0, visibleWidth(prefix));
34889
34900
  }
34901
+ function getProjectedCursorIndex(line, cursorX, cols) {
34902
+ if (cursorX < cols - 1) {
34903
+ return cursorX;
34904
+ }
34905
+ for (let index = Math.min(cursorX, cols) - 1; index >= 0; index -= 1) {
34906
+ const cell = line.getCell(index);
34907
+ if (!cell || cell.getWidth() === 0) {
34908
+ continue;
34909
+ }
34910
+ if (isDefaultPaddingCell(cell)) {
34911
+ continue;
34912
+ }
34913
+ return index + 1;
34914
+ }
34915
+ return 0;
34916
+ }
34917
+ function isDefaultPaddingCell(cell) {
34918
+ return cell.isAttributeDefault() && (cell.getCode() === 32 || cell.getCode() === 0 && cell.getChars() === "");
34919
+ }
34890
34920
  function getCellStyle(cell) {
34891
34921
  return {
34892
34922
  bg: cell.getBgColor(),
@@ -35639,8 +35669,8 @@ function waveText(text, rgb2, frame, startOffset = 0, options2) {
35639
35669
  const raw = Math.sin(phase);
35640
35670
  if (allowDim) {
35641
35671
  const bright = Math.pow(Math.max(0, raw), 3) * 0.4;
35642
- const dim2 = Math.min(0, raw) * 0.25;
35643
- const factor = bright + dim2;
35672
+ const dim3 = Math.min(0, raw) * 0.25;
35673
+ const factor = bright + dim3;
35644
35674
  const cr = Math.min(255, Math.max(0, Math.round(factor >= 0 ? r + (255 - r) * factor : r + r * factor)));
35645
35675
  const cg = Math.min(255, Math.max(0, Math.round(factor >= 0 ? g + (255 - g) * factor : g + g * factor)));
35646
35676
  const cb = Math.min(255, Math.max(0, Math.round(factor >= 0 ? b + (255 - b) * factor : b + b * factor)));
@@ -36237,10 +36267,10 @@ function buildEntryEditorLines(entry, state, deps) {
36237
36267
  const options2 = getEntryEditorOptions(entry, state, deps);
36238
36268
  const currentValue = getEntryEditorCurrentValue(entry, state, deps);
36239
36269
  const cursor = "cursor" in state ? state.cursor : 0;
36240
- return options2.map((option2, index) => {
36270
+ return options2.map((option3, index) => {
36241
36271
  const cursorToken = index === cursor ? `${getEntryColor(entry.cliType)}\u25B8${ANSI_RESET5}` : " ";
36242
- const marker = option2.value === currentValue ? "\u25CF" : "\u25CB";
36243
- return ` ${cursorToken} ${marker} ${option2.label}`;
36272
+ const marker = option3.value === currentValue ? "\u25CF" : "\u25CB";
36273
+ return ` ${cursorToken} ${marker} ${option3.label}`;
36244
36274
  });
36245
36275
  }
36246
36276
  function buildRenameEditorLines(renameState, theme) {
@@ -36303,7 +36333,7 @@ function getSelectedEntry(model) {
36303
36333
  return selectedCarrierId ? model.viewModel.flatEntries.find((entry) => entry.carrierId === selectedCarrierId) ?? null : null;
36304
36334
  }
36305
36335
  function renderEntryLine(entry, isSelected, deps) {
36306
- const dim2 = deps.theme.dim;
36336
+ const dim3 = deps.theme.dim;
36307
36337
  const slotStr = `#${entry.slot}`;
36308
36338
  const slotPad = " ".repeat(Math.max(0, SLOT_WIDTH - slotStr.length));
36309
36339
  const namePad = " ".repeat(Math.max(0, NAME_WIDTH - visibleWidth(entry.displayName)));
@@ -36311,12 +36341,12 @@ function renderEntryLine(entry, isSelected, deps) {
36311
36341
  const selectedPrefix = isSelected ? `${nameColor}\u25B8${ANSI_RESET5}` : " ";
36312
36342
  const coloredName = `${nameColor}${entry.displayName}${ANSI_RESET5}`;
36313
36343
  const modelLabel = getModelLabel(deps.getAvailableModels(entry.cliType), entry.model);
36314
- const modelStr = entry.isDefault ? dim2(modelLabel) : modelLabel;
36344
+ const modelStr = entry.isDefault ? dim3(modelLabel) : modelLabel;
36315
36345
  const effortSupported = deps.getModelEffortLevels(entry.cliType, entry.model).length > 0;
36316
- const effortStr = effortSupported && entry.effort ? `${dim2(" \xB7 ")}${entry.effort}` : "";
36317
- const roleStr = entry.role ? dim2(` (${entry.role})`) : "";
36346
+ const effortStr = effortSupported && entry.effort ? `${dim3(" \xB7 ")}${entry.effort}` : "";
36347
+ const roleStr = entry.role ? dim3(` (${entry.role})`) : "";
36318
36348
  const tfTag = entry.taskForceBackendCount >= 2 ? ` \x1B[38;2;100;180;255m[TF:${entry.taskForceBackendCount}]${ANSI_RESET5}` : "";
36319
- return ` ${selectedPrefix} ${dim2(slotStr)}${slotPad}${coloredName}${namePad}${modelStr}${effortStr}${roleStr}${tfTag}`;
36349
+ return ` ${selectedPrefix} ${dim3(slotStr)}${slotPad}${coloredName}${namePad}${modelStr}${effortStr}${roleStr}${tfTag}`;
36320
36350
  }
36321
36351
  function shouldRenderEntryEditor(state, carrierId) {
36322
36352
  return (state.kind === "model" || state.kind === "effort" || state.kind === "cliType") && state.carrierId === carrierId;
@@ -37033,10 +37063,32 @@ function errorMessage(error51) {
37033
37063
  return error51 instanceof Error ? error51.message : String(error51);
37034
37064
  }
37035
37065
 
37036
- // src/cli-style.ts
37066
+ // ../../packages/fleet-tui/dist/style/ansi.js
37037
37067
  var ANSI_RESET6 = "\x1B[0m";
37038
37068
  var ANSI_BOLD = "\x1B[1m";
37039
37069
  var ANSI_DIM2 = "\x1B[2m";
37070
+ var ANSI_PATTERN3 = /\x1b\[[0-9;]*m/g;
37071
+ function stripAnsi(text) {
37072
+ return text.replace(ANSI_PATTERN3, "");
37073
+ }
37074
+ function paint(color, text, colorEnabled) {
37075
+ if (!colorEnabled) {
37076
+ return text;
37077
+ }
37078
+ return `${color}${text}${ANSI_RESET6}`;
37079
+ }
37080
+
37081
+ // ../../packages/fleet-tui/dist/style/banner.js
37082
+ var ASCII_FLEET_BANNER = [
37083
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
37084
+ "\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D",
37085
+ "\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 ",
37086
+ "\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 ",
37087
+ "\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 ",
37088
+ "\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D "
37089
+ ];
37090
+
37091
+ // ../../packages/fleet-tui/dist/style/palette.js
37040
37092
  var FLEET_ACCENT = "\x1B[38;2;254;188;56m";
37041
37093
  var FLEET_OPTION = "\x1B[38;2;125;211;252m";
37042
37094
  var FLEET_COMMAND = "\x1B[38;2;94;234;212m";
@@ -37048,14 +37100,25 @@ var GRADIENT_COLORS = [
37048
37100
  "\x1B[38;2;0;95;255m",
37049
37101
  "\x1B[38;2;0;0;255m"
37050
37102
  ];
37051
- var ASCII_FLEET_BANNER = [
37052
- "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
37053
- "\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D",
37054
- "\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 ",
37055
- "\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 ",
37056
- "\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 ",
37057
- "\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D "
37058
- ];
37103
+
37104
+ // ../../packages/fleet-tui/dist/style/help-tokens.js
37105
+ function resolveColorEnabled(options2 = {}) {
37106
+ const env = options2.env ?? process.env;
37107
+ const isTTY = options2.isTTY ?? process.stdout.isTTY;
37108
+ return isTTY === true && env.NO_COLOR === void 0;
37109
+ }
37110
+ function section(text, colorEnabled) {
37111
+ return paint(`${ANSI_BOLD}${FLEET_ACCENT}`, text, colorEnabled);
37112
+ }
37113
+ function command(text, colorEnabled) {
37114
+ return paint(FLEET_COMMAND, text, colorEnabled);
37115
+ }
37116
+ function option(text, colorEnabled) {
37117
+ return paint(FLEET_OPTION, text, colorEnabled);
37118
+ }
37119
+ function dim(text, colorEnabled) {
37120
+ return paint(ANSI_DIM2, text, colorEnabled);
37121
+ }
37059
37122
 
37060
37123
  // src/mission-control/welcome.ts
37061
37124
  var FLEET_BANNER = ASCII_FLEET_BANNER;
@@ -37095,7 +37158,6 @@ function gradientLine(line) {
37095
37158
  }
37096
37159
 
37097
37160
  // src/mission-control/renderer.ts
37098
- var ANSI_RESET7 = "\x1B[0m";
37099
37161
  var SELECTED_MARKER = "\u25B8";
37100
37162
  var IDLE_MARKER = " ";
37101
37163
  var CHOICE_INDENT = 4;
@@ -37111,17 +37173,17 @@ var FLEET_MENU_ITEMS = [
37111
37173
  "About"
37112
37174
  ];
37113
37175
  var MISSION_CONTROL_THEME = {
37114
- accent: (text) => paint(FLEET_ACCENT, text),
37115
- bg: (name, text) => paint(name === "selected" ? "\x1B[48;2;45;55;70m" : "\x1B[48;2;28;28;36m", text),
37116
- bold: (text) => paint("\x1B[1m", text),
37117
- border: (text) => paint("\x1B[38;5;244m", text),
37118
- dim: (text) => paint("\x1B[38;5;244m", text),
37119
- error: (text) => paint("\x1B[38;2;255;120;120m", text),
37176
+ accent: (text) => paint2(FLEET_ACCENT, text),
37177
+ bg: (name, text) => paint2(name === "selected" ? "\x1B[48;2;45;55;70m" : "\x1B[48;2;28;28;36m", text),
37178
+ bold: (text) => paint2("\x1B[1m", text),
37179
+ border: (text) => paint2("\x1B[38;5;244m", text),
37180
+ dim: (text) => paint2("\x1B[38;5;244m", text),
37181
+ error: (text) => paint2("\x1B[38;2;255;120;120m", text),
37120
37182
  fg: (name, text) => MISSION_CONTROL_THEME[name](text),
37121
- muted: (text) => paint("\x1B[38;2;160;150;180m", text),
37122
- reset: (text) => `${text}${ANSI_RESET7}`,
37123
- success: (text) => paint("\x1B[38;2;80;200;160m", text),
37124
- warning: (text) => paint("\x1B[38;2;255;200;100m", text)
37183
+ muted: (text) => paint2("\x1B[38;2;160;150;180m", text),
37184
+ reset: (text) => `${text}${ANSI_RESET6}`,
37185
+ success: (text) => paint2("\x1B[38;2;80;200;160m", text),
37186
+ warning: (text) => paint2("\x1B[38;2;255;200;100m", text)
37125
37187
  };
37126
37188
  var STYLE = {
37127
37189
  accent: MISSION_CONTROL_THEME.accent,
@@ -37213,7 +37275,7 @@ function renderCountsLine(counts, release2, innerWidth) {
37213
37275
  }
37214
37276
  }
37215
37277
  if (release2 !== void 0 && release2.version.length > 0) {
37216
- const channelLabel = release2.channel === "stable" ? STYLE.success("stable") : release2.channel === "canary" ? STYLE.warning("canary") : STYLE.dim("local");
37278
+ const channelLabel = release2.channel === "stable" ? STYLE.success("stable") : STYLE.dim("local");
37217
37279
  segments.push(`${STYLE.dim(`v${release2.version}`)} ${STYLE.dim("\xB7")} ${channelLabel}`);
37218
37280
  }
37219
37281
  if (segments.length === 0) {
@@ -37226,8 +37288,7 @@ function renderUpdateLine(release2, innerWidth) {
37226
37288
  if (release2?.latestVersion === void 0 || release2.latestVersion === release2.version) {
37227
37289
  return void 0;
37228
37290
  }
37229
- const channel = release2.channel === "canary" ? "canary" : "latest";
37230
- return centerText(STYLE.warning(`\u25C6 Update available \u2014 v${release2.latestVersion} (${channel})`), innerWidth);
37291
+ return centerText(STYLE.warning(`\u25C6 Update available \u2014 v${release2.latestVersion} (latest)`), innerWidth);
37231
37292
  }
37232
37293
  function renderFooterHint(state, innerWidth) {
37233
37294
  const hint = state === "launching" ? "Starting... please wait" : state === "ended" || state === "failed" ? "R relaunch C choose CLI \u2192 model O options M menu X exit Fleet" : "\u2191\u2193/j/k select Enter start \u2192 model O options M menu X exit Fleet";
@@ -37288,12 +37349,12 @@ function formatExitEvent(event) {
37288
37349
  }
37289
37350
  function colorizeProvider(cliId, text) {
37290
37351
  const color = CARRIER_COLORS[cliId] ?? "";
37291
- return color ? `${color}${text}${ANSI_RESET7}` : text;
37352
+ return color ? `${color}${text}${ANSI_RESET6}` : text;
37292
37353
  }
37293
37354
  function computeChoiceWidth(cliOptions) {
37294
37355
  let maxLabelWidth = 0;
37295
- for (const option2 of cliOptions) {
37296
- const width = visibleWidth(option2.label);
37356
+ for (const option3 of cliOptions) {
37357
+ const width = visibleWidth(option3.label);
37297
37358
  if (width > maxLabelWidth) {
37298
37359
  maxLabelWidth = width;
37299
37360
  }
@@ -37315,12 +37376,12 @@ function padEndVisible(text, width) {
37315
37376
  const truncated = truncateToWidth(text, width);
37316
37377
  return `${truncated}${" ".repeat(Math.max(0, width - visibleWidth(truncated)))}`;
37317
37378
  }
37318
- function paint(code, text) {
37319
- return `${code}${text}${ANSI_RESET7}`;
37379
+ function paint2(code, text) {
37380
+ return paint(code, text, true);
37320
37381
  }
37321
37382
 
37322
37383
  // src/carrier-status/taskforce-overlay.ts
37323
- var ANSI_RESET8 = "\x1B[0m";
37384
+ var ANSI_RESET7 = "\x1B[0m";
37324
37385
  var ANSI_DIM3 = "\x1B[38;2;120;120;120m";
37325
37386
  var ANSI_ACCENT = "\x1B[38;2;100;180;255m";
37326
37387
  var TASKFORCE_FRAME_ROWS = 3;
@@ -37387,7 +37448,7 @@ var TaskForceConfigOverlay = class {
37387
37448
  const models = this.getAvailableModels(entry.cliType).models;
37388
37449
  for (let j = 0; j < models.length; j++) {
37389
37450
  const model = models[j];
37390
- const cursor = j === this.editCursor ? `${entry.color}\u25B8${ANSI_RESET8}` : " ";
37451
+ const cursor = j === this.editCursor ? `${entry.color}\u25B8${ANSI_RESET7}` : " ";
37391
37452
  const marker = model.modelId === entry.model ? "\u25CF" : "\u25CB";
37392
37453
  body.push(` ${cursor} ${marker} ${model.name ?? model.modelId}`);
37393
37454
  }
@@ -37396,7 +37457,7 @@ var TaskForceConfigOverlay = class {
37396
37457
  const effortLevels = this.getEffortLevels(entry.cliType, this.pendingModelId ?? entry.model);
37397
37458
  for (let j = 0; j < effortLevels.length; j++) {
37398
37459
  const level = effortLevels[j];
37399
- const cursor = j === this.editCursor ? `${entry.color}\u25B8${ANSI_RESET8}` : " ";
37460
+ const cursor = j === this.editCursor ? `${entry.color}\u25B8${ANSI_RESET7}` : " ";
37400
37461
  const marker = level === (entry.effort ?? "") ? "\u25CF" : "\u25CB";
37401
37462
  body.push(` ${cursor} ${marker} ${level}`);
37402
37463
  }
@@ -37545,14 +37606,14 @@ var TaskForceConfigOverlay = class {
37545
37606
  this.options.requestRender();
37546
37607
  }
37547
37608
  renderEntryLine(entry, isSelected) {
37548
- const selectedPrefix = isSelected ? `${entry.color}\u25B8${ANSI_RESET8}` : " ";
37609
+ const selectedPrefix = isSelected ? `${entry.color}\u25B8${ANSI_RESET7}` : " ";
37549
37610
  const provider = this.getAvailableModels(entry.cliType);
37550
37611
  const modelName = provider.models.find((model) => model.modelId === entry.model)?.name ?? entry.model;
37551
37612
  const modelStr = entry.isCustom ? modelName : this.options.theme.dim(modelName);
37552
37613
  const effortSupported = this.getEffortLevels(entry.cliType, entry.model).length > 0;
37553
37614
  const effortStr = effortSupported && entry.effort ? ` ${this.options.theme.dim("\xB7")} ${entry.isCustom ? entry.effort : this.options.theme.dim(entry.effort)}` : "";
37554
- const configTag = entry.isCustom ? ` ${ANSI_ACCENT}(custom)${ANSI_RESET8}` : ` ${ANSI_DIM3}(origin)${ANSI_RESET8}`;
37555
- return ` ${selectedPrefix} ${entry.color}${entry.displayName}${ANSI_RESET8} ${modelStr}${effortStr}${configTag}`;
37615
+ const configTag = entry.isCustom ? ` ${ANSI_ACCENT}(custom)${ANSI_RESET7}` : ` ${ANSI_DIM3}(origin)${ANSI_RESET7}`;
37616
+ return ` ${selectedPrefix} ${entry.color}${entry.displayName}${ANSI_RESET7} ${modelStr}${effortStr}${configTag}`;
37556
37617
  }
37557
37618
  getBackendConfig(cliType) {
37558
37619
  const snapshot = readStatesSnapshot();
@@ -38654,11 +38715,60 @@ import net from "net";
38654
38715
  import path19 from "path";
38655
38716
  import { fileURLToPath } from "url";
38656
38717
  import os7 from "os";
38718
+ var ANSI_RESET8 = "\x1B[0m";
38719
+ var ANSI_BOLD2 = "\x1B[1m";
38720
+ var ANSI_DIM4 = "\x1B[2m";
38721
+ var ANSI_PATTERN4 = /\x1b\[[0-9;]*m/g;
38722
+ function stripAnsi2(text) {
38723
+ return text.replace(ANSI_PATTERN4, "");
38724
+ }
38725
+ function paint3(color, text, colorEnabled) {
38726
+ if (!colorEnabled) {
38727
+ return text;
38728
+ }
38729
+ return `${color}${text}${ANSI_RESET8}`;
38730
+ }
38731
+ var ASCII_FLEET_BANNER2 = [
38732
+ "\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
38733
+ "\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D",
38734
+ "\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 ",
38735
+ "\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2551 ",
38736
+ "\u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 ",
38737
+ "\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D "
38738
+ ];
38739
+ var FLEET_ACCENT2 = "\x1B[38;2;254;188;56m";
38740
+ var FLEET_OPTION2 = "\x1B[38;2;125;211;252m";
38741
+ var FLEET_COMMAND2 = "\x1B[38;2;94;234;212m";
38742
+ var GRADIENT_COLORS2 = [
38743
+ "\x1B[38;2;0;255;255m",
38744
+ "\x1B[38;2;0;215;255m",
38745
+ "\x1B[38;2;0;175;255m",
38746
+ "\x1B[38;2;0;135;255m",
38747
+ "\x1B[38;2;0;95;255m",
38748
+ "\x1B[38;2;0;0;255m"
38749
+ ];
38750
+ function resolveColorEnabled2(options2 = {}) {
38751
+ const env = options2.env ?? process.env;
38752
+ const isTTY = options2.isTTY ?? process.stdout.isTTY;
38753
+ return isTTY === true && env.NO_COLOR === void 0;
38754
+ }
38755
+ function section2(text, colorEnabled) {
38756
+ return paint3(`${ANSI_BOLD2}${FLEET_ACCENT2}`, text, colorEnabled);
38757
+ }
38758
+ function command2(text, colorEnabled) {
38759
+ return paint3(FLEET_COMMAND2, text, colorEnabled);
38760
+ }
38761
+ function option2(text, colorEnabled) {
38762
+ return paint3(FLEET_OPTION2, text, colorEnabled);
38763
+ }
38764
+ function dim2(text, colorEnabled) {
38765
+ return paint3(ANSI_DIM4, text, colorEnabled);
38766
+ }
38657
38767
  async function openBrowser(url2) {
38658
38768
  if (process.env.FLEET_WIKI_NO_BROWSER === "1") return;
38659
- const command2 = browserCommand(url2);
38769
+ const command22 = browserCommand(url2);
38660
38770
  await new Promise((resolve, reject) => {
38661
- const child = spawn3(command2.command, command2.args, {
38771
+ const child = spawn3(command22.command, command22.args, {
38662
38772
  detached: true,
38663
38773
  stdio: "ignore",
38664
38774
  shell: false
@@ -38825,9 +38935,6 @@ function isLockTrustworthyForRestart(lock, currentCwd, healthResponseCwd, curren
38825
38935
  if (!Number.isInteger(lock.pid) || lock.pid <= 1) {
38826
38936
  return { trusted: false, reason: `pid \uAC80\uC99D \uC2E4\uD328(${lock.pid})` };
38827
38937
  }
38828
- if (lock.host !== void 0 && lock.host !== DEFAULT_HOST) {
38829
- return { trusted: false, reason: `host \uBD88\uC77C\uCE58(lock=${lock.host}, current=${DEFAULT_HOST})` };
38830
- }
38831
38938
  if (lock.host !== void 0 && currentHost !== void 0 && lock.host !== currentHost) {
38832
38939
  return { trusted: false, reason: `host \uBD88\uC77C\uCE58(lock=${lock.host}, current=${currentHost})` };
38833
38940
  }
@@ -38842,28 +38949,13 @@ var HEALTH_TIMEOUT_MS = 5e3;
38842
38949
  var HEALTH_INTERVAL_MS = 150;
38843
38950
  var TRAMPOLINE_ENV = "FLEET_WIKI_TRAMPOLINED";
38844
38951
  var SIGNAL_EXIT_FALLBACK_MS = 1e3;
38845
- var HELP_TEXT = [
38846
- "Fleet Wiki \uC6F9\uC11C\uBC84 \uC2E4\uD589/\uC885\uB8CC \uB3C4\uAD6C",
38847
- "",
38848
- "\uC0AC\uC6A9\uBC95:",
38849
- " fleet-wiki [--port <port>]",
38850
- " fleet-wiki --stop",
38851
- " fleet-wiki --help",
38852
- "",
38853
- "\uC635\uC158:",
38854
- " --port <port> \uC11C\uBC84 \uD3EC\uD2B8\uB97C \uC9C0\uC815\uD569\uB2C8\uB2E4.",
38855
- " --stop \uC0AC\uC6A9\uC790 Fleet Wiki daemon \uC804\uCCB4\uB97C \uC885\uB8CC\uD569\uB2C8\uB2E4.",
38856
- " --help \uC774 \uB3C4\uC6C0\uB9D0\uC744 \uCD9C\uB825\uD569\uB2C8\uB2E4.",
38857
- "",
38858
- "\uD658\uACBD\uBCC0\uC218:",
38859
- " FLEET_WIKI_PORT \uAE30\uBCF8 \uD3EC\uD2B8\uB97C \uC9C0\uC815\uD569\uB2C8\uB2E4.",
38860
- " FLEET_WIKI_NO_AUTO_RESTART \uAE30\uC874 \uC11C\uBC84 \uC790\uB3D9 \uC7AC\uC2DC\uC791\uC744 \uBE44\uD65C\uC131\uD654\uD569\uB2C8\uB2E4.",
38861
- "",
38862
- "\uC608\uC2DC:",
38863
- " fleet-wiki",
38864
- " FLEET_WIKI_PORT=4040 fleet-wiki",
38865
- " fleet-wiki --stop"
38866
- ].join("\n");
38952
+ var HELP_BANNER_INDENT = " ";
38953
+ var DEFAULT_HELP_RELEASE = "local";
38954
+ var RFC1123_HOSTNAME = /^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)*[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/;
38955
+ var IPV4_WILDCARD_HOST = "0.0.0.0";
38956
+ var IPV4_LOOPBACK_HOST = "127.0.0.1";
38957
+ var IPV6_WILDCARD_HOSTS = /* @__PURE__ */ new Set(["::", "0:0:0:0:0:0:0:0"]);
38958
+ var IPV6_LOOPBACK_HOST = "::1";
38867
38959
  function parseCliArgs(argv2) {
38868
38960
  const result = { mode: "run" };
38869
38961
  for (let i = 0; i < argv2.length; i++) {
@@ -38882,24 +38974,36 @@ function parseCliArgs(argv2) {
38882
38974
  i += 1;
38883
38975
  const port = Number(raw);
38884
38976
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
38885
- process.stderr.write(`--port \uAC12\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${raw}
38977
+ process.stderr.write(`Invalid --port value: ${raw}
38886
38978
  `);
38887
38979
  process.exit(1);
38888
38980
  return result;
38889
38981
  }
38890
38982
  result.port = port;
38983
+ } else if (arg === "--host") {
38984
+ const raw = argv2[i + 1];
38985
+ if (!raw || raw.startsWith("--")) {
38986
+ process.stderr.write("--host requires a value\n");
38987
+ process.exit(1);
38988
+ return result;
38989
+ }
38990
+ i += 1;
38991
+ result.host = parseHostValue(raw);
38891
38992
  } else if (arg.startsWith("--port=")) {
38892
38993
  const raw = arg.slice("--port=".length);
38893
38994
  const port = Number(raw);
38894
38995
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
38895
- process.stderr.write(`--port \uAC12\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${raw}
38996
+ process.stderr.write(`Invalid --port value: ${raw}
38896
38997
  `);
38897
38998
  process.exit(1);
38898
38999
  return result;
38899
39000
  }
38900
39001
  result.port = port;
39002
+ } else if (arg.startsWith("--host=")) {
39003
+ const raw = arg.slice("--host=".length);
39004
+ result.host = parseHostValue(raw);
38901
39005
  } else if (arg.startsWith("--")) {
38902
- process.stderr.write(`\uC54C \uC218 \uC5C6\uB294 \uC635\uC158: ${arg}
39006
+ process.stderr.write(`Unknown option: ${arg}
38903
39007
  `);
38904
39008
  process.exit(1);
38905
39009
  return result;
@@ -38907,6 +39011,39 @@ function parseCliArgs(argv2) {
38907
39011
  }
38908
39012
  return result;
38909
39013
  }
39014
+ function buildWikiHelpText(options2 = {}) {
39015
+ const colorEnabled = resolveColorEnabled2(options2);
39016
+ const subtitle = `Fleet Wiki \xB7 ${options2.release ?? DEFAULT_HELP_RELEASE}`;
39017
+ const lines = [
39018
+ ...ASCII_FLEET_BANNER2.map(
39019
+ (line, index) => `${HELP_BANNER_INDENT}${paint3(GRADIENT_COLORS2[index] ?? FLEET_COMMAND2, line, colorEnabled)}`
39020
+ ),
39021
+ dim2(subtitle, colorEnabled),
39022
+ "",
39023
+ section2("USAGE", colorEnabled),
39024
+ ` ${command2("fleet wiki", colorEnabled)} ${dim2("[--host <addr>] [--port <port>] [--stop] [--help]", colorEnabled)}`,
39025
+ ` ${dim2("Standalone binary:", colorEnabled)} ${command2("fleet-wiki", colorEnabled)} ${dim2("[--host <addr>] [--port <port>]", colorEnabled)}`,
39026
+ "",
39027
+ section2("OPTIONS", colorEnabled),
39028
+ ` ${option2("--host <addr>", colorEnabled)} ${dim2("Bind the daemon to an IP or RFC1123 hostname; non-loopback hosts expose GET reads on the LAN.", colorEnabled)}`,
39029
+ ` ${option2("--port <port>", colorEnabled)} ${dim2("Set the local Fleet Wiki daemon port.", colorEnabled)}`,
39030
+ ` ${option2("--stop", colorEnabled)} ${dim2("Stop the user's Fleet Wiki daemon.", colorEnabled)}`,
39031
+ ` ${option2("--help", colorEnabled)} ${dim2("Show this help message and exit.", colorEnabled)}`,
39032
+ "",
39033
+ section2("ENVIRONMENT", colorEnabled),
39034
+ ` ${option2("FLEET_WIKI_PORT", colorEnabled)} ${dim2("Set the default port.", colorEnabled)}`,
39035
+ ` ${option2("FLEET_WIKI_NO_AUTO_RESTART", colorEnabled)} ${dim2("Disable automatic restart of stale daemons.", colorEnabled)}`,
39036
+ "",
39037
+ section2("EXAMPLES", colorEnabled),
39038
+ ` ${command2("fleet wiki", colorEnabled)}`,
39039
+ ` ${command2("fleet wiki --host 0.0.0.0", colorEnabled)} ${dim2("# explicit LAN read-share; write/admin stay loopback-only", colorEnabled)}`,
39040
+ ` FLEET_WIKI_PORT=4040 ${command2("fleet wiki", colorEnabled)}`,
39041
+ ` ${command2("fleet wiki --stop", colorEnabled)}`,
39042
+ ""
39043
+ ];
39044
+ const text = lines.join("\n");
39045
+ return colorEnabled ? text : stripAnsi2(text);
39046
+ }
38910
39047
  function evaluateRestartDecision(existing, cwd, health, noAutoRestart, host, stale = false) {
38911
39048
  const trust = isLockTrustworthyForRestart(existing, cwd, health.cwd, host);
38912
39049
  if (!trust.trusted) {
@@ -38938,7 +39075,7 @@ async function openFleetWikiWorkspace(options2) {
38938
39075
  const lockPath = lockFilePath();
38939
39076
  const lock = await ensureServer(cwd, lockPath, host, port);
38940
39077
  const workspace = await registerWorkspace(lock, cwd);
38941
- const url2 = `${serverUrl(lock.host, lock.port)}${workspace.urlPath}`;
39078
+ const url2 = `${serverUrl(resolveBrowserOpenHost(lock.host), lock.port)}${workspace.urlPath}`;
38942
39079
  await openBrowser(url2);
38943
39080
  return { host: lock.host, pid: lock.pid, port: lock.port, url: url2 };
38944
39081
  }
@@ -38955,7 +39092,7 @@ async function probeFleetWikiDaemon(_options) {
38955
39092
  host: lock.host,
38956
39093
  pid: lock.pid,
38957
39094
  port: lock.port,
38958
- url: serverUrl(lock.host, lock.port)
39095
+ url: serverUrl(resolveBrowserOpenHost(lock.host), lock.port)
38959
39096
  };
38960
39097
  }
38961
39098
  async function main() {
@@ -38969,7 +39106,7 @@ async function main() {
38969
39106
  await stopDaemon();
38970
39107
  return;
38971
39108
  }
38972
- await openFleetWikiWorkspace({ cwd, port: cliArgs.port });
39109
+ await openFleetWikiWorkspace({ cwd, host: cliArgs.host, port: cliArgs.port });
38973
39110
  }
38974
39111
  function findLocalCliMjs(cwd) {
38975
39112
  let currentDir = path19.resolve(cwd);
@@ -39013,6 +39150,17 @@ function formatHostForUrl(host) {
39013
39150
  function serverUrl(host, port) {
39014
39151
  return `http://${formatHostForUrl(host)}:${port}`;
39015
39152
  }
39153
+ function resolveLocalControlHost(bindHost) {
39154
+ if (bindHost === IPV4_WILDCARD_HOST) return IPV4_LOOPBACK_HOST;
39155
+ if (IPV6_WILDCARD_HOSTS.has(bindHost)) return IPV6_LOOPBACK_HOST;
39156
+ if (!isLoopbackHost(bindHost)) return IPV4_LOOPBACK_HOST;
39157
+ return bindHost;
39158
+ }
39159
+ function resolveBrowserOpenHost(bindHost) {
39160
+ if (bindHost === IPV4_WILDCARD_HOST) return IPV4_LOOPBACK_HOST;
39161
+ if (IPV6_WILDCARD_HOSTS.has(bindHost)) return IPV6_LOOPBACK_HOST;
39162
+ return bindHost;
39163
+ }
39016
39164
  async function directoryExists(dirPath) {
39017
39165
  try {
39018
39166
  return (await stat(dirPath)).isDirectory();
@@ -39021,8 +39169,7 @@ async function directoryExists(dirPath) {
39021
39169
  }
39022
39170
  }
39023
39171
  function printHelp() {
39024
- process.stdout.write(`${HELP_TEXT}
39025
- `);
39172
+ process.stdout.write(buildWikiHelpText({ env: process.env, isTTY: process.stdout.isTTY }));
39026
39173
  }
39027
39174
  async function ensureServer(cwd, lockPath, host, port) {
39028
39175
  for (let attempt = 0; attempt < 3; attempt += 1) {
@@ -39059,14 +39206,14 @@ async function ensureServer(cwd, lockPath, host, port) {
39059
39206
  if (existing) {
39060
39207
  await removeLockFile(lockPath);
39061
39208
  }
39062
- spawnDetachedServer(cwd, lockPath, port);
39209
+ spawnDetachedServer(cwd, lockPath, host, port);
39063
39210
  return waitForHealthyLock(lockPath, { trust: "existing" }, host);
39064
39211
  }
39065
39212
  throw new Error("Fleet Wiki \uC11C\uBC84 \uB77D\uC744 \uD68D\uB4DD\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
39066
39213
  }
39067
- function spawnDetachedServer(cwd, lockPath, port) {
39214
+ function spawnDetachedServer(cwd, lockPath, host, port) {
39068
39215
  const serverPath = fileURLToPath(new URL("./server.mjs", import.meta.url));
39069
- const child = spawn3(process.execPath, [serverPath, "--cwd", cwd, "--lock", lockPath, "--port", String(port)], {
39216
+ const child = spawn3(process.execPath, [serverPath, "--cwd", cwd, "--lock", lockPath, "--host", host, "--port", String(port)], {
39070
39217
  cwd,
39071
39218
  detached: true,
39072
39219
  stdio: "ignore",
@@ -39096,7 +39243,7 @@ async function waitForHealthyLock(lockPath, options2, host) {
39096
39243
  }
39097
39244
  async function healthCheck(lock) {
39098
39245
  try {
39099
- const response = await fetch(`${serverUrl(lock.host, lock.port)}/api/health`);
39246
+ const response = await fetch(`${serverUrl(resolveLocalControlHost(lock.host), lock.port)}/api/health`);
39100
39247
  if (response.status !== 200) return { ok: false, cwd: null };
39101
39248
  const body = await response.json();
39102
39249
  return { ok: body.ok === true, cwd: typeof body.cwd === "string" ? body.cwd : null };
@@ -39114,7 +39261,7 @@ async function isExistingDaemonStale(lock) {
39114
39261
  }
39115
39262
  }
39116
39263
  async function registerWorkspace(lock, cwd) {
39117
- const response = await fetch(`${serverUrl(lock.host, lock.port)}/api/admin/workspaces`, {
39264
+ const response = await fetch(`${serverUrl(resolveLocalControlHost(lock.host), lock.port)}/api/admin/workspaces`, {
39118
39265
  method: "POST",
39119
39266
  headers: {
39120
39267
  authorization: `Bearer ${lock.token}`,
@@ -39140,6 +39287,23 @@ function configuredPort() {
39140
39287
  }
39141
39288
  return port;
39142
39289
  }
39290
+ function parseHostValue(raw) {
39291
+ if (!isValidHostValue(raw)) {
39292
+ process.stderr.write(`Invalid --host value: ${raw}
39293
+ `);
39294
+ process.exit(1);
39295
+ return raw;
39296
+ }
39297
+ return raw;
39298
+ }
39299
+ function isValidHostValue(raw) {
39300
+ if (!raw) return false;
39301
+ if (net.isIP(raw) !== 0) return true;
39302
+ return RFC1123_HOSTNAME.test(raw);
39303
+ }
39304
+ function isLoopbackHost(host) {
39305
+ return host === IPV4_LOOPBACK_HOST || host === IPV6_LOOPBACK_HOST || host === "localhost";
39306
+ }
39143
39307
  async function killServer(pid) {
39144
39308
  if (!signalProcess(pid, "SIGTERM")) {
39145
39309
  return;
@@ -40272,7 +40436,7 @@ async function readWorkspaceSchemaSummary(paths) {
40272
40436
  summary: extractSchemaSummary(wikiSchemaContent),
40273
40437
  requiredSections: REQUIRED_WORKSPACE_SCHEMA_SECTIONS,
40274
40438
  missingRequiredSections: REQUIRED_WORKSPACE_SCHEMA_SECTIONS.filter(
40275
- (section2) => !wikiSchemaContent.includes(`## ${section2}`)
40439
+ (section3) => !wikiSchemaContent.includes(`## ${section3}`)
40276
40440
  ),
40277
40441
  templates
40278
40442
  };
@@ -40316,7 +40480,7 @@ async function validateTemplateCompliance(paths, templateId, body) {
40316
40480
  throw new Error(`[fleet-wiki] selected template has no required sections: ${templateId}`);
40317
40481
  }
40318
40482
  const bodySections = new Set(parseRequiredSections(body));
40319
- const missing = template.sections.filter((section2) => !bodySections.has(section2));
40483
+ const missing = template.sections.filter((section3) => !bodySections.has(section3));
40320
40484
  if (missing.length > 0) {
40321
40485
  throw new Error(
40322
40486
  `[fleet-wiki] template compliance failed for template "${templateId}": missing sections: ${missing.join(", ")}`
@@ -40373,7 +40537,7 @@ function parseTemplateMarkdown(content) {
40373
40537
  return { frontmatter, body };
40374
40538
  }
40375
40539
  function parseRequiredSections(content) {
40376
- return content.replace(/\r\n/g, "\n").split("\n").map((line) => line.match(/^##\s+(.+?)\s*$/)?.[1]?.trim()).filter((section2) => Boolean(section2));
40540
+ return content.replace(/\r\n/g, "\n").split("\n").map((line) => line.match(/^##\s+(.+?)\s*$/)?.[1]?.trim()).filter((section3) => Boolean(section3));
40377
40541
  }
40378
40542
  function isAlreadyExistsError(error51) {
40379
40543
  return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "EEXIST";
@@ -43359,13 +43523,13 @@ async function schemaIssues(paths) {
43359
43523
  } else {
43360
43524
  const schemaContent = await readPatchFile(schema.wikiSchemaPath);
43361
43525
  issues.push(...safetyIssues(schemaContent, schema.wikiSchemaPath));
43362
- for (const section2 of schema.missingRequiredSections) {
43363
- if (REQUIRED_WORKSPACE_SCHEMA_SECTIONS.includes(section2)) {
43526
+ for (const section3 of schema.missingRequiredSections) {
43527
+ if (REQUIRED_WORKSPACE_SCHEMA_SECTIONS.includes(section3)) {
43364
43528
  issues.push(
43365
43529
  issue2(
43366
43530
  "schema_required_section_missing",
43367
43531
  "warning",
43368
- `Workspace schema required section missing: ${section2}`,
43532
+ `Workspace schema required section missing: ${section3}`,
43369
43533
  schema.wikiSchemaPath
43370
43534
  )
43371
43535
  );
@@ -43397,7 +43561,7 @@ async function templateComplianceIssues(paths, entries) {
43397
43561
  continue;
43398
43562
  }
43399
43563
  const bodySections = new Set(parseBodySections(entry.body));
43400
- const missing = template.sections.filter((section2) => !bodySections.has(section2));
43564
+ const missing = template.sections.filter((section3) => !bodySections.has(section3));
43401
43565
  if (missing.length > 0) {
43402
43566
  issues.push(
43403
43567
  issue2(
@@ -43623,7 +43787,7 @@ function asStringArray(value) {
43623
43787
  return Array.isArray(value) ? value.map((item) => String(item)) : [];
43624
43788
  }
43625
43789
  function parseBodySections(body) {
43626
- return body.replace(/\r\n/g, "\n").split("\n").map((line) => line.match(/^##\s+(.+?)\s*$/)?.[1]?.trim()).filter((section2) => Boolean(section2));
43790
+ return body.replace(/\r\n/g, "\n").split("\n").map((line) => line.match(/^##\s+(.+?)\s*$/)?.[1]?.trim()).filter((section3) => Boolean(section3));
43627
43791
  }
43628
43792
  function normalizeLookupKey(value) {
43629
43793
  return value.toLowerCase().replace(/\s+/g, " ").trim();
@@ -44381,17 +44545,17 @@ function truncateIndexSummary(payload) {
44381
44545
  if (!payload.index_summary || payload.token_estimate.fields_truncated.includes("index_summary.content")) {
44382
44546
  return;
44383
44547
  }
44384
- const section2 = payload.index_summary;
44385
- section2.content = truncateString(section2.content);
44386
- section2.truncated = true;
44548
+ const section3 = payload.index_summary;
44549
+ section3.content = truncateString(section3.content);
44550
+ section3.truncated = true;
44387
44551
  payload.token_estimate.fields_truncated.push("index_summary.content");
44388
44552
  }
44389
44553
  function truncateRecentLogEntries(payload) {
44390
44554
  if (!payload.recent_log) return false;
44391
- const section2 = payload.recent_log;
44392
- if (section2.entries.length <= 1) return false;
44393
- section2.entries.pop();
44394
- section2.truncated = true;
44555
+ const section3 = payload.recent_log;
44556
+ if (section3.entries.length <= 1) return false;
44557
+ section3.entries.pop();
44558
+ section3.truncated = true;
44395
44559
  if (!payload.token_estimate.fields_truncated.includes("recent_log.entries")) {
44396
44560
  payload.token_estimate.fields_truncated.push("recent_log.entries");
44397
44561
  }
@@ -44399,13 +44563,13 @@ function truncateRecentLogEntries(payload) {
44399
44563
  }
44400
44564
  function shortenRecentLogEntry(payload) {
44401
44565
  if (!payload.recent_log) return false;
44402
- const section2 = payload.recent_log;
44403
- if (section2.entries.length === 0) return false;
44404
- const lastIndex = section2.entries.length - 1;
44405
- const current = section2.entries[lastIndex];
44566
+ const section3 = payload.recent_log;
44567
+ if (section3.entries.length === 0) return false;
44568
+ const lastIndex = section3.entries.length - 1;
44569
+ const current = section3.entries[lastIndex];
44406
44570
  if (current.endsWith(TRUNCATION_MARKER)) return false;
44407
- section2.entries[lastIndex] = truncateString(current);
44408
- section2.truncated = true;
44571
+ section3.entries[lastIndex] = truncateString(current);
44572
+ section3.truncated = true;
44409
44573
  if (!payload.token_estimate.fields_truncated.includes(`recent_log.entries[${lastIndex}]`)) {
44410
44574
  payload.token_estimate.fields_truncated.push(`recent_log.entries[${lastIndex}]`);
44411
44575
  }
@@ -45973,8 +46137,6 @@ function countMarkdownFilesRecursively(dir, isWikiRoot) {
45973
46137
  }
45974
46138
 
45975
46139
  // src/sections/fleet-status-section.ts
45976
- var ANSI_RESET9 = "\x1B[0m";
45977
- var DIM_COLOR = "\x1B[38;5;244m";
45978
46140
  var BORDER_CHAR = "\u2500";
45979
46141
  var PROTOCOL_ICON = "\u2693";
45980
46142
  var FleetStatusSection = class {
@@ -45993,7 +46155,7 @@ var FleetStatusSection = class {
45993
46155
  };
45994
46156
  function renderStatusLine2(width, protocolColor, protocolLabel) {
45995
46157
  if (width <= 0) return "";
45996
- const centerBlock = colorize2(` ${PROTOCOL_ICON} ${protocolLabel} `, protocolColor);
46158
+ const centerBlock = paint(protocolColor, ` ${PROTOCOL_ICON} ${protocolLabel} `, true);
45997
46159
  const centerWidth = visibleWidth(centerBlock);
45998
46160
  if (centerWidth >= width) return truncateToWidth(centerBlock, width);
45999
46161
  const remainingWidth = width - centerWidth;
@@ -46001,27 +46163,24 @@ function renderStatusLine2(width, protocolColor, protocolLabel) {
46001
46163
  const rightWidth = remainingWidth - leftWidth;
46002
46164
  return renderBorder(leftWidth, protocolColor) + centerBlock + renderBorder(rightWidth, protocolColor);
46003
46165
  }
46004
- function colorize2(text, color) {
46005
- return `${color}${text}${ANSI_RESET9}`;
46006
- }
46007
46166
  function renderBorder(width, color) {
46008
46167
  if (width <= 0) return "";
46009
- return colorize2(BORDER_CHAR.repeat(width), color);
46168
+ return paint(color, BORDER_CHAR.repeat(width), true);
46010
46169
  }
46011
46170
 
46012
46171
  // src/sections/default-sections.ts
46013
46172
  function createDefaultFleetPtyComponent(sections) {
46014
46173
  return {
46015
46174
  desiredHeight(maxRows) {
46016
- return Math.min(maxRows, sections.reduce((sum, section2) => sum + (section2.component.desiredHeight?.(maxRows) ?? 1), 0));
46175
+ return Math.min(maxRows, sections.reduce((sum, section3) => sum + (section3.component.desiredHeight?.(maxRows) ?? 1), 0));
46017
46176
  },
46018
46177
  invalidate() {
46019
- for (const section2 of sections) {
46020
- section2.component.invalidate();
46178
+ for (const section3 of sections) {
46179
+ section3.component.invalidate();
46021
46180
  }
46022
46181
  },
46023
46182
  render(width) {
46024
- return sections.flatMap((section2) => section2.component.render(width));
46183
+ return sections.flatMap((section3) => section3.component.render(width));
46025
46184
  }
46026
46185
  };
46027
46186
  }
@@ -46570,9 +46729,9 @@ var NONBLOCK_FLAG2 = fs7.constants.O_NONBLOCK ?? 0;
46570
46729
  var SECURE_DIR_MODE3 = 448;
46571
46730
  function loadSection(key) {
46572
46731
  const global = readGlobalJson();
46573
- const section2 = global[key];
46574
- if (typeof section2 !== "object" || section2 === null) return {};
46575
- return section2;
46732
+ const section3 = global[key];
46733
+ if (typeof section3 !== "object" || section3 === null) return {};
46734
+ return section3;
46576
46735
  }
46577
46736
  function saveSection(key, data) {
46578
46737
  const global = readGlobalJson();
@@ -47075,7 +47234,9 @@ async function runApp(options2 = {}) {
47075
47234
  });
47076
47235
  syncCursorPolicy = createCursorPolicySync({
47077
47236
  cursorSync: true,
47237
+ cursorSyncExplicitlyEnabled: argvOptions.cursorSyncExplicitlyEnabled,
47078
47238
  fleetPty,
47239
+ getActiveAgentProfileId: () => missionControl.getActiveProfile()?.id,
47079
47240
  getMode: router.getMode,
47080
47241
  hasActiveMissionControlPanel: missionControl.hasActivePanel,
47081
47242
  isModeToggleSuppressed: () => modeToggleSuppressed,
@@ -47125,6 +47286,7 @@ function createRunAppArgOptions(options2) {
47125
47286
  cursorSync: options2.cursorSync === false
47126
47287
  },
47127
47288
  cursorSync: options2.cursorSync !== false,
47289
+ cursorSyncExplicitlyEnabled: false,
47128
47290
  help: false
47129
47291
  };
47130
47292
  }
@@ -47172,11 +47334,14 @@ function stopApp(ui, ptyHost, resize, disposeInputStream, unsubscribeJobBar, run
47172
47334
 
47173
47335
  // src/cli-args.ts
47174
47336
  init_release();
47175
- var HELP_BANNER_INDENT = " ";
47337
+ var FALSE_VALUES2 = /* @__PURE__ */ new Set(["0", "false", "no", "off"]);
47338
+ var HELP_BANNER_INDENT2 = " ";
47176
47339
  var HELP_HINT = "Run 'fleet --help' for usage.";
47177
- var ANSI_PATTERN3 = /\x1b\[[0-9;]*m/g;
47340
+ var TRUE_VALUES2 = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
47178
47341
  function parseFleetCliOptions(argv2, env = process.env) {
47179
- let cursorSync = parseCursorSyncEnv2(env.FLEET_CURSOR_SYNC);
47342
+ const cursorSyncEnv = parseCursorSyncEnv2(env.FLEET_CURSOR_SYNC);
47343
+ let cursorSync = cursorSyncEnv.value;
47344
+ let cursorSyncExplicitlyEnabled = cursorSyncEnv.explicitlyEnabled;
47180
47345
  let help = false;
47181
47346
  const argvOverrides = createEmptyArgOverrides();
47182
47347
  for (let index = 0; index < argv2.length; index += 1) {
@@ -47185,12 +47350,13 @@ function parseFleetCliOptions(argv2, env = process.env) {
47185
47350
  help = true;
47186
47351
  } else if (arg === "--disable-cursor-sync") {
47187
47352
  cursorSync = false;
47353
+ cursorSyncExplicitlyEnabled = false;
47188
47354
  argvOverrides.cursorSync = true;
47189
47355
  } else {
47190
47356
  throw new Error(formatUnknownFleetOption(arg));
47191
47357
  }
47192
47358
  }
47193
- return { cursorSync, argvOverrides, help };
47359
+ return { cursorSync, cursorSyncExplicitlyEnabled, argvOverrides, help };
47194
47360
  }
47195
47361
  function buildFleetHelpText(options2 = {}) {
47196
47362
  const release2 = options2.release ?? readFleetCliRelease();
@@ -47198,14 +47364,14 @@ function buildFleetHelpText(options2 = {}) {
47198
47364
  const subtitle = `Fleet Harness \xB7 ${release2.version} \xB7 ${release2.channel}`;
47199
47365
  const lines = [
47200
47366
  ...ASCII_FLEET_BANNER.map(
47201
- (line, index) => `${HELP_BANNER_INDENT}${paintLine(GRADIENT_COLORS[index] ?? FLEET_COMMAND, line, colorEnabled)}`
47367
+ (line, index) => `${HELP_BANNER_INDENT2}${paint(GRADIENT_COLORS[index] ?? FLEET_COMMAND, line, colorEnabled)}`
47202
47368
  ),
47203
47369
  dim(subtitle, colorEnabled),
47204
47370
  "",
47205
47371
  section("USAGE", colorEnabled),
47206
47372
  ` ${command("fleet", colorEnabled)} ${dim("[options]", colorEnabled)}`,
47207
47373
  ` ${command("fleet auth", colorEnabled)} ${dim("<login|list|logout> [claude-zai|claude-kimi]", colorEnabled)}`,
47208
- ` ${command("fleet wiki", colorEnabled)} ${dim("[--port <port>] [--stop] [--help]", colorEnabled)}`,
47374
+ ` ${command("fleet wiki", colorEnabled)} ${dim("[--host <addr>] [--port <port>] [--stop] [--help]", colorEnabled)}`,
47209
47375
  ` ${command("fleet update", colorEnabled)}`,
47210
47376
  "",
47211
47377
  section("COMMANDS", colorEnabled),
@@ -47218,6 +47384,8 @@ function buildFleetHelpText(options2 = {}) {
47218
47384
  ` ${option("--disable-cursor-sync", colorEnabled)}`,
47219
47385
  ` ${dim("Disable outer-terminal cursor projection for terminals", colorEnabled)}`,
47220
47386
  ` ${dim("with problematic IME cursor anchoring.", colorEnabled)}`,
47387
+ ` ${dim("Claude Code on Windows defaults to disabled; set", colorEnabled)}`,
47388
+ ` ${dim("FLEET_CURSOR_SYNC=1 to override.", colorEnabled)}`,
47221
47389
  ""
47222
47390
  ];
47223
47391
  const text = `${lines.join("\n")}`;
@@ -47228,45 +47396,22 @@ function createEmptyArgOverrides() {
47228
47396
  cursorSync: false
47229
47397
  };
47230
47398
  }
47231
- function formatUnknownFleetOption(option2) {
47232
- return `Unknown fleet option: ${option2}
47399
+ function formatUnknownFleetOption(option3) {
47400
+ return `Unknown fleet option: ${option3}
47233
47401
  ${HELP_HINT}`;
47234
47402
  }
47235
- function resolveColorEnabled(options2) {
47236
- const env = options2.env ?? process.env;
47237
- const isTTY = options2.isTTY ?? process.stdout.isTTY;
47238
- return isTTY === true && env.NO_COLOR === void 0;
47239
- }
47240
- function section(text, colorEnabled) {
47241
- return paint2(`${ANSI_BOLD}${FLEET_ACCENT}`, text, colorEnabled);
47242
- }
47243
- function command(text, colorEnabled) {
47244
- return paint2(FLEET_COMMAND, text, colorEnabled);
47245
- }
47246
- function option(text, colorEnabled) {
47247
- return paint2(FLEET_OPTION, text, colorEnabled);
47248
- }
47249
- function dim(text, colorEnabled) {
47250
- return paint2(ANSI_DIM2, text, colorEnabled);
47251
- }
47252
- function paintLine(color, text, colorEnabled) {
47253
- return paint2(color, text, colorEnabled);
47254
- }
47255
- function paint2(color, text, colorEnabled) {
47256
- if (!colorEnabled) {
47257
- return text;
47258
- }
47259
- return `${color}${text}${ANSI_RESET6}`;
47260
- }
47261
- function stripAnsi(text) {
47262
- return text.replace(ANSI_PATTERN3, "");
47263
- }
47264
47403
  function parseCursorSyncEnv2(value) {
47265
47404
  if (value === void 0) {
47266
- return true;
47405
+ return { explicitlyEnabled: false, value: true };
47267
47406
  }
47268
47407
  const normalized = value.trim().toLowerCase();
47269
- return normalized !== "0" && normalized !== "false";
47408
+ if (TRUE_VALUES2.has(normalized)) {
47409
+ return { explicitlyEnabled: true, value: true };
47410
+ }
47411
+ if (FALSE_VALUES2.has(normalized)) {
47412
+ return { explicitlyEnabled: false, value: false };
47413
+ }
47414
+ return { explicitlyEnabled: false, value: true };
47270
47415
  }
47271
47416
 
47272
47417
  // src/update/dispatcher.ts
@@ -47276,13 +47421,13 @@ Usage:
47276
47421
  fleet update
47277
47422
  `;
47278
47423
  async function dispatchUpdateCommand(argv2, io) {
47279
- const command2 = argv2[1];
47280
- if (command2 === "--help" || command2 === "-h") {
47424
+ const command3 = argv2[1];
47425
+ if (command3 === "--help" || command3 === "-h") {
47281
47426
  io.stdout.write(UPDATE_HELP_TEXT);
47282
47427
  return 0;
47283
47428
  }
47284
- if (command2 !== void 0) {
47285
- io.stderr.write(`Unknown fleet update command: ${command2}
47429
+ if (command3 !== void 0) {
47430
+ io.stderr.write(`Unknown fleet update command: ${command3}
47286
47431
  `);
47287
47432
  io.stdout.write(UPDATE_HELP_TEXT);
47288
47433
  return 1;