sessix-server 0.5.3 → 0.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/index.js +158 -47
  2. package/dist/server.js +153 -42
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -24,9 +24,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/index.ts
27
- var import_node_os10 = require("os");
28
- var import_node_fs4 = require("fs");
29
- var import_node_path10 = require("path");
27
+ var import_node_os12 = require("os");
28
+ var import_node_fs6 = require("fs");
29
+ var import_node_path12 = require("path");
30
30
  var import_node_child_process13 = require("child_process");
31
31
 
32
32
  // src/i18n/locales/zh.ts
@@ -304,8 +304,8 @@ function t(key, params) {
304
304
  // src/server.ts
305
305
  var import_uuid8 = require("uuid");
306
306
  var import_promises7 = require("fs/promises");
307
- var import_node_os9 = require("os");
308
- var import_node_path9 = require("path");
307
+ var import_node_os11 = require("os");
308
+ var import_node_path11 = require("path");
309
309
  var import_node_child_process12 = require("child_process");
310
310
  var import_node_util3 = require("util");
311
311
  var import_node_v8 = require("v8");
@@ -446,6 +446,21 @@ var import_promises = require("fs/promises");
446
446
  var import_readline = require("readline");
447
447
  var import_path = require("path");
448
448
  var import_os = require("os");
449
+
450
+ // src/utils/modelValidation.ts
451
+ function isUsableModel(model) {
452
+ if (typeof model !== "string") return false;
453
+ const trimmed = model.trim();
454
+ if (!trimmed) return false;
455
+ if (trimmed === "unknown") return false;
456
+ if (trimmed.startsWith("<")) return false;
457
+ return true;
458
+ }
459
+ function sanitizeModel(model) {
460
+ return isUsableModel(model) ? model.trim() : void 0;
461
+ }
462
+
463
+ // src/session/ProjectReader.ts
449
464
  var CLAUDE_PROJECTS_DIR = (0, import_path.join)((0, import_os.homedir)(), ".claude", "projects");
450
465
  function getSessionFilePath(projectPath, sessionId) {
451
466
  return (0, import_path.join)(CLAUDE_PROJECTS_DIR, encodeDirName(projectPath), `${sessionId}.jsonl`);
@@ -466,7 +481,7 @@ async function getSessionModel(projectPath, sessionId) {
466
481
  const obj = JSON.parse(line);
467
482
  if (obj.type !== "assistant" || !obj.message) continue;
468
483
  const model = obj.message.model;
469
- if (typeof model === "string" && model && model !== "unknown") {
484
+ if (isUsableModel(model)) {
470
485
  lastModel = model;
471
486
  }
472
487
  } catch {
@@ -1084,17 +1099,22 @@ var ProcessProvider = class {
1084
1099
  } else {
1085
1100
  args.push("--session-id", sessionId);
1086
1101
  }
1087
- if (model) {
1088
- args.push("--model", model);
1102
+ const safeModel = sanitizeModel(model);
1103
+ if (model && !safeModel) {
1104
+ console.warn(`[ProcessProvider] Session ${sessionId}: ignoring invalid model "${model}", falling back to CLI default`);
1105
+ }
1106
+ if (safeModel) {
1107
+ args.push("--model", safeModel);
1089
1108
  }
1109
+ const safeFallbackModel = sanitizeModel(fallbackModel);
1090
1110
  if (permissionMode && permissionMode !== "default") {
1091
1111
  args.push("--permission-mode", permissionMode);
1092
1112
  }
1093
1113
  if (effort) {
1094
1114
  args.push("--effort", effort);
1095
1115
  }
1096
- if (fallbackModel) {
1097
- args.push("--fallback-model", fallbackModel);
1116
+ if (safeFallbackModel) {
1117
+ args.push("--fallback-model", safeFallbackModel);
1098
1118
  }
1099
1119
  if (maxBudgetUsd != null) {
1100
1120
  args.push("--max-budget-usd", String(maxBudgetUsd));
@@ -5128,6 +5148,36 @@ var DesktopNotificationChannel = class {
5128
5148
  }
5129
5149
  };
5130
5150
 
5151
+ // src/notification/pushTokenStore.ts
5152
+ var import_node_fs4 = require("fs");
5153
+ var import_node_os7 = require("os");
5154
+ var import_node_path6 = require("path");
5155
+ var DEFAULT_PUSH_TOKENS_FILE = (0, import_node_path6.join)((0, import_node_os7.homedir)(), ".sessix", "push-tokens.json");
5156
+ function loadPushTokens(filePath = DEFAULT_PUSH_TOKENS_FILE) {
5157
+ try {
5158
+ const parsed = JSON.parse((0, import_node_fs4.readFileSync)(filePath, "utf-8"));
5159
+ if (!Array.isArray(parsed)) return [];
5160
+ return parsed.filter((t2) => typeof t2 === "string");
5161
+ } catch {
5162
+ return [];
5163
+ }
5164
+ }
5165
+ function savePushTokens(tokens, filePath = DEFAULT_PUSH_TOKENS_FILE) {
5166
+ const deduped = [];
5167
+ const seen = /* @__PURE__ */ new Set();
5168
+ for (const t2 of tokens) {
5169
+ if (typeof t2 !== "string" || seen.has(t2)) continue;
5170
+ seen.add(t2);
5171
+ deduped.push(t2);
5172
+ }
5173
+ try {
5174
+ (0, import_node_fs4.mkdirSync)((0, import_node_path6.dirname)(filePath), { recursive: true });
5175
+ (0, import_node_fs4.writeFileSync)(filePath, JSON.stringify(deduped, null, 2), "utf-8");
5176
+ } catch (err) {
5177
+ console.warn("[pushTokenStore] \u5199\u5165 push token \u5931\u8D25:", err);
5178
+ }
5179
+ }
5180
+
5131
5181
  // src/notification/ExpoNotificationChannel.ts
5132
5182
  var EXPO_PUSH_API = "https://exp.host/--/api/v2/push/send";
5133
5183
  var EXPO_RECEIPT_API = "https://exp.host/--/api/v2/push/getReceipts";
@@ -5138,18 +5188,35 @@ var ExpoNotificationChannel = class {
5138
5188
  tokenWsMap = /* @__PURE__ */ new Map();
5139
5189
  /** per-token 通知音效偏好 */
5140
5190
  soundPreferences = /* @__PURE__ */ new Map();
5191
+ /** push token 持久化文件路径 */
5192
+ pushTokensFile;
5193
+ constructor(opts = {}) {
5194
+ this.pushTokensFile = opts.pushTokensFile ?? DEFAULT_PUSH_TOKENS_FILE;
5195
+ for (const token of loadPushTokens(this.pushTokensFile)) {
5196
+ this.tokens.add(token);
5197
+ }
5198
+ if (this.tokens.size > 0) {
5199
+ console.log(`[ExpoNotificationChannel] \u4ECE\u78C1\u76D8\u91CD\u8F7D ${this.tokens.size} \u4E2A push token`);
5200
+ }
5201
+ }
5202
+ /** 把当前 token 集合落盘,供进程重启后重载。 */
5203
+ persist() {
5204
+ savePushTokens(Array.from(this.tokens), this.pushTokensFile);
5205
+ }
5141
5206
  isAvailable() {
5142
5207
  return this.tokens.size > 0;
5143
5208
  }
5144
5209
  addToken(token, ws) {
5145
5210
  this.tokens.add(token);
5146
5211
  if (ws) this.tokenWsMap.set(token, ws);
5212
+ this.persist();
5147
5213
  console.log(`[ExpoNotificationChannel] ${t("notification.tokenRegistered", { count: this.tokens.size })}`);
5148
5214
  }
5149
5215
  removeToken(token) {
5150
5216
  this.tokens.delete(token);
5151
5217
  this.tokenWsMap.delete(token);
5152
5218
  this.soundPreferences.delete(token);
5219
+ this.persist();
5153
5220
  console.log(`[ExpoNotificationChannel] ${t("notification.tokenRemoved", { count: this.tokens.size })}`);
5154
5221
  }
5155
5222
  /** 更新某个 token 的音效偏好 */
@@ -5221,6 +5288,7 @@ var ExpoNotificationChannel = class {
5221
5288
  this.tokens.delete(staleToken);
5222
5289
  this.tokenWsMap.delete(staleToken);
5223
5290
  this.soundPreferences.delete(staleToken);
5291
+ this.persist();
5224
5292
  console.warn(`[ExpoNotificationChannel] \u26A0\uFE0F \u5DF2\u79FB\u9664\u5931\u6548 token\uFF08DeviceNotRegistered\uFF09\u3002\u82E5\u901A\u77E5\u672A\u6062\u590D\uFF0C\u8BF7\u91CD\u542F App \u91CD\u65B0\u6CE8\u518C push token\u3002`);
5225
5293
  }
5226
5294
  } else if (ticket.status === "ok" && typeof ticket.id === "string" && targetTokens[i]) {
@@ -5267,6 +5335,7 @@ var ExpoNotificationChannel = class {
5267
5335
  this.tokens.delete(token);
5268
5336
  this.tokenWsMap.delete(token);
5269
5337
  this.soundPreferences.delete(token);
5338
+ this.persist();
5270
5339
  console.warn("[ExpoNotificationChannel] \u26A0\uFE0F \u5DF2\u79FB\u9664\u5931\u6548 token\uFF08receipt DeviceNotRegistered\uFF09\u3002\u91CD\u542F App \u53EF\u91CD\u65B0\u6CE8\u518C\u3002");
5271
5340
  } else if (errorCode === "InvalidCredentials" || errorCode === "MismatchSenderId") {
5272
5341
  console.error(
@@ -5766,6 +5835,9 @@ var PairingManager = class {
5766
5835
 
5767
5836
  // src/utils/shellPath.ts
5768
5837
  var import_node_child_process7 = require("child_process");
5838
+ var import_node_fs5 = require("fs");
5839
+ var import_node_path7 = require("path");
5840
+ var import_node_os8 = require("os");
5769
5841
  var fixed = false;
5770
5842
  function fixShellPath() {
5771
5843
  if (fixed || isWindows) {
@@ -5773,23 +5845,62 @@ function fixShellPath() {
5773
5845
  return;
5774
5846
  }
5775
5847
  fixed = true;
5848
+ const fromShell = readLoginShellPath();
5849
+ if (fromShell) {
5850
+ process.env.PATH = mergePath(fromShell, process.env.PATH || "");
5851
+ }
5852
+ const stableNodeDir = resolveStableNodeDir();
5853
+ if (stableNodeDir) {
5854
+ process.env.PATH = mergePath(stableNodeDir, process.env.PATH || "");
5855
+ }
5856
+ }
5857
+ function readLoginShellPath() {
5776
5858
  const shell = process.env.SHELL || "/bin/zsh";
5777
5859
  const isFish = /\/fish$/.test(shell);
5778
5860
  const printPathCmd = isFish ? "string join : $PATH" : 'printf "%s" "$PATH"';
5779
- let raw;
5861
+ for (const flags of [["-i", "-l", "-c"], ["-l", "-c"]]) {
5862
+ try {
5863
+ const raw = (0, import_node_child_process7.execFileSync)(shell, [...flags, printPathCmd], {
5864
+ encoding: "utf8",
5865
+ timeout: 4e3,
5866
+ stdio: ["ignore", "pipe", "ignore"]
5867
+ }).trim();
5868
+ if (raw) return raw;
5869
+ } catch {
5870
+ }
5871
+ }
5872
+ return null;
5873
+ }
5874
+ function resolveStableNodeDir() {
5875
+ const exe = isWindows ? "node.exe" : "node";
5876
+ for (const dir of (process.env.PATH || "").split(":")) {
5877
+ if (!dir) continue;
5878
+ try {
5879
+ const p = (0, import_node_path7.join)(dir, exe);
5880
+ (0, import_node_fs5.accessSync)(p, import_node_fs5.constants.X_OK);
5881
+ return (0, import_node_path7.dirname)((0, import_node_fs5.realpathSync)(p));
5882
+ } catch {
5883
+ }
5884
+ }
5885
+ return scanFnmNodeDir();
5886
+ }
5887
+ function scanFnmNodeDir() {
5888
+ const base = (0, import_node_path7.join)((0, import_node_os8.homedir)(), ".fnm", "node-versions");
5780
5889
  try {
5781
- raw = (0, import_node_child_process7.execFileSync)(shell, ["-l", "-c", printPathCmd], {
5782
- encoding: "utf8",
5783
- timeout: 3e3,
5784
- stdio: ["ignore", "pipe", "ignore"]
5785
- });
5786
- } catch (err) {
5787
- console.warn("[fixShellPath] failed to read login shell PATH:", err);
5788
- return;
5890
+ const versions = (0, import_node_fs5.readdirSync)(base).filter((v) => /^v?\d+\./.test(v)).sort(
5891
+ (a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })
5892
+ );
5893
+ for (const v of versions) {
5894
+ const dir = (0, import_node_path7.join)(base, v, "installation", "bin");
5895
+ try {
5896
+ (0, import_node_fs5.accessSync)((0, import_node_path7.join)(dir, "node"), import_node_fs5.constants.X_OK);
5897
+ return dir;
5898
+ } catch {
5899
+ }
5900
+ }
5901
+ } catch {
5789
5902
  }
5790
- const fromShell = raw.trim();
5791
- if (!fromShell) return;
5792
- process.env.PATH = mergePath(fromShell, process.env.PATH || "");
5903
+ return null;
5793
5904
  }
5794
5905
  function mergePath(primary, secondary) {
5795
5906
  const seen = /* @__PURE__ */ new Set();
@@ -6023,13 +6134,13 @@ var TerminalExecutor = class {
6023
6134
  var import_node_child_process9 = require("child_process");
6024
6135
  var import_node_util = require("util");
6025
6136
  var import_promises4 = require("fs/promises");
6026
- var import_node_path6 = require("path");
6027
- var import_node_os7 = require("os");
6137
+ var import_node_path8 = require("path");
6138
+ var import_node_os9 = require("os");
6028
6139
  var import_uuid5 = require("uuid");
6029
6140
  var execAsync = (0, import_node_util.promisify)(import_node_child_process9.exec);
6030
6141
  var BUILD_TIMEOUT_MS = 30 * 60 * 1e3;
6031
6142
  var INSTALL_TIMEOUT_MS = 5 * 60 * 1e3;
6032
- var CONFIG_FILE = (0, import_node_path6.join)((0, import_node_os7.homedir)(), ".sessix", "xcode-config.json");
6143
+ var CONFIG_FILE = (0, import_node_path8.join)((0, import_node_os9.homedir)(), ".sessix", "xcode-config.json");
6033
6144
  var SKIP_DIRS = /* @__PURE__ */ new Set([
6034
6145
  "node_modules",
6035
6146
  ".git",
@@ -6082,7 +6193,7 @@ var XcodeBuildExecutor = class {
6082
6193
  return this.configCache;
6083
6194
  }
6084
6195
  async writeConfigs(store) {
6085
- await (0, import_promises4.mkdir)((0, import_node_path6.join)((0, import_node_os7.homedir)(), ".sessix"), { recursive: true });
6196
+ await (0, import_promises4.mkdir)((0, import_node_path8.join)((0, import_node_os9.homedir)(), ".sessix"), { recursive: true });
6086
6197
  await (0, import_promises4.writeFile)(CONFIG_FILE, JSON.stringify(store, null, 2), "utf8");
6087
6198
  this.configCache = store;
6088
6199
  }
@@ -6135,7 +6246,7 @@ var XcodeBuildExecutor = class {
6135
6246
  if (SKIP_DIRS.has(name)) continue;
6136
6247
  if (name.startsWith(".")) continue;
6137
6248
  if (name.endsWith(".xcodeproj") || name.endsWith(".xcworkspace")) continue;
6138
- const childPath = (0, import_node_path6.join)(currentPath, name);
6249
+ const childPath = (0, import_node_path8.join)(currentPath, name);
6139
6250
  await this.scanDir(rootPath, childPath, depth + 1, results);
6140
6251
  }
6141
6252
  }
@@ -6362,7 +6473,7 @@ ${e.stderr ?? ""}`);
6362
6473
  if (!builtDir || !productName) {
6363
6474
  throw new Error("\u65E0\u6CD5\u4ECE -showBuildSettings \u4E2D\u8BFB\u53D6 BUILT_PRODUCTS_DIR / FULL_PRODUCT_NAME");
6364
6475
  }
6365
- return (0, import_node_path6.join)(builtDir, productName);
6476
+ return (0, import_node_path8.join)(builtDir, productName);
6366
6477
  }
6367
6478
  // ============================================
6368
6479
  // 清理
@@ -6434,7 +6545,7 @@ function kindOrder(k) {
6434
6545
 
6435
6546
  // src/commands/CommandDiscovery.ts
6436
6547
  var import_promises5 = require("fs/promises");
6437
- var import_node_path7 = require("path");
6548
+ var import_node_path9 = require("path");
6438
6549
  var import_node_crypto = require("crypto");
6439
6550
  var CACHE_TTL_MS = 5 * 60 * 1e3;
6440
6551
  var MAX_README_BYTES = 256 * 1024;
@@ -6458,7 +6569,7 @@ var CommandDiscovery = class {
6458
6569
  this.scanReadme(projectPath, "CLAUDE.md", "claude.md", collector)
6459
6570
  ]);
6460
6571
  for (const sub of SUBPACKAGE_DIRS) {
6461
- const subRoot = (0, import_node_path7.join)(projectPath, sub);
6572
+ const subRoot = (0, import_node_path9.join)(projectPath, sub);
6462
6573
  let entries;
6463
6574
  try {
6464
6575
  entries = await (0, import_promises5.readdir)(subRoot);
@@ -6468,7 +6579,7 @@ var CommandDiscovery = class {
6468
6579
  let scanned = 0;
6469
6580
  for (const name of entries) {
6470
6581
  if (name.startsWith(".") || scanned >= MAX_SCAN_PER_DIR) continue;
6471
- const childAbs = (0, import_node_path7.join)(subRoot, name);
6582
+ const childAbs = (0, import_node_path9.join)(subRoot, name);
6472
6583
  try {
6473
6584
  const s = await (0, import_promises5.stat)(childAbs);
6474
6585
  if (!s.isDirectory()) continue;
@@ -6509,7 +6620,7 @@ var CommandDiscovery = class {
6509
6620
  // ============================================
6510
6621
  async scanPackageJson(rootPath, subDir, out) {
6511
6622
  const file = subDir ? `${subDir}/package.json` : "package.json";
6512
- const abs = (0, import_node_path7.join)(rootPath, file);
6623
+ const abs = (0, import_node_path9.join)(rootPath, file);
6513
6624
  let raw;
6514
6625
  try {
6515
6626
  raw = await (0, import_promises5.readFile)(abs, "utf8");
@@ -6540,7 +6651,7 @@ var CommandDiscovery = class {
6540
6651
  }
6541
6652
  async scanMakefile(rootPath, subDir, out) {
6542
6653
  const file = subDir ? `${subDir}/Makefile` : "Makefile";
6543
- const abs = (0, import_node_path7.join)(rootPath, file);
6654
+ const abs = (0, import_node_path9.join)(rootPath, file);
6544
6655
  let raw;
6545
6656
  try {
6546
6657
  raw = await (0, import_promises5.readFile)(abs, "utf8");
@@ -6581,7 +6692,7 @@ var CommandDiscovery = class {
6581
6692
  }
6582
6693
  async scanJustfile(rootPath, subDir, out) {
6583
6694
  const file = subDir ? `${subDir}/justfile` : "justfile";
6584
- const abs = (0, import_node_path7.join)(rootPath, file);
6695
+ const abs = (0, import_node_path9.join)(rootPath, file);
6585
6696
  let raw;
6586
6697
  try {
6587
6698
  raw = await (0, import_promises5.readFile)(abs, "utf8");
@@ -6622,7 +6733,7 @@ var CommandDiscovery = class {
6622
6733
  }
6623
6734
  async scanCargo(rootPath, subDir, out) {
6624
6735
  const file = subDir ? `${subDir}/Cargo.toml` : "Cargo.toml";
6625
- const abs = (0, import_node_path7.join)(rootPath, file);
6736
+ const abs = (0, import_node_path9.join)(rootPath, file);
6626
6737
  try {
6627
6738
  await (0, import_promises5.stat)(abs);
6628
6739
  } catch {
@@ -6653,7 +6764,7 @@ var CommandDiscovery = class {
6653
6764
  for (const name of ["docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"]) {
6654
6765
  const file = subDir ? `${subDir}/${name}` : name;
6655
6766
  try {
6656
- await (0, import_promises5.stat)((0, import_node_path7.join)(rootPath, file));
6767
+ await (0, import_promises5.stat)((0, import_node_path9.join)(rootPath, file));
6657
6768
  } catch {
6658
6769
  continue;
6659
6770
  }
@@ -6679,7 +6790,7 @@ var CommandDiscovery = class {
6679
6790
  }
6680
6791
  }
6681
6792
  async scanReadme(rootPath, fileName, source, out) {
6682
- const abs = (0, import_node_path7.join)(rootPath, fileName);
6793
+ const abs = (0, import_node_path9.join)(rootPath, fileName);
6683
6794
  let raw;
6684
6795
  try {
6685
6796
  const s = await (0, import_promises5.stat)(abs);
@@ -7059,8 +7170,8 @@ var GitExecutor = class {
7059
7170
 
7060
7171
  // src/scheduling/ScheduledSessionManager.ts
7061
7172
  var import_promises6 = require("fs/promises");
7062
- var import_node_os8 = require("os");
7063
- var import_node_path8 = require("path");
7173
+ var import_node_os10 = require("os");
7174
+ var import_node_path10 = require("path");
7064
7175
  var import_uuid7 = require("uuid");
7065
7176
  var MAX_TIMEOUT_MS = 2147483647;
7066
7177
  var ScheduledSessionManager = class {
@@ -7071,7 +7182,7 @@ var ScheduledSessionManager = class {
7071
7182
  onFired;
7072
7183
  persistTimer = null;
7073
7184
  constructor(opts) {
7074
- this.storeFile = opts.storeFile ?? (0, import_node_path8.join)((0, import_node_os8.homedir)(), ".sessix", "scheduled-sessions.json");
7185
+ this.storeFile = opts.storeFile ?? (0, import_node_path10.join)((0, import_node_os10.homedir)(), ".sessix", "scheduled-sessions.json");
7075
7186
  this.onFire = opts.onFire;
7076
7187
  this.onChange = opts.onChange;
7077
7188
  this.onFired = opts.onFired;
@@ -7176,7 +7287,7 @@ var ScheduledSessionManager = class {
7176
7287
  this.persistTimer = setTimeout(() => {
7177
7288
  this.persistTimer = null;
7178
7289
  const tasks = [...this.tasks.values()].map((e) => e.task);
7179
- (0, import_promises6.mkdir)((0, import_node_path8.join)(this.storeFile, ".."), { recursive: true }).then(() => (0, import_promises6.writeFile)(this.storeFile, JSON.stringify(tasks, null, 2), "utf8")).catch((err) => {
7290
+ (0, import_promises6.mkdir)((0, import_node_path10.join)(this.storeFile, ".."), { recursive: true }).then(() => (0, import_promises6.writeFile)(this.storeFile, JSON.stringify(tasks, null, 2), "utf8")).catch((err) => {
7180
7291
  console.error("[ScheduledSessionManager] persist error:", err);
7181
7292
  });
7182
7293
  }, 500);
@@ -7280,7 +7391,7 @@ async function killPortProcess(port) {
7280
7391
  }
7281
7392
  }
7282
7393
  async function loadApnsConfigFromFile() {
7283
- const path2 = (0, import_node_path9.join)((0, import_node_os9.homedir)(), ".sessix", "apns.json");
7394
+ const path2 = (0, import_node_path11.join)((0, import_node_os11.homedir)(), ".sessix", "apns.json");
7284
7395
  try {
7285
7396
  const raw = await (0, import_promises7.readFile)(path2, "utf8");
7286
7397
  const cfg = JSON.parse(raw);
@@ -7327,8 +7438,8 @@ async function createWithRetry(label, port, factory) {
7327
7438
  }
7328
7439
  async function start(opts = {}) {
7329
7440
  fixShellPath();
7330
- const configDir = (0, import_node_path9.join)((0, import_node_os9.homedir)(), ".sessix");
7331
- const tokenFile = (0, import_node_path9.join)(configDir, "token");
7441
+ const configDir = (0, import_node_path11.join)((0, import_node_os11.homedir)(), ".sessix");
7442
+ const tokenFile = (0, import_node_path11.join)(configDir, "token");
7332
7443
  let token;
7333
7444
  if (opts.token !== void 0) {
7334
7445
  token = opts.token;
@@ -7393,7 +7504,7 @@ async function start(opts = {}) {
7393
7504
  let mdnsService = null;
7394
7505
  const pairingManager = new PairingManager({
7395
7506
  token,
7396
- serverName: (0, import_node_os9.hostname)(),
7507
+ serverName: (0, import_node_os11.hostname)(),
7397
7508
  version: "0.2.0",
7398
7509
  onStateChange: (state) => mdnsService?.updatePairingState(state)
7399
7510
  });
@@ -8201,7 +8312,7 @@ async function start(opts = {}) {
8201
8312
  var import_qrcode_terminal = __toESM(require("qrcode-terminal"));
8202
8313
  function getPackageVersion() {
8203
8314
  try {
8204
- const pkg = JSON.parse((0, import_node_fs4.readFileSync)((0, import_node_path10.join)(__dirname, "..", "package.json"), "utf8"));
8315
+ const pkg = JSON.parse((0, import_node_fs6.readFileSync)((0, import_node_path12.join)(__dirname, "..", "package.json"), "utf8"));
8205
8316
  return pkg.version ?? "0.0.0";
8206
8317
  } catch {
8207
8318
  return "0.0.0";
@@ -8345,7 +8456,7 @@ ${t("startup.pairingReopened")}`);
8345
8456
  }
8346
8457
  }
8347
8458
  function getLocalIp() {
8348
- const interfaces = (0, import_node_os10.networkInterfaces)();
8459
+ const interfaces = (0, import_node_os12.networkInterfaces)();
8349
8460
  for (const iface of Object.values(interfaces)) {
8350
8461
  for (const addr of iface ?? []) {
8351
8462
  if (addr.family === "IPv4" && !addr.internal) {
package/dist/server.js CHANGED
@@ -309,8 +309,8 @@ function t(key, params) {
309
309
  // src/server.ts
310
310
  var import_uuid8 = require("uuid");
311
311
  var import_promises7 = require("fs/promises");
312
- var import_node_os9 = require("os");
313
- var import_node_path9 = require("path");
312
+ var import_node_os11 = require("os");
313
+ var import_node_path11 = require("path");
314
314
  var import_node_child_process12 = require("child_process");
315
315
  var import_node_util3 = require("util");
316
316
  var import_node_v8 = require("v8");
@@ -451,6 +451,21 @@ var import_promises = require("fs/promises");
451
451
  var import_readline = require("readline");
452
452
  var import_path = require("path");
453
453
  var import_os = require("os");
454
+
455
+ // src/utils/modelValidation.ts
456
+ function isUsableModel(model) {
457
+ if (typeof model !== "string") return false;
458
+ const trimmed = model.trim();
459
+ if (!trimmed) return false;
460
+ if (trimmed === "unknown") return false;
461
+ if (trimmed.startsWith("<")) return false;
462
+ return true;
463
+ }
464
+ function sanitizeModel(model) {
465
+ return isUsableModel(model) ? model.trim() : void 0;
466
+ }
467
+
468
+ // src/session/ProjectReader.ts
454
469
  var CLAUDE_PROJECTS_DIR = (0, import_path.join)((0, import_os.homedir)(), ".claude", "projects");
455
470
  function getSessionFilePath(projectPath, sessionId) {
456
471
  return (0, import_path.join)(CLAUDE_PROJECTS_DIR, encodeDirName(projectPath), `${sessionId}.jsonl`);
@@ -471,7 +486,7 @@ async function getSessionModel(projectPath, sessionId) {
471
486
  const obj = JSON.parse(line);
472
487
  if (obj.type !== "assistant" || !obj.message) continue;
473
488
  const model = obj.message.model;
474
- if (typeof model === "string" && model && model !== "unknown") {
489
+ if (isUsableModel(model)) {
475
490
  lastModel = model;
476
491
  }
477
492
  } catch {
@@ -1089,17 +1104,22 @@ var ProcessProvider = class {
1089
1104
  } else {
1090
1105
  args.push("--session-id", sessionId);
1091
1106
  }
1092
- if (model) {
1093
- args.push("--model", model);
1107
+ const safeModel = sanitizeModel(model);
1108
+ if (model && !safeModel) {
1109
+ console.warn(`[ProcessProvider] Session ${sessionId}: ignoring invalid model "${model}", falling back to CLI default`);
1110
+ }
1111
+ if (safeModel) {
1112
+ args.push("--model", safeModel);
1094
1113
  }
1114
+ const safeFallbackModel = sanitizeModel(fallbackModel);
1095
1115
  if (permissionMode && permissionMode !== "default") {
1096
1116
  args.push("--permission-mode", permissionMode);
1097
1117
  }
1098
1118
  if (effort) {
1099
1119
  args.push("--effort", effort);
1100
1120
  }
1101
- if (fallbackModel) {
1102
- args.push("--fallback-model", fallbackModel);
1121
+ if (safeFallbackModel) {
1122
+ args.push("--fallback-model", safeFallbackModel);
1103
1123
  }
1104
1124
  if (maxBudgetUsd != null) {
1105
1125
  args.push("--max-budget-usd", String(maxBudgetUsd));
@@ -5133,6 +5153,36 @@ var DesktopNotificationChannel = class {
5133
5153
  }
5134
5154
  };
5135
5155
 
5156
+ // src/notification/pushTokenStore.ts
5157
+ var import_node_fs4 = require("fs");
5158
+ var import_node_os7 = require("os");
5159
+ var import_node_path6 = require("path");
5160
+ var DEFAULT_PUSH_TOKENS_FILE = (0, import_node_path6.join)((0, import_node_os7.homedir)(), ".sessix", "push-tokens.json");
5161
+ function loadPushTokens(filePath = DEFAULT_PUSH_TOKENS_FILE) {
5162
+ try {
5163
+ const parsed = JSON.parse((0, import_node_fs4.readFileSync)(filePath, "utf-8"));
5164
+ if (!Array.isArray(parsed)) return [];
5165
+ return parsed.filter((t2) => typeof t2 === "string");
5166
+ } catch {
5167
+ return [];
5168
+ }
5169
+ }
5170
+ function savePushTokens(tokens, filePath = DEFAULT_PUSH_TOKENS_FILE) {
5171
+ const deduped = [];
5172
+ const seen = /* @__PURE__ */ new Set();
5173
+ for (const t2 of tokens) {
5174
+ if (typeof t2 !== "string" || seen.has(t2)) continue;
5175
+ seen.add(t2);
5176
+ deduped.push(t2);
5177
+ }
5178
+ try {
5179
+ (0, import_node_fs4.mkdirSync)((0, import_node_path6.dirname)(filePath), { recursive: true });
5180
+ (0, import_node_fs4.writeFileSync)(filePath, JSON.stringify(deduped, null, 2), "utf-8");
5181
+ } catch (err) {
5182
+ console.warn("[pushTokenStore] \u5199\u5165 push token \u5931\u8D25:", err);
5183
+ }
5184
+ }
5185
+
5136
5186
  // src/notification/ExpoNotificationChannel.ts
5137
5187
  var EXPO_PUSH_API = "https://exp.host/--/api/v2/push/send";
5138
5188
  var EXPO_RECEIPT_API = "https://exp.host/--/api/v2/push/getReceipts";
@@ -5143,18 +5193,35 @@ var ExpoNotificationChannel = class {
5143
5193
  tokenWsMap = /* @__PURE__ */ new Map();
5144
5194
  /** per-token 通知音效偏好 */
5145
5195
  soundPreferences = /* @__PURE__ */ new Map();
5196
+ /** push token 持久化文件路径 */
5197
+ pushTokensFile;
5198
+ constructor(opts = {}) {
5199
+ this.pushTokensFile = opts.pushTokensFile ?? DEFAULT_PUSH_TOKENS_FILE;
5200
+ for (const token of loadPushTokens(this.pushTokensFile)) {
5201
+ this.tokens.add(token);
5202
+ }
5203
+ if (this.tokens.size > 0) {
5204
+ console.log(`[ExpoNotificationChannel] \u4ECE\u78C1\u76D8\u91CD\u8F7D ${this.tokens.size} \u4E2A push token`);
5205
+ }
5206
+ }
5207
+ /** 把当前 token 集合落盘,供进程重启后重载。 */
5208
+ persist() {
5209
+ savePushTokens(Array.from(this.tokens), this.pushTokensFile);
5210
+ }
5146
5211
  isAvailable() {
5147
5212
  return this.tokens.size > 0;
5148
5213
  }
5149
5214
  addToken(token, ws) {
5150
5215
  this.tokens.add(token);
5151
5216
  if (ws) this.tokenWsMap.set(token, ws);
5217
+ this.persist();
5152
5218
  console.log(`[ExpoNotificationChannel] ${t("notification.tokenRegistered", { count: this.tokens.size })}`);
5153
5219
  }
5154
5220
  removeToken(token) {
5155
5221
  this.tokens.delete(token);
5156
5222
  this.tokenWsMap.delete(token);
5157
5223
  this.soundPreferences.delete(token);
5224
+ this.persist();
5158
5225
  console.log(`[ExpoNotificationChannel] ${t("notification.tokenRemoved", { count: this.tokens.size })}`);
5159
5226
  }
5160
5227
  /** 更新某个 token 的音效偏好 */
@@ -5226,6 +5293,7 @@ var ExpoNotificationChannel = class {
5226
5293
  this.tokens.delete(staleToken);
5227
5294
  this.tokenWsMap.delete(staleToken);
5228
5295
  this.soundPreferences.delete(staleToken);
5296
+ this.persist();
5229
5297
  console.warn(`[ExpoNotificationChannel] \u26A0\uFE0F \u5DF2\u79FB\u9664\u5931\u6548 token\uFF08DeviceNotRegistered\uFF09\u3002\u82E5\u901A\u77E5\u672A\u6062\u590D\uFF0C\u8BF7\u91CD\u542F App \u91CD\u65B0\u6CE8\u518C push token\u3002`);
5230
5298
  }
5231
5299
  } else if (ticket.status === "ok" && typeof ticket.id === "string" && targetTokens[i]) {
@@ -5272,6 +5340,7 @@ var ExpoNotificationChannel = class {
5272
5340
  this.tokens.delete(token);
5273
5341
  this.tokenWsMap.delete(token);
5274
5342
  this.soundPreferences.delete(token);
5343
+ this.persist();
5275
5344
  console.warn("[ExpoNotificationChannel] \u26A0\uFE0F \u5DF2\u79FB\u9664\u5931\u6548 token\uFF08receipt DeviceNotRegistered\uFF09\u3002\u91CD\u542F App \u53EF\u91CD\u65B0\u6CE8\u518C\u3002");
5276
5345
  } else if (errorCode === "InvalidCredentials" || errorCode === "MismatchSenderId") {
5277
5346
  console.error(
@@ -5771,6 +5840,9 @@ var PairingManager = class {
5771
5840
 
5772
5841
  // src/utils/shellPath.ts
5773
5842
  var import_node_child_process7 = require("child_process");
5843
+ var import_node_fs5 = require("fs");
5844
+ var import_node_path7 = require("path");
5845
+ var import_node_os8 = require("os");
5774
5846
  var fixed = false;
5775
5847
  function fixShellPath() {
5776
5848
  if (fixed || isWindows) {
@@ -5778,23 +5850,62 @@ function fixShellPath() {
5778
5850
  return;
5779
5851
  }
5780
5852
  fixed = true;
5853
+ const fromShell = readLoginShellPath();
5854
+ if (fromShell) {
5855
+ process.env.PATH = mergePath(fromShell, process.env.PATH || "");
5856
+ }
5857
+ const stableNodeDir = resolveStableNodeDir();
5858
+ if (stableNodeDir) {
5859
+ process.env.PATH = mergePath(stableNodeDir, process.env.PATH || "");
5860
+ }
5861
+ }
5862
+ function readLoginShellPath() {
5781
5863
  const shell = process.env.SHELL || "/bin/zsh";
5782
5864
  const isFish = /\/fish$/.test(shell);
5783
5865
  const printPathCmd = isFish ? "string join : $PATH" : 'printf "%s" "$PATH"';
5784
- let raw;
5866
+ for (const flags of [["-i", "-l", "-c"], ["-l", "-c"]]) {
5867
+ try {
5868
+ const raw = (0, import_node_child_process7.execFileSync)(shell, [...flags, printPathCmd], {
5869
+ encoding: "utf8",
5870
+ timeout: 4e3,
5871
+ stdio: ["ignore", "pipe", "ignore"]
5872
+ }).trim();
5873
+ if (raw) return raw;
5874
+ } catch {
5875
+ }
5876
+ }
5877
+ return null;
5878
+ }
5879
+ function resolveStableNodeDir() {
5880
+ const exe = isWindows ? "node.exe" : "node";
5881
+ for (const dir of (process.env.PATH || "").split(":")) {
5882
+ if (!dir) continue;
5883
+ try {
5884
+ const p = (0, import_node_path7.join)(dir, exe);
5885
+ (0, import_node_fs5.accessSync)(p, import_node_fs5.constants.X_OK);
5886
+ return (0, import_node_path7.dirname)((0, import_node_fs5.realpathSync)(p));
5887
+ } catch {
5888
+ }
5889
+ }
5890
+ return scanFnmNodeDir();
5891
+ }
5892
+ function scanFnmNodeDir() {
5893
+ const base = (0, import_node_path7.join)((0, import_node_os8.homedir)(), ".fnm", "node-versions");
5785
5894
  try {
5786
- raw = (0, import_node_child_process7.execFileSync)(shell, ["-l", "-c", printPathCmd], {
5787
- encoding: "utf8",
5788
- timeout: 3e3,
5789
- stdio: ["ignore", "pipe", "ignore"]
5790
- });
5791
- } catch (err) {
5792
- console.warn("[fixShellPath] failed to read login shell PATH:", err);
5793
- return;
5895
+ const versions = (0, import_node_fs5.readdirSync)(base).filter((v) => /^v?\d+\./.test(v)).sort(
5896
+ (a, b) => b.localeCompare(a, void 0, { numeric: true, sensitivity: "base" })
5897
+ );
5898
+ for (const v of versions) {
5899
+ const dir = (0, import_node_path7.join)(base, v, "installation", "bin");
5900
+ try {
5901
+ (0, import_node_fs5.accessSync)((0, import_node_path7.join)(dir, "node"), import_node_fs5.constants.X_OK);
5902
+ return dir;
5903
+ } catch {
5904
+ }
5905
+ }
5906
+ } catch {
5794
5907
  }
5795
- const fromShell = raw.trim();
5796
- if (!fromShell) return;
5797
- process.env.PATH = mergePath(fromShell, process.env.PATH || "");
5908
+ return null;
5798
5909
  }
5799
5910
  function mergePath(primary, secondary) {
5800
5911
  const seen = /* @__PURE__ */ new Set();
@@ -6028,13 +6139,13 @@ var TerminalExecutor = class {
6028
6139
  var import_node_child_process9 = require("child_process");
6029
6140
  var import_node_util = require("util");
6030
6141
  var import_promises4 = require("fs/promises");
6031
- var import_node_path6 = require("path");
6032
- var import_node_os7 = require("os");
6142
+ var import_node_path8 = require("path");
6143
+ var import_node_os9 = require("os");
6033
6144
  var import_uuid5 = require("uuid");
6034
6145
  var execAsync = (0, import_node_util.promisify)(import_node_child_process9.exec);
6035
6146
  var BUILD_TIMEOUT_MS = 30 * 60 * 1e3;
6036
6147
  var INSTALL_TIMEOUT_MS = 5 * 60 * 1e3;
6037
- var CONFIG_FILE = (0, import_node_path6.join)((0, import_node_os7.homedir)(), ".sessix", "xcode-config.json");
6148
+ var CONFIG_FILE = (0, import_node_path8.join)((0, import_node_os9.homedir)(), ".sessix", "xcode-config.json");
6038
6149
  var SKIP_DIRS = /* @__PURE__ */ new Set([
6039
6150
  "node_modules",
6040
6151
  ".git",
@@ -6087,7 +6198,7 @@ var XcodeBuildExecutor = class {
6087
6198
  return this.configCache;
6088
6199
  }
6089
6200
  async writeConfigs(store) {
6090
- await (0, import_promises4.mkdir)((0, import_node_path6.join)((0, import_node_os7.homedir)(), ".sessix"), { recursive: true });
6201
+ await (0, import_promises4.mkdir)((0, import_node_path8.join)((0, import_node_os9.homedir)(), ".sessix"), { recursive: true });
6091
6202
  await (0, import_promises4.writeFile)(CONFIG_FILE, JSON.stringify(store, null, 2), "utf8");
6092
6203
  this.configCache = store;
6093
6204
  }
@@ -6140,7 +6251,7 @@ var XcodeBuildExecutor = class {
6140
6251
  if (SKIP_DIRS.has(name)) continue;
6141
6252
  if (name.startsWith(".")) continue;
6142
6253
  if (name.endsWith(".xcodeproj") || name.endsWith(".xcworkspace")) continue;
6143
- const childPath = (0, import_node_path6.join)(currentPath, name);
6254
+ const childPath = (0, import_node_path8.join)(currentPath, name);
6144
6255
  await this.scanDir(rootPath, childPath, depth + 1, results);
6145
6256
  }
6146
6257
  }
@@ -6367,7 +6478,7 @@ ${e.stderr ?? ""}`);
6367
6478
  if (!builtDir || !productName) {
6368
6479
  throw new Error("\u65E0\u6CD5\u4ECE -showBuildSettings \u4E2D\u8BFB\u53D6 BUILT_PRODUCTS_DIR / FULL_PRODUCT_NAME");
6369
6480
  }
6370
- return (0, import_node_path6.join)(builtDir, productName);
6481
+ return (0, import_node_path8.join)(builtDir, productName);
6371
6482
  }
6372
6483
  // ============================================
6373
6484
  // 清理
@@ -6439,7 +6550,7 @@ function kindOrder(k) {
6439
6550
 
6440
6551
  // src/commands/CommandDiscovery.ts
6441
6552
  var import_promises5 = require("fs/promises");
6442
- var import_node_path7 = require("path");
6553
+ var import_node_path9 = require("path");
6443
6554
  var import_node_crypto = require("crypto");
6444
6555
  var CACHE_TTL_MS = 5 * 60 * 1e3;
6445
6556
  var MAX_README_BYTES = 256 * 1024;
@@ -6463,7 +6574,7 @@ var CommandDiscovery = class {
6463
6574
  this.scanReadme(projectPath, "CLAUDE.md", "claude.md", collector)
6464
6575
  ]);
6465
6576
  for (const sub of SUBPACKAGE_DIRS) {
6466
- const subRoot = (0, import_node_path7.join)(projectPath, sub);
6577
+ const subRoot = (0, import_node_path9.join)(projectPath, sub);
6467
6578
  let entries;
6468
6579
  try {
6469
6580
  entries = await (0, import_promises5.readdir)(subRoot);
@@ -6473,7 +6584,7 @@ var CommandDiscovery = class {
6473
6584
  let scanned = 0;
6474
6585
  for (const name of entries) {
6475
6586
  if (name.startsWith(".") || scanned >= MAX_SCAN_PER_DIR) continue;
6476
- const childAbs = (0, import_node_path7.join)(subRoot, name);
6587
+ const childAbs = (0, import_node_path9.join)(subRoot, name);
6477
6588
  try {
6478
6589
  const s = await (0, import_promises5.stat)(childAbs);
6479
6590
  if (!s.isDirectory()) continue;
@@ -6514,7 +6625,7 @@ var CommandDiscovery = class {
6514
6625
  // ============================================
6515
6626
  async scanPackageJson(rootPath, subDir, out) {
6516
6627
  const file = subDir ? `${subDir}/package.json` : "package.json";
6517
- const abs = (0, import_node_path7.join)(rootPath, file);
6628
+ const abs = (0, import_node_path9.join)(rootPath, file);
6518
6629
  let raw;
6519
6630
  try {
6520
6631
  raw = await (0, import_promises5.readFile)(abs, "utf8");
@@ -6545,7 +6656,7 @@ var CommandDiscovery = class {
6545
6656
  }
6546
6657
  async scanMakefile(rootPath, subDir, out) {
6547
6658
  const file = subDir ? `${subDir}/Makefile` : "Makefile";
6548
- const abs = (0, import_node_path7.join)(rootPath, file);
6659
+ const abs = (0, import_node_path9.join)(rootPath, file);
6549
6660
  let raw;
6550
6661
  try {
6551
6662
  raw = await (0, import_promises5.readFile)(abs, "utf8");
@@ -6586,7 +6697,7 @@ var CommandDiscovery = class {
6586
6697
  }
6587
6698
  async scanJustfile(rootPath, subDir, out) {
6588
6699
  const file = subDir ? `${subDir}/justfile` : "justfile";
6589
- const abs = (0, import_node_path7.join)(rootPath, file);
6700
+ const abs = (0, import_node_path9.join)(rootPath, file);
6590
6701
  let raw;
6591
6702
  try {
6592
6703
  raw = await (0, import_promises5.readFile)(abs, "utf8");
@@ -6627,7 +6738,7 @@ var CommandDiscovery = class {
6627
6738
  }
6628
6739
  async scanCargo(rootPath, subDir, out) {
6629
6740
  const file = subDir ? `${subDir}/Cargo.toml` : "Cargo.toml";
6630
- const abs = (0, import_node_path7.join)(rootPath, file);
6741
+ const abs = (0, import_node_path9.join)(rootPath, file);
6631
6742
  try {
6632
6743
  await (0, import_promises5.stat)(abs);
6633
6744
  } catch {
@@ -6658,7 +6769,7 @@ var CommandDiscovery = class {
6658
6769
  for (const name of ["docker-compose.yml", "docker-compose.yaml", "compose.yml", "compose.yaml"]) {
6659
6770
  const file = subDir ? `${subDir}/${name}` : name;
6660
6771
  try {
6661
- await (0, import_promises5.stat)((0, import_node_path7.join)(rootPath, file));
6772
+ await (0, import_promises5.stat)((0, import_node_path9.join)(rootPath, file));
6662
6773
  } catch {
6663
6774
  continue;
6664
6775
  }
@@ -6684,7 +6795,7 @@ var CommandDiscovery = class {
6684
6795
  }
6685
6796
  }
6686
6797
  async scanReadme(rootPath, fileName, source, out) {
6687
- const abs = (0, import_node_path7.join)(rootPath, fileName);
6798
+ const abs = (0, import_node_path9.join)(rootPath, fileName);
6688
6799
  let raw;
6689
6800
  try {
6690
6801
  const s = await (0, import_promises5.stat)(abs);
@@ -7064,8 +7175,8 @@ var GitExecutor = class {
7064
7175
 
7065
7176
  // src/scheduling/ScheduledSessionManager.ts
7066
7177
  var import_promises6 = require("fs/promises");
7067
- var import_node_os8 = require("os");
7068
- var import_node_path8 = require("path");
7178
+ var import_node_os10 = require("os");
7179
+ var import_node_path10 = require("path");
7069
7180
  var import_uuid7 = require("uuid");
7070
7181
  var MAX_TIMEOUT_MS = 2147483647;
7071
7182
  var ScheduledSessionManager = class {
@@ -7076,7 +7187,7 @@ var ScheduledSessionManager = class {
7076
7187
  onFired;
7077
7188
  persistTimer = null;
7078
7189
  constructor(opts) {
7079
- this.storeFile = opts.storeFile ?? (0, import_node_path8.join)((0, import_node_os8.homedir)(), ".sessix", "scheduled-sessions.json");
7190
+ this.storeFile = opts.storeFile ?? (0, import_node_path10.join)((0, import_node_os10.homedir)(), ".sessix", "scheduled-sessions.json");
7080
7191
  this.onFire = opts.onFire;
7081
7192
  this.onChange = opts.onChange;
7082
7193
  this.onFired = opts.onFired;
@@ -7181,7 +7292,7 @@ var ScheduledSessionManager = class {
7181
7292
  this.persistTimer = setTimeout(() => {
7182
7293
  this.persistTimer = null;
7183
7294
  const tasks = [...this.tasks.values()].map((e) => e.task);
7184
- (0, import_promises6.mkdir)((0, import_node_path8.join)(this.storeFile, ".."), { recursive: true }).then(() => (0, import_promises6.writeFile)(this.storeFile, JSON.stringify(tasks, null, 2), "utf8")).catch((err) => {
7295
+ (0, import_promises6.mkdir)((0, import_node_path10.join)(this.storeFile, ".."), { recursive: true }).then(() => (0, import_promises6.writeFile)(this.storeFile, JSON.stringify(tasks, null, 2), "utf8")).catch((err) => {
7185
7296
  console.error("[ScheduledSessionManager] persist error:", err);
7186
7297
  });
7187
7298
  }, 500);
@@ -7285,7 +7396,7 @@ async function killPortProcess(port) {
7285
7396
  }
7286
7397
  }
7287
7398
  async function loadApnsConfigFromFile() {
7288
- const path2 = (0, import_node_path9.join)((0, import_node_os9.homedir)(), ".sessix", "apns.json");
7399
+ const path2 = (0, import_node_path11.join)((0, import_node_os11.homedir)(), ".sessix", "apns.json");
7289
7400
  try {
7290
7401
  const raw = await (0, import_promises7.readFile)(path2, "utf8");
7291
7402
  const cfg = JSON.parse(raw);
@@ -7332,8 +7443,8 @@ async function createWithRetry(label, port, factory) {
7332
7443
  }
7333
7444
  async function start(opts = {}) {
7334
7445
  fixShellPath();
7335
- const configDir = (0, import_node_path9.join)((0, import_node_os9.homedir)(), ".sessix");
7336
- const tokenFile = (0, import_node_path9.join)(configDir, "token");
7446
+ const configDir = (0, import_node_path11.join)((0, import_node_os11.homedir)(), ".sessix");
7447
+ const tokenFile = (0, import_node_path11.join)(configDir, "token");
7337
7448
  let token;
7338
7449
  if (opts.token !== void 0) {
7339
7450
  token = opts.token;
@@ -7398,7 +7509,7 @@ async function start(opts = {}) {
7398
7509
  let mdnsService = null;
7399
7510
  const pairingManager = new PairingManager({
7400
7511
  token,
7401
- serverName: (0, import_node_os9.hostname)(),
7512
+ serverName: (0, import_node_os11.hostname)(),
7402
7513
  version: "0.2.0",
7403
7514
  onStateChange: (state) => mdnsService?.updatePairingState(state)
7404
7515
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sessix-server",
3
- "version": "0.5.3",
3
+ "version": "0.5.6",
4
4
  "bin": {
5
5
  "sessix-server": "dist/index.js"
6
6
  },