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.
- package/dist/index.js +158 -47
- package/dist/server.js +153 -42
- 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
|
|
28
|
-
var
|
|
29
|
-
var
|
|
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
|
|
308
|
-
var
|
|
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 (
|
|
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
|
-
|
|
1088
|
-
|
|
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 (
|
|
1097
|
-
args.push("--fallback-model",
|
|
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
|
-
|
|
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
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
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
|
-
|
|
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
|
|
6027
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
7063
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
7331
|
-
const tokenFile = (0,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
313
|
-
var
|
|
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 (
|
|
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
|
-
|
|
1093
|
-
|
|
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 (
|
|
1102
|
-
args.push("--fallback-model",
|
|
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
|
-
|
|
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
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
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
|
-
|
|
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
|
|
6032
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
7068
|
-
var
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
7336
|
-
const tokenFile = (0,
|
|
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,
|
|
7512
|
+
serverName: (0, import_node_os11.hostname)(),
|
|
7402
7513
|
version: "0.2.0",
|
|
7403
7514
|
onStateChange: (state) => mdnsService?.updatePairingState(state)
|
|
7404
7515
|
});
|