claude-threads 1.37.2 → 1.38.1

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
@@ -2232,6 +2232,35 @@ function resolveOverheadVisibility(value, fieldPath) {
2232
2232
  return value;
2233
2233
  throw new Error(`Invalid ${fieldPath}: expected one of ${OVERHEAD_VISIBILITY_VALUES.join(", ")}, got ${JSON.stringify(value)}`);
2234
2234
  }
2235
+ function isPresentationMode(value) {
2236
+ return typeof value === "string" && PRESENTATION_MODE_VALUES.includes(value);
2237
+ }
2238
+ function resolvePresentationMode(value, fieldPath) {
2239
+ if (value === undefined || value === null)
2240
+ return "full";
2241
+ if (isPresentationMode(value))
2242
+ return value;
2243
+ throw new Error(`Invalid ${fieldPath}: expected one of ${PRESENTATION_MODE_VALUES.join(", ")}, got ${JSON.stringify(value)}`);
2244
+ }
2245
+ function resolvePresentationOverhead(entry, fieldPath) {
2246
+ const preset = PRESENTATION_MODE_EXPANSIONS[resolvePresentationMode(entry.mode, `${fieldPath}.mode`)];
2247
+ const override = (value, field, fallback) => value === undefined || value === null ? fallback : resolveOverheadVisibility(value, `${fieldPath}.${field}`);
2248
+ return {
2249
+ sessionHeader: override(entry.sessionHeader, "sessionHeader", preset.sessionHeader),
2250
+ stickyMessage: override(entry.stickyMessage, "stickyMessage", preset.stickyMessage),
2251
+ lifecycle: override(entry.lifecycle, "lifecycle", preset.lifecycle)
2252
+ };
2253
+ }
2254
+ function presentationOverridesAgainstPreset(entry) {
2255
+ if (!isPresentationMode(entry.mode) || entry.mode === "full")
2256
+ return [];
2257
+ const preset = PRESENTATION_MODE_EXPANSIONS[entry.mode];
2258
+ const fields = ["sessionHeader", "stickyMessage", "lifecycle"];
2259
+ return fields.filter((field) => {
2260
+ const value = entry[field];
2261
+ return value !== undefined && value !== null && value !== preset[field];
2262
+ });
2263
+ }
2235
2264
  function resolveTurnMarker(mode, emoji, platformType, fieldPath) {
2236
2265
  const m = mode === undefined || mode === null ? "off" : mode;
2237
2266
  if (!TURN_MARKER_VALUES.includes(m)) {
@@ -2423,10 +2452,19 @@ function effectivePermissionMode(input) {
2423
2452
  return "default";
2424
2453
  return input.botWideMode;
2425
2454
  }
2426
- var OVERHEAD_VISIBILITY_VALUES, DEFAULT_OVERHEAD_VISIBILITY = "full", RECONNECT_POLICY_VALUES, DEFAULT_RECONNECT_POLICY = "retry", TURN_MARKER_VALUES, DEFAULT_TURN_MARKER, DEFAULT_TURN_MARKER_EMOJI = "checkered_flag", TURN_COMPLETE_EVENT_TYPE = "claude_threads_turn_complete", TURN_COMPLETE_PAYLOAD_VERSION = 1, DEFAULT_MEMORY_CONFIG, MEMORY_DISABLED, BOT_MCP_SERVER_NAME = "claude-threads-mcp", STDIO_KEYS, REMOTE_KEYS, LIMITS_DEFAULTS, MODE_INFO;
2455
+ var OVERHEAD_VISIBILITY_VALUES, DEFAULT_OVERHEAD_VISIBILITY = "full", RECONNECT_POLICY_VALUES, DEFAULT_RECONNECT_POLICY = "retry", PRESENTATION_MODE_VALUES, PRESENTATION_MODE_EXPANSIONS, TURN_MARKER_VALUES, DEFAULT_TURN_MARKER, DEFAULT_TURN_MARKER_EMOJI = "checkered_flag", TURN_COMPLETE_EVENT_TYPE = "claude_threads_turn_complete", TURN_COMPLETE_PAYLOAD_VERSION = 1, DEFAULT_MEMORY_CONFIG, MEMORY_DISABLED, BOT_MCP_SERVER_NAME = "claude-threads-mcp", STDIO_KEYS, REMOTE_KEYS, LIMITS_DEFAULTS, MODE_INFO;
2427
2456
  var init_types = __esm(() => {
2428
2457
  OVERHEAD_VISIBILITY_VALUES = ["full", "minimal", "hidden"];
2429
2458
  RECONNECT_POLICY_VALUES = ["retry", "exit"];
2459
+ PRESENTATION_MODE_VALUES = ["full", "assistant"];
2460
+ PRESENTATION_MODE_EXPANSIONS = {
2461
+ full: {
2462
+ sessionHeader: DEFAULT_OVERHEAD_VISIBILITY,
2463
+ stickyMessage: DEFAULT_OVERHEAD_VISIBILITY,
2464
+ lifecycle: DEFAULT_OVERHEAD_VISIBILITY
2465
+ },
2466
+ assistant: { sessionHeader: "hidden", stickyMessage: "hidden", lifecycle: "hidden" }
2467
+ };
2430
2468
  TURN_MARKER_VALUES = ["reaction", "metadata", "off"];
2431
2469
  DEFAULT_TURN_MARKER = { mode: "off" };
2432
2470
  DEFAULT_MEMORY_CONFIG = {
@@ -2476,20 +2514,487 @@ var init_types = __esm(() => {
2476
2514
  };
2477
2515
  });
2478
2516
 
2479
- // src/utils/spawn.ts
2480
- import { spawn as nodeSpawn, spawnSync as nodeSpawnSync } from "child_process";
2481
- function addWindowsShell(options) {
2482
- if (isWindows && options.shell === undefined) {
2483
- return { ...options, shell: true };
2517
+ // node_modules/isexe/windows.js
2518
+ var require_windows = __commonJS(function(exports, module) {
2519
+ module.exports = isexe;
2520
+ isexe.sync = sync;
2521
+ var fs = __require("fs");
2522
+ function checkPathExt(path, options) {
2523
+ var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
2524
+ if (!pathext) {
2525
+ return true;
2526
+ }
2527
+ pathext = pathext.split(";");
2528
+ if (pathext.indexOf("") !== -1) {
2529
+ return true;
2530
+ }
2531
+ for (var i = 0;i < pathext.length; i++) {
2532
+ var p = pathext[i].toLowerCase();
2533
+ if (p && path.substr(-p.length).toLowerCase() === p) {
2534
+ return true;
2535
+ }
2536
+ }
2537
+ return false;
2484
2538
  }
2485
- return options;
2486
- }
2539
+ function checkStat(stat, path, options) {
2540
+ if (!stat.isSymbolicLink() && !stat.isFile()) {
2541
+ return false;
2542
+ }
2543
+ return checkPathExt(path, options);
2544
+ }
2545
+ function isexe(path, options, cb) {
2546
+ fs.stat(path, function(er, stat) {
2547
+ cb(er, er ? false : checkStat(stat, path, options));
2548
+ });
2549
+ }
2550
+ function sync(path, options) {
2551
+ return checkStat(fs.statSync(path), path, options);
2552
+ }
2553
+ });
2554
+
2555
+ // node_modules/isexe/mode.js
2556
+ var require_mode = __commonJS(function(exports, module) {
2557
+ module.exports = isexe;
2558
+ isexe.sync = sync;
2559
+ var fs = __require("fs");
2560
+ function isexe(path, options, cb) {
2561
+ fs.stat(path, function(er, stat) {
2562
+ cb(er, er ? false : checkStat(stat, options));
2563
+ });
2564
+ }
2565
+ function sync(path, options) {
2566
+ return checkStat(fs.statSync(path), options);
2567
+ }
2568
+ function checkStat(stat, options) {
2569
+ return stat.isFile() && checkMode(stat, options);
2570
+ }
2571
+ function checkMode(stat, options) {
2572
+ var mod = stat.mode;
2573
+ var uid = stat.uid;
2574
+ var gid = stat.gid;
2575
+ var myUid = options.uid !== undefined ? options.uid : process.getuid && process.getuid();
2576
+ var myGid = options.gid !== undefined ? options.gid : process.getgid && process.getgid();
2577
+ var u = parseInt("100", 8);
2578
+ var g = parseInt("010", 8);
2579
+ var o = parseInt("001", 8);
2580
+ var ug = u | g;
2581
+ var ret = mod & o || mod & g && gid === myGid || mod & u && uid === myUid || mod & ug && myUid === 0;
2582
+ return ret;
2583
+ }
2584
+ });
2585
+
2586
+ // node_modules/isexe/index.js
2587
+ var require_isexe = __commonJS(function(exports, module) {
2588
+ var fs = __require("fs");
2589
+ var core;
2590
+ if (process.platform === "win32" || global.TESTING_WINDOWS) {
2591
+ core = require_windows();
2592
+ } else {
2593
+ core = require_mode();
2594
+ }
2595
+ module.exports = isexe;
2596
+ isexe.sync = sync;
2597
+ function isexe(path, options, cb) {
2598
+ if (typeof options === "function") {
2599
+ cb = options;
2600
+ options = {};
2601
+ }
2602
+ if (!cb) {
2603
+ if (typeof Promise !== "function") {
2604
+ throw new TypeError("callback not provided");
2605
+ }
2606
+ return new Promise(function(resolve, reject) {
2607
+ isexe(path, options || {}, function(er, is) {
2608
+ if (er) {
2609
+ reject(er);
2610
+ } else {
2611
+ resolve(is);
2612
+ }
2613
+ });
2614
+ });
2615
+ }
2616
+ core(path, options || {}, function(er, is) {
2617
+ if (er) {
2618
+ if (er.code === "EACCES" || options && options.ignoreErrors) {
2619
+ er = null;
2620
+ is = false;
2621
+ }
2622
+ }
2623
+ cb(er, is);
2624
+ });
2625
+ }
2626
+ function sync(path, options) {
2627
+ try {
2628
+ return core.sync(path, options || {});
2629
+ } catch (er) {
2630
+ if (options && options.ignoreErrors || er.code === "EACCES") {
2631
+ return false;
2632
+ } else {
2633
+ throw er;
2634
+ }
2635
+ }
2636
+ }
2637
+ });
2638
+
2639
+ // node_modules/which/which.js
2640
+ var require_which = __commonJS(function(exports, module) {
2641
+ var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
2642
+ var path = __require("path");
2643
+ var COLON = isWindows ? ";" : ":";
2644
+ var isexe = require_isexe();
2645
+ var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
2646
+ var getPathInfo = (cmd, opt) => {
2647
+ const colon = opt.colon || COLON;
2648
+ const pathEnv = cmd.match(/\//) || isWindows && cmd.match(/\\/) ? [""] : [
2649
+ ...isWindows ? [process.cwd()] : [],
2650
+ ...(opt.path || process.env.PATH || "").split(colon)
2651
+ ];
2652
+ const pathExtExe = isWindows ? opt.pathExt || process.env.PATHEXT || ".EXE;.CMD;.BAT;.COM" : "";
2653
+ const pathExt = isWindows ? pathExtExe.split(colon) : [""];
2654
+ if (isWindows) {
2655
+ if (cmd.indexOf(".") !== -1 && pathExt[0] !== "")
2656
+ pathExt.unshift("");
2657
+ }
2658
+ return {
2659
+ pathEnv,
2660
+ pathExt,
2661
+ pathExtExe
2662
+ };
2663
+ };
2664
+ var which = (cmd, opt, cb) => {
2665
+ if (typeof opt === "function") {
2666
+ cb = opt;
2667
+ opt = {};
2668
+ }
2669
+ if (!opt)
2670
+ opt = {};
2671
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
2672
+ const found = [];
2673
+ const step = (i) => new Promise((resolve, reject) => {
2674
+ if (i === pathEnv.length)
2675
+ return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
2676
+ const ppRaw = pathEnv[i];
2677
+ const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
2678
+ const pCmd = path.join(pathPart, cmd);
2679
+ const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
2680
+ resolve(subStep(p, i, 0));
2681
+ });
2682
+ const subStep = (p, i, ii) => new Promise((resolve, reject) => {
2683
+ if (ii === pathExt.length)
2684
+ return resolve(step(i + 1));
2685
+ const ext = pathExt[ii];
2686
+ isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
2687
+ if (!er && is) {
2688
+ if (opt.all)
2689
+ found.push(p + ext);
2690
+ else
2691
+ return resolve(p + ext);
2692
+ }
2693
+ return resolve(subStep(p, i, ii + 1));
2694
+ });
2695
+ });
2696
+ return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
2697
+ };
2698
+ var whichSync = (cmd, opt) => {
2699
+ opt = opt || {};
2700
+ const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
2701
+ const found = [];
2702
+ for (let i = 0;i < pathEnv.length; i++) {
2703
+ const ppRaw = pathEnv[i];
2704
+ const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
2705
+ const pCmd = path.join(pathPart, cmd);
2706
+ const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
2707
+ for (let j = 0;j < pathExt.length; j++) {
2708
+ const cur = p + pathExt[j];
2709
+ try {
2710
+ const is = isexe.sync(cur, { pathExt: pathExtExe });
2711
+ if (is) {
2712
+ if (opt.all)
2713
+ found.push(cur);
2714
+ else
2715
+ return cur;
2716
+ }
2717
+ } catch (ex) {}
2718
+ }
2719
+ }
2720
+ if (opt.all && found.length)
2721
+ return found;
2722
+ if (opt.nothrow)
2723
+ return null;
2724
+ throw getNotFoundError(cmd);
2725
+ };
2726
+ module.exports = which;
2727
+ which.sync = whichSync;
2728
+ });
2729
+
2730
+ // node_modules/path-key/index.js
2731
+ var require_path_key = __commonJS(function(exports, module) {
2732
+ var pathKey = (options = {}) => {
2733
+ const environment = options.env || process.env;
2734
+ const platform = options.platform || process.platform;
2735
+ if (platform !== "win32") {
2736
+ return "PATH";
2737
+ }
2738
+ return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
2739
+ };
2740
+ module.exports = pathKey;
2741
+ module.exports.default = pathKey;
2742
+ });
2743
+
2744
+ // node_modules/cross-spawn/lib/util/resolveCommand.js
2745
+ var require_resolveCommand = __commonJS(function(exports, module) {
2746
+ var path = __require("path");
2747
+ var which = require_which();
2748
+ var getPathKey = require_path_key();
2749
+ function resolveCommandAttempt(parsed, withoutPathExt) {
2750
+ const env = parsed.options.env || process.env;
2751
+ const cwd = process.cwd();
2752
+ const hasCustomCwd = parsed.options.cwd != null;
2753
+ const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;
2754
+ if (shouldSwitchCwd) {
2755
+ try {
2756
+ process.chdir(parsed.options.cwd);
2757
+ } catch (err) {}
2758
+ }
2759
+ let resolved;
2760
+ try {
2761
+ resolved = which.sync(parsed.command, {
2762
+ path: env[getPathKey({ env })],
2763
+ pathExt: withoutPathExt ? path.delimiter : undefined
2764
+ });
2765
+ } catch (e) {} finally {
2766
+ if (shouldSwitchCwd) {
2767
+ process.chdir(cwd);
2768
+ }
2769
+ }
2770
+ if (resolved) {
2771
+ resolved = path.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
2772
+ }
2773
+ return resolved;
2774
+ }
2775
+ function resolveCommand(parsed) {
2776
+ return resolveCommandAttempt(parsed) || resolveCommandAttempt(parsed, true);
2777
+ }
2778
+ module.exports = resolveCommand;
2779
+ });
2780
+
2781
+ // node_modules/cross-spawn/lib/util/escape.js
2782
+ var require_escape = __commonJS(function(exports, module) {
2783
+ var metaCharsRegExp = /([()\][%!^"`<>&|;, *?])/g;
2784
+ function escapeCommand(arg) {
2785
+ arg = arg.replace(metaCharsRegExp, "^$1");
2786
+ return arg;
2787
+ }
2788
+ function escapeArgument(arg, doubleEscapeMetaChars) {
2789
+ arg = `${arg}`;
2790
+ arg = arg.replace(/(?=(\\+?)?)\1"/g, "$1$1\\\"");
2791
+ arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
2792
+ arg = `"${arg}"`;
2793
+ arg = arg.replace(metaCharsRegExp, "^$1");
2794
+ if (doubleEscapeMetaChars) {
2795
+ arg = arg.replace(metaCharsRegExp, "^$1");
2796
+ }
2797
+ return arg;
2798
+ }
2799
+ exports.command = escapeCommand;
2800
+ exports.argument = escapeArgument;
2801
+ });
2802
+
2803
+ // node_modules/shebang-regex/index.js
2804
+ var require_shebang_regex = __commonJS(function(exports, module) {
2805
+ module.exports = /^#!(.*)/;
2806
+ });
2807
+
2808
+ // node_modules/shebang-command/index.js
2809
+ var require_shebang_command = __commonJS(function(exports, module) {
2810
+ var shebangRegex = require_shebang_regex();
2811
+ module.exports = (string = "") => {
2812
+ const match = string.match(shebangRegex);
2813
+ if (!match) {
2814
+ return null;
2815
+ }
2816
+ const [path, argument] = match[0].replace(/#! ?/, "").split(" ");
2817
+ const binary = path.split("/").pop();
2818
+ if (binary === "env") {
2819
+ return argument;
2820
+ }
2821
+ return argument ? `${binary} ${argument}` : binary;
2822
+ };
2823
+ });
2824
+
2825
+ // node_modules/cross-spawn/lib/util/readShebang.js
2826
+ var require_readShebang = __commonJS(function(exports, module) {
2827
+ var fs = __require("fs");
2828
+ var shebangCommand = require_shebang_command();
2829
+ function readShebang(command) {
2830
+ const size = 150;
2831
+ const buffer = Buffer.alloc(size);
2832
+ let fd;
2833
+ try {
2834
+ fd = fs.openSync(command, "r");
2835
+ fs.readSync(fd, buffer, 0, size, 0);
2836
+ fs.closeSync(fd);
2837
+ } catch (e) {}
2838
+ return shebangCommand(buffer.toString());
2839
+ }
2840
+ module.exports = readShebang;
2841
+ });
2842
+
2843
+ // node_modules/cross-spawn/lib/parse.js
2844
+ var require_parse = __commonJS(function(exports, module) {
2845
+ var path = __require("path");
2846
+ var resolveCommand = require_resolveCommand();
2847
+ var escape = require_escape();
2848
+ var readShebang = require_readShebang();
2849
+ var isWin = process.platform === "win32";
2850
+ var isExecutableRegExp = /\.(?:com|exe)$/i;
2851
+ var isCmdShimRegExp = /node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;
2852
+ function detectShebang(parsed) {
2853
+ parsed.file = resolveCommand(parsed);
2854
+ const shebang = parsed.file && readShebang(parsed.file);
2855
+ if (shebang) {
2856
+ parsed.args.unshift(parsed.file);
2857
+ parsed.command = shebang;
2858
+ return resolveCommand(parsed);
2859
+ }
2860
+ return parsed.file;
2861
+ }
2862
+ function parseNonShell(parsed) {
2863
+ if (!isWin) {
2864
+ return parsed;
2865
+ }
2866
+ const commandFile = detectShebang(parsed);
2867
+ const needsShell = !isExecutableRegExp.test(commandFile);
2868
+ if (parsed.options.forceShell || needsShell) {
2869
+ const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
2870
+ parsed.command = path.normalize(parsed.command);
2871
+ parsed.command = escape.command(parsed.command);
2872
+ parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
2873
+ const shellCommand = [parsed.command].concat(parsed.args).join(" ");
2874
+ parsed.args = ["/d", "/s", "/c", `"${shellCommand}"`];
2875
+ parsed.command = process.env.comspec || "cmd.exe";
2876
+ parsed.options.windowsVerbatimArguments = true;
2877
+ }
2878
+ return parsed;
2879
+ }
2880
+ function parse(command, args, options) {
2881
+ if (args && !Array.isArray(args)) {
2882
+ options = args;
2883
+ args = null;
2884
+ }
2885
+ args = args ? args.slice(0) : [];
2886
+ options = Object.assign({}, options);
2887
+ const parsed = {
2888
+ command,
2889
+ args,
2890
+ options,
2891
+ file: undefined,
2892
+ original: {
2893
+ command,
2894
+ args
2895
+ }
2896
+ };
2897
+ return options.shell ? parsed : parseNonShell(parsed);
2898
+ }
2899
+ module.exports = parse;
2900
+ });
2901
+
2902
+ // node_modules/cross-spawn/lib/enoent.js
2903
+ var require_enoent = __commonJS(function(exports, module) {
2904
+ var isWin = process.platform === "win32";
2905
+ function notFoundError(original, syscall) {
2906
+ return Object.assign(new Error(`${syscall} ${original.command} ENOENT`), {
2907
+ code: "ENOENT",
2908
+ errno: "ENOENT",
2909
+ syscall: `${syscall} ${original.command}`,
2910
+ path: original.command,
2911
+ spawnargs: original.args
2912
+ });
2913
+ }
2914
+ function hookChildProcess(cp, parsed) {
2915
+ if (!isWin) {
2916
+ return;
2917
+ }
2918
+ const originalEmit = cp.emit;
2919
+ cp.emit = function(name, arg1) {
2920
+ if (name === "exit") {
2921
+ const err = verifyENOENT(arg1, parsed);
2922
+ if (err) {
2923
+ return originalEmit.call(cp, "error", err);
2924
+ }
2925
+ }
2926
+ return originalEmit.apply(cp, arguments);
2927
+ };
2928
+ }
2929
+ function verifyENOENT(status, parsed) {
2930
+ if (isWin && status === 1 && !parsed.file) {
2931
+ return notFoundError(parsed.original, "spawn");
2932
+ }
2933
+ return null;
2934
+ }
2935
+ function verifyENOENTSync(status, parsed) {
2936
+ if (isWin && status === 1 && !parsed.file) {
2937
+ return notFoundError(parsed.original, "spawnSync");
2938
+ }
2939
+ return null;
2940
+ }
2941
+ module.exports = {
2942
+ hookChildProcess,
2943
+ verifyENOENT,
2944
+ verifyENOENTSync,
2945
+ notFoundError
2946
+ };
2947
+ });
2948
+
2949
+ // node_modules/cross-spawn/index.js
2950
+ var require_cross_spawn = __commonJS(function(exports, module) {
2951
+ var cp = __require("child_process");
2952
+ var parse = require_parse();
2953
+ var enoent = require_enoent();
2954
+ function spawn(command, args, options) {
2955
+ const parsed = parse(command, args, options);
2956
+ const spawned = cp.spawn(parsed.command, parsed.args, parsed.options);
2957
+ enoent.hookChildProcess(spawned, parsed);
2958
+ return spawned;
2959
+ }
2960
+ function spawnSync(command, args, options) {
2961
+ const parsed = parse(command, args, options);
2962
+ const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
2963
+ result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
2964
+ return result;
2965
+ }
2966
+ module.exports = spawn;
2967
+ module.exports.spawn = spawn;
2968
+ module.exports.sync = spawnSync;
2969
+ module.exports._parse = parse;
2970
+ module.exports._enoent = enoent;
2971
+ });
2972
+
2973
+ // src/utils/spawn.ts
2974
+ import { win32 as win32Path } from "path";
2487
2975
  function crossSpawn(command, args, options) {
2488
- return nodeSpawn(command, args, addWindowsShell(options ?? {}));
2976
+ return import_cross_spawn.default(command, args, options ?? {});
2977
+ }
2978
+ function crossSpawnSync(command, args, options) {
2979
+ return import_cross_spawn.default.sync(command, args, options ?? {});
2980
+ }
2981
+ function findWindowsGitBash(env, exists) {
2982
+ const systemRoot = (env.SystemRoot ?? env.SYSTEMROOT ?? "C:\\Windows").toLowerCase();
2983
+ const isWslLauncher = (dir) => {
2984
+ const lower = dir.toLowerCase().replace(/[\\/]+$/, "");
2985
+ return lower.startsWith(`${systemRoot}\\system32`) || lower.startsWith(`${systemRoot}\\sysnative`) || lower.endsWith("\\windowsapps");
2986
+ };
2987
+ const pathDirs = (env.PATH ?? env.Path ?? "").split(";").filter(Boolean);
2988
+ const candidates = [
2989
+ ...pathDirs.filter((dir) => !isWslLauncher(dir)).map((dir) => win32Path.join(dir, "bash.exe")),
2990
+ ...[env.ProgramFiles, env.ProgramW6432, env["ProgramFiles(x86)"]].filter((dir) => Boolean(dir)).map((dir) => win32Path.join(dir, "Git", "bin", "bash.exe")),
2991
+ ...env.LOCALAPPDATA ? [win32Path.join(env.LOCALAPPDATA, "Programs", "Git", "bin", "bash.exe")] : []
2992
+ ];
2993
+ return candidates.find((candidate) => exists(candidate)) ?? null;
2489
2994
  }
2490
- var isWindows;
2995
+ var import_cross_spawn;
2491
2996
  var init_spawn = __esm(() => {
2492
- isWindows = process.platform === "win32";
2997
+ import_cross_spawn = __toESM(require_cross_spawn(), 1);
2493
2998
  });
2494
2999
 
2495
3000
  // node_modules/semver/internal/constants.js
@@ -2932,7 +3437,7 @@ var require_semver = __commonJS(function(exports, module) {
2932
3437
  });
2933
3438
 
2934
3439
  // node_modules/semver/functions/parse.js
2935
- var require_parse = __commonJS(function(exports, module) {
3440
+ var require_parse2 = __commonJS(function(exports, module) {
2936
3441
  var SemVer = require_semver();
2937
3442
  var parse = (version, options, throwErrors = false) => {
2938
3443
  if (version instanceof SemVer) {
@@ -2952,7 +3457,7 @@ var require_parse = __commonJS(function(exports, module) {
2952
3457
 
2953
3458
  // node_modules/semver/functions/valid.js
2954
3459
  var require_valid = __commonJS(function(exports, module) {
2955
- var parse = require_parse();
3460
+ var parse = require_parse2();
2956
3461
  var valid = (version, options) => {
2957
3462
  const v = parse(version, options);
2958
3463
  return v ? v.version : null;
@@ -2962,7 +3467,7 @@ var require_valid = __commonJS(function(exports, module) {
2962
3467
 
2963
3468
  // node_modules/semver/functions/clean.js
2964
3469
  var require_clean = __commonJS(function(exports, module) {
2965
- var parse = require_parse();
3470
+ var parse = require_parse2();
2966
3471
  var clean = (version, options) => {
2967
3472
  const s = parse(version.trim().replace(/^[=v]+/, ""), options);
2968
3473
  return s ? s.version : null;
@@ -2990,7 +3495,7 @@ var require_inc = __commonJS(function(exports, module) {
2990
3495
 
2991
3496
  // node_modules/semver/functions/diff.js
2992
3497
  var require_diff = __commonJS(function(exports, module) {
2993
- var parse = require_parse();
3498
+ var parse = require_parse2();
2994
3499
  var diff = (version1, version2) => {
2995
3500
  const v1 = parse(version1, null, true);
2996
3501
  const v2 = parse(version2, null, true);
@@ -3052,7 +3557,7 @@ var require_patch = __commonJS(function(exports, module) {
3052
3557
 
3053
3558
  // node_modules/semver/functions/prerelease.js
3054
3559
  var require_prerelease = __commonJS(function(exports, module) {
3055
- var parse = require_parse();
3560
+ var parse = require_parse2();
3056
3561
  var prerelease = (version, options) => {
3057
3562
  const parsed = parse(version, options);
3058
3563
  return parsed && parsed.prerelease.length ? parsed.prerelease : null;
@@ -3198,7 +3703,7 @@ var require_cmp = __commonJS(function(exports, module) {
3198
3703
  // node_modules/semver/functions/coerce.js
3199
3704
  var require_coerce = __commonJS(function(exports, module) {
3200
3705
  var SemVer = require_semver();
3201
- var parse = require_parse();
3706
+ var parse = require_parse2();
3202
3707
  var { safeRe: re, t } = require_re();
3203
3708
  var coerce = (version, options) => {
3204
3709
  if (version instanceof SemVer) {
@@ -3240,7 +3745,7 @@ var require_coerce = __commonJS(function(exports, module) {
3240
3745
 
3241
3746
  // node_modules/semver/functions/truncate.js
3242
3747
  var require_truncate = __commonJS(function(exports, module) {
3243
- var parse = require_parse();
3748
+ var parse = require_parse2();
3244
3749
  var constants = require_constants();
3245
3750
  var SemVer = require_semver();
3246
3751
  var truncate = (version, truncation, options) => {
@@ -4248,7 +4753,7 @@ var require_semver2 = __commonJS(function(exports, module) {
4248
4753
  var constants = require_constants();
4249
4754
  var SemVer = require_semver();
4250
4755
  var identifiers = require_identifiers();
4251
- var parse = require_parse();
4756
+ var parse = require_parse2();
4252
4757
  var valid = require_valid();
4253
4758
  var clean = require_clean();
4254
4759
  var inc = require_inc();
@@ -55234,7 +55739,7 @@ import process8 from "node:process";
55234
55739
  import path9 from "node:path";
55235
55740
  import os4 from "node:os";
55236
55741
  import fs4 from "node:fs";
55237
- var isWindows2 = process8.platform === "win32";
55742
+ var isWindows = process8.platform === "win32";
55238
55743
  var readRc = (filePath) => {
55239
55744
  try {
55240
55745
  return import_ini.default.parse(fs4.readFileSync(filePath, "utf8")).prefix;
@@ -55242,7 +55747,7 @@ var readRc = (filePath) => {
55242
55747
  };
55243
55748
  var getEnvNpmPrefix = () => Object.keys(process8.env).reduce((prefix, name) => /^npm_config_prefix$/i.test(name) ? process8.env[name] : prefix, undefined);
55244
55749
  var getGlobalNpmrc = () => {
55245
- if (isWindows2 && process8.env.APPDATA) {
55750
+ if (isWindows && process8.env.APPDATA) {
55246
55751
  return path9.join(process8.env.APPDATA, "/npm/etc/npmrc");
55247
55752
  }
55248
55753
  if (process8.execPath.includes("/Cellar/node")) {
@@ -55255,7 +55760,7 @@ var getGlobalNpmrc = () => {
55255
55760
  }
55256
55761
  };
55257
55762
  var getDefaultNpmPrefix = () => {
55258
- if (isWindows2) {
55763
+ if (isWindows) {
55259
55764
  const { APPDATA } = process8.env;
55260
55765
  return APPDATA ? path9.join(APPDATA, "npm") : path9.dirname(process8.execPath);
55261
55766
  }
@@ -55281,7 +55786,7 @@ var getNpmPrefix = () => {
55281
55786
  };
55282
55787
  var npmPrefix = path9.resolve(getNpmPrefix());
55283
55788
  var getYarnWindowsDirectory = () => {
55284
- if (isWindows2 && process8.env.LOCALAPPDATA) {
55789
+ if (isWindows && process8.env.LOCALAPPDATA) {
55285
55790
  const dir = path9.join(process8.env.LOCALAPPDATA, "Yarn");
55286
55791
  if (fs4.existsSync(dir)) {
55287
55792
  return dir;
@@ -55310,8 +55815,8 @@ var getYarnPrefix = () => {
55310
55815
  var globalDirectory = {};
55311
55816
  globalDirectory.npm = {};
55312
55817
  globalDirectory.npm.prefix = npmPrefix;
55313
- globalDirectory.npm.packages = path9.join(npmPrefix, isWindows2 ? "node_modules" : "lib/node_modules");
55314
- globalDirectory.npm.binaries = isWindows2 ? npmPrefix : path9.join(npmPrefix, "bin");
55818
+ globalDirectory.npm.packages = path9.join(npmPrefix, isWindows ? "node_modules" : "lib/node_modules");
55819
+ globalDirectory.npm.binaries = isWindows ? npmPrefix : path9.join(npmPrefix, "bin");
55315
55820
  var yarnPrefix = path9.resolve(getYarnPrefix());
55316
55821
  globalDirectory.yarn = {};
55317
55822
  globalDirectory.yarn.prefix = yarnPrefix;
@@ -72234,10 +72739,15 @@ async function handleReaction(deps, platformId, postId, emojiName, username, act
72234
72739
  }
72235
72740
  let session = deps.registry.findByPost(postId);
72236
72741
  if (!session) {
72742
+ const hadInFlight = deps.registry.hasInFlightInteractivePost();
72237
72743
  await deps.registry.awaitPendingPost(postId, UNKNOWN_POST_GRACE_MS);
72238
72744
  session = deps.registry.findByPost(postId);
72239
- if (!session)
72745
+ if (!session) {
72746
+ if (hadInFlight) {
72747
+ log52.debug(`Reaction :${normalizedEmoji}: by @${username} on unknown post ${postId} ` + `dropped after the in-flight grace window (${UNKNOWN_POST_GRACE_MS}ms)`);
72748
+ }
72240
72749
  return;
72750
+ }
72241
72751
  }
72242
72752
  if (session.platformId !== platformId)
72243
72753
  return;
@@ -73665,7 +74175,7 @@ var isSharedWorker = typeof SharedWorkerGlobalScope !== "undefined" && globalThi
73665
74175
  var isServiceWorker = typeof ServiceWorkerGlobalScope !== "undefined" && globalThis instanceof ServiceWorkerGlobalScope;
73666
74176
  var platform = globalThis.navigator?.userAgentData?.platform;
73667
74177
  var isMacOs = platform === "macOS" || globalThis.navigator?.platform === "MacIntel" || globalThis.navigator?.userAgent?.includes(" Mac ") === true || globalThis.process?.platform === "darwin";
73668
- var isWindows3 = platform === "Windows" || globalThis.navigator?.platform === "Win32" || globalThis.process?.platform === "win32";
74178
+ var isWindows2 = platform === "Windows" || globalThis.navigator?.platform === "Win32" || globalThis.process?.platform === "win32";
73669
74179
  var isLinux = platform === "Linux" || globalThis.navigator?.platform?.startsWith("Linux") === true || globalThis.navigator?.userAgent?.includes(" Linux ") === true || globalThis.process?.platform === "linux";
73670
74180
  var isIos = platform === "iOS" || globalThis.navigator?.platform === "MacIntel" && globalThis.navigator?.maxTouchPoints > 1 || /iPad|iPhone|iPod/.test(globalThis.navigator?.platform);
73671
74181
  var isAndroid = platform === "Android" || globalThis.navigator?.platform === "Android" || globalThis.navigator?.userAgent?.includes(" Android ") === true || globalThis.process?.platform === "android";
@@ -73674,7 +74184,7 @@ var isAndroid = platform === "Android" || globalThis.navigator?.platform === "An
73674
74184
  var ESC = "\x1B[";
73675
74185
  var SEP = ";";
73676
74186
  var isTerminalApp = !isBrowser && process11.env.TERM_PROGRAM === "Apple_Terminal";
73677
- var isWindows4 = !isBrowser && process11.platform === "win32";
74187
+ var isWindows3 = !isBrowser && process11.platform === "win32";
73678
74188
  var isTmux = !isBrowser && (process11.env.TERM?.startsWith("screen") || process11.env.TERM?.startsWith("tmux") || process11.env.TMUX !== undefined);
73679
74189
  var cwdFunction = isBrowser ? () => {
73680
74190
  throw new Error("`process.cwd()` only works in Node.js, not the browser.");
@@ -73718,7 +74228,7 @@ var scrollUp = ESC + "S";
73718
74228
  var scrollDown = ESC + "T";
73719
74229
  var clearViewport = `${eraseScreen}${ESC}H`;
73720
74230
  var isOldWindows = () => {
73721
- if (isBrowser || !isWindows4) {
74231
+ if (isBrowser || !isWindows3) {
73722
74232
  return false;
73723
74233
  }
73724
74234
  const parts = os5.release().split(".");
@@ -85754,6 +86264,7 @@ class UpdateScheduler extends EventEmitter8 {
85754
86264
  pendingUpdate = null;
85755
86265
  checkTimer = null;
85756
86266
  countdownTimer = null;
86267
+ deferTimer = null;
85757
86268
  idleStartTime = null;
85758
86269
  scheduledRestartAt = null;
85759
86270
  askApprovals = new Map;
@@ -85776,6 +86287,8 @@ class UpdateScheduler extends EventEmitter8 {
85776
86287
  }
85777
86288
  cancelSchedule() {
85778
86289
  this.stopChecking();
86290
+ this.stopCountdown();
86291
+ this.stopDeferTimer();
85779
86292
  this.pendingUpdate = null;
85780
86293
  this.idleStartTime = null;
85781
86294
  this.scheduledRestartAt = null;
@@ -85784,9 +86297,21 @@ class UpdateScheduler extends EventEmitter8 {
85784
86297
  log55.debug("Update schedule cancelled");
85785
86298
  }
85786
86299
  deferUpdate(minutes) {
85787
- const deferUntil = new Date(Date.now() + minutes * 60 * 1000);
86300
+ const deferMs = minutes * 60 * 1000;
86301
+ const deferUntil = new Date(Date.now() + deferMs);
86302
+ this.stopCountdown();
86303
+ this.stopChecking();
86304
+ this.stopDeferTimer();
85788
86305
  this.scheduledRestartAt = null;
85789
86306
  this.idleStartTime = null;
86307
+ this.askApprovals.clear();
86308
+ this.askStartTime = null;
86309
+ if (this.pendingUpdate) {
86310
+ this.deferTimer = setTimeout(() => {
86311
+ this.deferTimer = null;
86312
+ this.startChecking();
86313
+ }, deferMs);
86314
+ }
85790
86315
  this.emit("deferred", deferUntil);
85791
86316
  log55.info(`Update deferred until ${deferUntil.toLocaleTimeString()}`);
85792
86317
  return deferUntil;
@@ -85808,12 +86333,13 @@ class UpdateScheduler extends EventEmitter8 {
85808
86333
  stop() {
85809
86334
  this.stopChecking();
85810
86335
  this.stopCountdown();
86336
+ this.stopDeferTimer();
85811
86337
  }
85812
86338
  startChecking() {
85813
86339
  if (this.checkTimer)
85814
86340
  return;
85815
- this.checkCondition();
85816
86341
  this.checkTimer = setInterval(() => this.checkCondition(), 1e4);
86342
+ this.checkCondition();
85817
86343
  log55.debug(`Started checking for ${this.config.autoRestartMode} condition`);
85818
86344
  }
85819
86345
  stopChecking() {
@@ -85943,59 +86469,71 @@ class UpdateScheduler extends EventEmitter8 {
85943
86469
  if (!this.pendingUpdate)
85944
86470
  return;
85945
86471
  this.stopChecking();
86472
+ if (this.countdownTimer || this.deferTimer)
86473
+ return;
85946
86474
  this.scheduledRestartAt = new Date(Date.now() + 60000);
85947
86475
  let secondsRemaining = 60;
85948
86476
  this.emit("countdown", secondsRemaining);
85949
- this.countdownTimer = setInterval(() => {
86477
+ const timer = setInterval(() => {
85950
86478
  secondsRemaining--;
85951
86479
  this.emit("countdown", secondsRemaining);
85952
86480
  if (secondsRemaining <= 0) {
85953
- this.stopCountdown();
86481
+ clearInterval(timer);
86482
+ if (this.countdownTimer === timer)
86483
+ this.countdownTimer = null;
85954
86484
  this.emit("ready", this.pendingUpdate);
85955
86485
  }
85956
86486
  }, 1000);
86487
+ this.countdownTimer = timer;
85957
86488
  log55.info("Update countdown started (60 seconds)");
85958
86489
  }
85959
86490
  stopCountdown() {
85960
86491
  if (this.countdownTimer) {
85961
86492
  clearInterval(this.countdownTimer);
85962
86493
  this.countdownTimer = null;
86494
+ this.scheduledRestartAt = null;
86495
+ }
86496
+ }
86497
+ stopDeferTimer() {
86498
+ if (this.deferTimer) {
86499
+ clearTimeout(this.deferTimer);
86500
+ this.deferTimer = null;
85963
86501
  }
85964
86502
  }
85965
86503
  }
85966
86504
 
85967
86505
  // src/auto-update/installer.ts
86506
+ init_spawn();
85968
86507
  init_state_home();
85969
- import { spawn as spawn4, spawnSync } from "child_process";
85970
86508
  import { existsSync as existsSync17, readFileSync as readFileSync12, mkdirSync as mkdirSync8 } from "fs";
85971
86509
  import { dirname as dirname9, resolve as resolve8 } from "path";
85972
86510
  import { homedir as homedir3 } from "os";
85973
86511
  init_logger();
85974
86512
  var log56 = createLogger("installer");
85975
86513
  function detectPackageManager() {
85976
- const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
86514
+ const npmCmd = "npm";
85977
86515
  const originalInstaller = detectOriginalInstaller();
85978
86516
  if (originalInstaller) {
85979
86517
  log56.debug(`Detected original installer: ${originalInstaller}`);
85980
86518
  if (originalInstaller === "bun") {
85981
- const bunCheck = spawnSync("bun", ["--version"], { stdio: "ignore" });
86519
+ const bunCheck = crossSpawnSync("bun", ["--version"], { stdio: "ignore" });
85982
86520
  if (bunCheck.status === 0) {
85983
86521
  return { cmd: "bun", isBun: true };
85984
86522
  }
85985
86523
  log56.warn("Originally installed with bun, but bun not found. Falling back to npm.");
85986
86524
  } else {
85987
- const npmCheck = spawnSync(npmCmd, ["--version"], { stdio: "ignore" });
86525
+ const npmCheck = crossSpawnSync(npmCmd, ["--version"], { stdio: "ignore" });
85988
86526
  if (npmCheck.status === 0) {
85989
86527
  return { cmd: npmCmd, isBun: false };
85990
86528
  }
85991
86529
  log56.warn("Originally installed with npm, but npm not found. Falling back to bun.");
85992
86530
  }
85993
86531
  }
85994
- const bunCheck = spawnSync("bun", ["--version"], { stdio: "ignore" });
86532
+ const bunCheck = crossSpawnSync("bun", ["--version"], { stdio: "ignore" });
85995
86533
  if (bunCheck.status === 0) {
85996
86534
  return { cmd: "bun", isBun: true };
85997
86535
  }
85998
- const npmCheck = spawnSync(npmCmd, ["--version"], { stdio: "ignore" });
86536
+ const npmCheck = crossSpawnSync(npmCmd, ["--version"], { stdio: "ignore" });
85999
86537
  if (npmCheck.status === 0) {
86000
86538
  return { cmd: npmCmd, isBun: false };
86001
86539
  }
@@ -86014,13 +86552,12 @@ function detectOriginalInstaller() {
86014
86552
  if (scriptPath.startsWith(bunGlobalDir)) {
86015
86553
  return "bun";
86016
86554
  }
86017
- const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
86018
- const npmPrefixResult = spawnSync(npmCmd, ["prefix", "-g"], {
86555
+ const npmPrefixResult = crossSpawnSync("npm", ["prefix", "-g"], {
86019
86556
  encoding: "utf-8",
86020
86557
  stdio: ["ignore", "pipe", "ignore"]
86021
86558
  });
86022
86559
  if (npmPrefixResult.status === 0 && npmPrefixResult.stdout) {
86023
- const npmPrefix = normalizePath(npmPrefixResult.stdout.trim());
86560
+ const npmPrefix = normalizePath(String(npmPrefixResult.stdout).trim());
86024
86561
  if (scriptPath.startsWith(npmPrefix)) {
86025
86562
  return "npm";
86026
86563
  }
@@ -86110,7 +86647,7 @@ async function installVersion(version) {
86110
86647
  const { cmd, isBun } = pm;
86111
86648
  const args = ["install", "-g", `${PACKAGE_NAME2}@${version}`];
86112
86649
  log56.debug(`Using ${isBun ? "bun" : "npm"} for installation`);
86113
- const child = spawn4(cmd, args, {
86650
+ const child = crossSpawn(cmd, args, {
86114
86651
  stdio: ["ignore", "pipe", "pipe"],
86115
86652
  env: {
86116
86653
  ...process.env,
@@ -86193,7 +86730,7 @@ class UpdateInstaller {
86193
86730
 
86194
86731
  // src/auto-update/respawn.ts
86195
86732
  init_logger();
86196
- import { spawn as spawn5 } from "child_process";
86733
+ init_spawn();
86197
86734
  import { existsSync as existsSync18, statSync as statSync5 } from "fs";
86198
86735
  import { delimiter, join as join18 } from "path";
86199
86736
  var log57 = createLogger("respawn");
@@ -86263,14 +86800,12 @@ function spawnReplacement(argv = process.argv.slice(2), binPath = resolveClaudeT
86263
86800
  const childEnv = { ...process.env };
86264
86801
  delete childEnv.CLAUDE_THREADS_BIN;
86265
86802
  delete childEnv.CLAUDE_THREADS_INTERACTIVE;
86266
- const useShell = process.platform === "win32";
86267
86803
  let child;
86268
86804
  try {
86269
- child = spawn5(binPath, argv, {
86805
+ child = crossSpawn(binPath, argv, {
86270
86806
  detached: true,
86271
86807
  stdio: "inherit",
86272
- env: childEnv,
86273
- shell: useShell
86808
+ env: childEnv
86274
86809
  });
86275
86810
  } catch (err) {
86276
86811
  log57.error(`spawn() threw: ${err instanceof Error ? err.message : String(err)}`);
@@ -86346,6 +86881,7 @@ class AutoUpdateManager extends EventEmitter9 {
86346
86881
  return;
86347
86882
  }
86348
86883
  log58.info("Forcing immediate update");
86884
+ this.scheduler.stop();
86349
86885
  await this.performUpdate(updateInfo);
86350
86886
  }
86351
86887
  deferUpdate(minutes = 60) {
@@ -86636,6 +87172,8 @@ async function main() {
86636
87172
  const { spawn } = await import("child_process");
86637
87173
  const { dirname, resolve } = await import("path");
86638
87174
  const { fileURLToPath } = await import("url");
87175
+ const { existsSync } = await import("fs");
87176
+ await Promise.resolve().then(() => init_spawn());
86639
87177
  const __filename2 = fileURLToPath(import.meta.url);
86640
87178
  const __dirname2 = dirname(__filename2);
86641
87179
  const daemonPath = resolve(__dirname2, "..", "bin", "claude-threads-daemon");
@@ -86645,7 +87183,14 @@ async function main() {
86645
87183
  const binPath = __filename2;
86646
87184
  let child;
86647
87185
  if (process.platform === "win32") {
86648
- child = spawn("bash", [daemonPath, "--restart-on-error", ...args], {
87186
+ const bashPath = findWindowsGitBash(process.env, existsSync);
87187
+ if (!bashPath) {
87188
+ console.error("Auto-restart requires Git for Windows (bash.exe). Starting without auto-restart...");
87189
+ console.error("");
87190
+ await startWithoutDaemon();
87191
+ return;
87192
+ }
87193
+ child = spawn(bashPath, [daemonPath, "--restart-on-error", ...args], {
86649
87194
  stdio: "inherit",
86650
87195
  env: {
86651
87196
  ...process.env,
@@ -86731,6 +87276,15 @@ async function startWithoutDaemon() {
86731
87276
  if (cliArgs.keepAlive !== undefined) {
86732
87277
  newConfig.keepAlive = cliArgs.keepAlive;
86733
87278
  }
87279
+ const presetOverrideWarnings = newConfig.platforms.flatMap((platformConfig) => {
87280
+ const overridden = presentationOverridesAgainstPreset(platformConfig);
87281
+ if (overridden.length === 0)
87282
+ return [];
87283
+ const one = overridden.length === 1;
87284
+ return [
87285
+ ` ⚠️ platforms[${platformConfig.id}]: mode: ${String(platformConfig.mode)} is overridden for ${overridden.join(", ")} by ${one ? "an explicit field" : "explicit fields"}. Remove ${one ? "it" : "them"} to let the preset apply.`
87286
+ ];
87287
+ });
86734
87288
  if (cliArgs.sessionHeader !== undefined) {
86735
87289
  for (const p of newConfig.platforms) {
86736
87290
  p.sessionHeader = cliArgs.sessionHeader;
@@ -86745,14 +87299,15 @@ async function startWithoutDaemon() {
86745
87299
  if (!newConfig.platforms || newConfig.platforms.length === 0) {
86746
87300
  throw new Error("No platforms configured. Run with --setup to configure.");
86747
87301
  }
86748
- let mcpPostureWarnings = [];
87302
+ let startupWarnings = [];
86749
87303
  try {
86750
- mcpPostureWarnings = resolvePlatformMcpPosture(newConfig.platforms, newConfig.mcpServers).warnings;
87304
+ startupWarnings = resolvePlatformMcpPosture(newConfig.platforms, newConfig.mcpServers).warnings;
86751
87305
  } catch (err) {
86752
87306
  console.error(red(` ❌ ${err instanceof Error ? err.message : String(err)}`));
86753
87307
  process.exit(1);
86754
87308
  }
86755
- for (const w of mcpPostureWarnings)
87309
+ startupWarnings.push(...presetOverrideWarnings);
87310
+ for (const w of startupWarnings)
86756
87311
  console.warn(w);
86757
87312
  const config = newConfig;
86758
87313
  const firstPlatformConfig = config.platforms[0];
@@ -86914,7 +87469,7 @@ async function startWithoutDaemon() {
86914
87469
  }
86915
87470
  }
86916
87471
  });
86917
- for (const w of mcpPostureWarnings) {
87472
+ for (const w of startupWarnings) {
86918
87473
  ui.addLog({ level: "warn", component: "config", message: w });
86919
87474
  }
86920
87475
  setLogHandler((level, component, message, sessionId) => {
@@ -86963,9 +87518,7 @@ async function startWithoutDaemon() {
86963
87518
  configureAuditLog(platformConfig.id, resolveAuditLogEnabled(platformConfig.auditLog, `platforms[${platformConfig.id}].auditLog`));
86964
87519
  session.addPlatform(platformConfig.id, client, {
86965
87520
  overhead: {
86966
- sessionHeader: resolveOverheadVisibility(platformConfig.sessionHeader, `platforms[${platformConfig.id}].sessionHeader`),
86967
- stickyMessage: resolveOverheadVisibility(platformConfig.stickyMessage, `platforms[${platformConfig.id}].stickyMessage`),
86968
- lifecycle: resolveOverheadVisibility(platformConfig.lifecycle, `platforms[${platformConfig.id}].lifecycle`),
87521
+ ...resolvePresentationOverhead(platformConfig, `platforms[${platformConfig.id}]`),
86969
87522
  turnMarker: resolveTurnMarker(platformConfig.turnMarker, platformConfig.turnMarkerEmoji, platformConfig.type, `platforms[${platformConfig.id}]`)
86970
87523
  },
86971
87524
  memory: resolveMemoryConfig(platformConfig.memory, `platforms[${platformConfig.id}].memory`),
@@ -86992,9 +87545,8 @@ async function startWithoutDaemon() {
86992
87545
  configureAuditLog(dmConfig.id, resolveAuditLogEnabled(dmConfig.auditLog, `dm[${dmConfig.id}].auditLog`));
86993
87546
  session.addPlatform(dmConfig.id, dmClient, {
86994
87547
  overhead: {
86995
- sessionHeader: resolveOverheadVisibility(dmConfig.sessionHeader, `dm[${dmConfig.id}].sessionHeader`),
87548
+ ...resolvePresentationOverhead(dmConfig, `dm[${dmConfig.id}]`),
86996
87549
  stickyMessage: "hidden",
86997
- lifecycle: resolveOverheadVisibility(dmConfig.lifecycle, `dm[${dmConfig.id}].lifecycle`),
86998
87550
  turnMarker: resolveTurnMarker(dmConfig.turnMarker, dmConfig.turnMarkerEmoji, dmConfig.type, `dm[${dmConfig.id}]`)
86999
87551
  },
87000
87552
  memory: resolveMemoryConfig(dmConfig.memory, `dm[${dmConfig.id}].memory`),