sessix-server 0.2.7 → 0.2.9
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 +180 -84
- package/dist/server.js +180 -84
- package/package.json +10 -1
- package/dist/approval/ApprovalProxy.d.ts +0 -86
- package/dist/approval/ApprovalProxy.d.ts.map +0 -1
- package/dist/approval/ApprovalProxy.js +0 -363
- package/dist/approval/ApprovalProxy.js.map +0 -1
- package/dist/hooks/HookInstaller.d.ts +0 -55
- package/dist/hooks/HookInstaller.d.ts.map +0 -1
- package/dist/hooks/HookInstaller.js +0 -215
- package/dist/hooks/HookInstaller.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/mdns/MdnsService.d.ts +0 -36
- package/dist/mdns/MdnsService.d.ts.map +0 -1
- package/dist/mdns/MdnsService.js +0 -66
- package/dist/mdns/MdnsService.js.map +0 -1
- package/dist/notification/ActivityPushChannel.d.ts +0 -54
- package/dist/notification/ActivityPushChannel.d.ts.map +0 -1
- package/dist/notification/ActivityPushChannel.js +0 -235
- package/dist/notification/ActivityPushChannel.js.map +0 -1
- package/dist/notification/ExpoNotificationChannel.d.ts +0 -17
- package/dist/notification/ExpoNotificationChannel.d.ts.map +0 -1
- package/dist/notification/ExpoNotificationChannel.js +0 -57
- package/dist/notification/ExpoNotificationChannel.js.map +0 -1
- package/dist/notification/MacNotificationChannel.d.ts +0 -22
- package/dist/notification/MacNotificationChannel.d.ts.map +0 -1
- package/dist/notification/MacNotificationChannel.js +0 -33
- package/dist/notification/MacNotificationChannel.js.map +0 -1
- package/dist/notification/NotificationService.d.ts +0 -50
- package/dist/notification/NotificationService.d.ts.map +0 -1
- package/dist/notification/NotificationService.js +0 -177
- package/dist/notification/NotificationService.js.map +0 -1
- package/dist/providers/ExecutionProvider.d.ts +0 -60
- package/dist/providers/ExecutionProvider.d.ts.map +0 -1
- package/dist/providers/ExecutionProvider.js +0 -3
- package/dist/providers/ExecutionProvider.js.map +0 -1
- package/dist/providers/ProcessProvider.d.ts +0 -117
- package/dist/providers/ProcessProvider.d.ts.map +0 -1
- package/dist/providers/ProcessProvider.js +0 -507
- package/dist/providers/ProcessProvider.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/session/ProjectReader.d.ts +0 -44
- package/dist/session/ProjectReader.d.ts.map +0 -1
- package/dist/session/ProjectReader.js +0 -471
- package/dist/session/ProjectReader.js.map +0 -1
- package/dist/session/SessionFileWatcher.d.ts +0 -35
- package/dist/session/SessionFileWatcher.d.ts.map +0 -1
- package/dist/session/SessionFileWatcher.js +0 -207
- package/dist/session/SessionFileWatcher.js.map +0 -1
- package/dist/session/SessionManager.d.ts +0 -114
- package/dist/session/SessionManager.d.ts.map +0 -1
- package/dist/session/SessionManager.js +0 -356
- package/dist/session/SessionManager.js.map +0 -1
- package/dist/ws/WsBridge.d.ts +0 -55
- package/dist/ws/WsBridge.d.ts.map +0 -1
- package/dist/ws/WsBridge.js +0 -220
- package/dist/ws/WsBridge.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -299,7 +299,7 @@ var import_uuid5 = require("uuid");
|
|
|
299
299
|
var import_promises4 = require("fs/promises");
|
|
300
300
|
var import_node_os6 = require("os");
|
|
301
301
|
var import_node_path5 = require("path");
|
|
302
|
-
var
|
|
302
|
+
var import_node_child_process6 = require("child_process");
|
|
303
303
|
var import_node_util = require("util");
|
|
304
304
|
|
|
305
305
|
// src/providers/ProcessProvider.ts
|
|
@@ -2059,79 +2059,120 @@ var ApprovalProxy = class _ApprovalProxy {
|
|
|
2059
2059
|
};
|
|
2060
2060
|
|
|
2061
2061
|
// src/mdns/MdnsService.ts
|
|
2062
|
-
var
|
|
2062
|
+
var import_node_child_process3 = require("child_process");
|
|
2063
2063
|
var import_node_os4 = require("os");
|
|
2064
|
-
function
|
|
2065
|
-
|
|
2066
|
-
for (const [name, addrs] of Object.entries((0, import_node_os4.networkInterfaces)())) {
|
|
2067
|
-
if (name.startsWith("utun") || name === "lo") continue;
|
|
2068
|
-
if (isWindows && (name.startsWith("vEthernet") || name.includes("Loopback"))) continue;
|
|
2069
|
-
for (const addr of addrs ?? []) {
|
|
2070
|
-
if (addr.family === "IPv4" && !addr.internal) {
|
|
2071
|
-
results.push(addr.address);
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
return results;
|
|
2064
|
+
function buildTxtArgs(txt) {
|
|
2065
|
+
return Object.entries(txt).map(([k, v]) => `${k}=${v}`);
|
|
2076
2066
|
}
|
|
2077
2067
|
var MdnsService = class {
|
|
2078
|
-
|
|
2079
|
-
|
|
2068
|
+
proc = null;
|
|
2069
|
+
bonjourInstance = null;
|
|
2070
|
+
bonjourService = null;
|
|
2080
2071
|
wsPort;
|
|
2081
2072
|
httpPort;
|
|
2082
2073
|
version;
|
|
2083
2074
|
pairing;
|
|
2075
|
+
useDnsSd;
|
|
2084
2076
|
constructor(options) {
|
|
2085
2077
|
this.wsPort = options.wsPort;
|
|
2086
2078
|
this.httpPort = options.httpPort;
|
|
2087
2079
|
this.version = options.version ?? "0.1.0";
|
|
2088
2080
|
this.pairing = options.pairing ?? "closed";
|
|
2081
|
+
this.useDnsSd = (0, import_node_os4.platform)() === "darwin";
|
|
2082
|
+
}
|
|
2083
|
+
getTxt() {
|
|
2084
|
+
return {
|
|
2085
|
+
version: this.version,
|
|
2086
|
+
httpPort: String(this.httpPort),
|
|
2087
|
+
wsPort: String(this.wsPort),
|
|
2088
|
+
pairing: this.pairing
|
|
2089
|
+
};
|
|
2089
2090
|
}
|
|
2090
2091
|
/**
|
|
2091
2092
|
* 启动 mDNS 广播
|
|
2092
2093
|
*/
|
|
2093
2094
|
start() {
|
|
2094
|
-
if (this.
|
|
2095
|
+
if (this.useDnsSd) {
|
|
2096
|
+
this.startDnsSd();
|
|
2097
|
+
} else {
|
|
2098
|
+
this.startBonjour();
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
startDnsSd() {
|
|
2102
|
+
if (this.proc) {
|
|
2095
2103
|
console.warn(`[MdnsService] ${t("mdns.alreadyRunning")}`);
|
|
2096
2104
|
return;
|
|
2097
2105
|
}
|
|
2098
|
-
const
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
wsPort: String(this.wsPort),
|
|
2117
|
-
pairing: this.pairing
|
|
2106
|
+
const args = [
|
|
2107
|
+
"-R",
|
|
2108
|
+
"Sessix",
|
|
2109
|
+
"_sessix._tcp",
|
|
2110
|
+
"local",
|
|
2111
|
+
String(this.wsPort),
|
|
2112
|
+
...buildTxtArgs(this.getTxt())
|
|
2113
|
+
];
|
|
2114
|
+
this.proc = (0, import_node_child_process3.spawn)("dns-sd", args, { stdio: "ignore" });
|
|
2115
|
+
this.proc.on("error", (err) => {
|
|
2116
|
+
console.warn(`[MdnsService] dns-sd failed, falling back to bonjour-service: ${err.message}`);
|
|
2117
|
+
this.proc = null;
|
|
2118
|
+
this.useDnsSd = false;
|
|
2119
|
+
this.startBonjour();
|
|
2120
|
+
});
|
|
2121
|
+
this.proc.on("exit", (code) => {
|
|
2122
|
+
if (code !== null && code !== 0) {
|
|
2123
|
+
console.warn(`[MdnsService] dns-sd exited with code ${code}`);
|
|
2118
2124
|
}
|
|
2125
|
+
this.proc = null;
|
|
2119
2126
|
});
|
|
2120
|
-
console.log(`[MdnsService] ${t("mdns.started", { port: this.wsPort })}`);
|
|
2127
|
+
console.log(`[MdnsService] ${t("mdns.started", { port: this.wsPort })} (dns-sd)`);
|
|
2128
|
+
}
|
|
2129
|
+
async startBonjour() {
|
|
2130
|
+
if (this.bonjourInstance) {
|
|
2131
|
+
console.warn(`[MdnsService] ${t("mdns.alreadyRunning")}`);
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
2134
|
+
try {
|
|
2135
|
+
const { default: Bonjour } = await import("bonjour-service");
|
|
2136
|
+
const { networkInterfaces: networkInterfaces2 } = await import("os");
|
|
2137
|
+
const lanAddrs = getLanAddresses(networkInterfaces2);
|
|
2138
|
+
const opts = lanAddrs.length > 0 ? { interface: lanAddrs[0] } : {};
|
|
2139
|
+
const onError = (err) => {
|
|
2140
|
+
if (err.code === "EADDRINUSE") return;
|
|
2141
|
+
console.warn(`[MdnsService] mDNS error (non-fatal): ${err.message}`);
|
|
2142
|
+
};
|
|
2143
|
+
this.bonjourInstance = new Bonjour(opts, onError);
|
|
2144
|
+
this.bonjourInstance.server?.mdns?.on("error", onError);
|
|
2145
|
+
if (lanAddrs.length > 0) {
|
|
2146
|
+
console.log(`[MdnsService] ${t("mdns.boundInterface", { ip: lanAddrs[0] })}`);
|
|
2147
|
+
}
|
|
2148
|
+
this.bonjourService = this.bonjourInstance.publish({
|
|
2149
|
+
name: "Sessix",
|
|
2150
|
+
type: "sessix",
|
|
2151
|
+
port: this.wsPort,
|
|
2152
|
+
txt: this.getTxt()
|
|
2153
|
+
});
|
|
2154
|
+
console.log(`[MdnsService] ${t("mdns.started", { port: this.wsPort })} (bonjour-service)`);
|
|
2155
|
+
} catch (err) {
|
|
2156
|
+
console.warn(`[MdnsService] bonjour-service failed: ${err.message}`);
|
|
2157
|
+
}
|
|
2121
2158
|
}
|
|
2122
2159
|
/**
|
|
2123
2160
|
* 停止 mDNS 广播
|
|
2124
2161
|
*/
|
|
2125
2162
|
stop() {
|
|
2126
|
-
if (this.
|
|
2127
|
-
this.
|
|
2163
|
+
if (this.proc) {
|
|
2164
|
+
this.proc.kill();
|
|
2165
|
+
this.proc = null;
|
|
2166
|
+
}
|
|
2167
|
+
if (this.bonjourService) {
|
|
2168
|
+
this.bonjourService.stop?.(() => {
|
|
2128
2169
|
console.log(`[MdnsService] ${t("mdns.stopped")}`);
|
|
2129
2170
|
});
|
|
2130
|
-
this.
|
|
2171
|
+
this.bonjourService = null;
|
|
2131
2172
|
}
|
|
2132
|
-
if (this.
|
|
2133
|
-
this.
|
|
2134
|
-
this.
|
|
2173
|
+
if (this.bonjourInstance) {
|
|
2174
|
+
this.bonjourInstance.destroy();
|
|
2175
|
+
this.bonjourInstance = null;
|
|
2135
2176
|
}
|
|
2136
2177
|
console.log(`[MdnsService] ${t("mdns.closed")}`);
|
|
2137
2178
|
}
|
|
@@ -2140,30 +2181,45 @@ var MdnsService = class {
|
|
|
2140
2181
|
*/
|
|
2141
2182
|
updatePairingState(state) {
|
|
2142
2183
|
this.pairing = state;
|
|
2143
|
-
if (
|
|
2184
|
+
if (this.useDnsSd) {
|
|
2185
|
+
if (this.proc) {
|
|
2186
|
+
this.proc.kill();
|
|
2187
|
+
this.proc = null;
|
|
2188
|
+
}
|
|
2189
|
+
this.startDnsSd();
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
if (!this.bonjourInstance) return;
|
|
2144
2193
|
const republish = () => {
|
|
2145
|
-
if (!this.
|
|
2146
|
-
this.
|
|
2194
|
+
if (!this.bonjourInstance) return;
|
|
2195
|
+
this.bonjourService = this.bonjourInstance.publish({
|
|
2147
2196
|
name: "Sessix",
|
|
2148
2197
|
type: "sessix",
|
|
2149
2198
|
port: this.wsPort,
|
|
2150
|
-
txt:
|
|
2151
|
-
version: this.version,
|
|
2152
|
-
httpPort: String(this.httpPort),
|
|
2153
|
-
wsPort: String(this.wsPort),
|
|
2154
|
-
pairing: state
|
|
2155
|
-
}
|
|
2199
|
+
txt: this.getTxt()
|
|
2156
2200
|
});
|
|
2157
2201
|
};
|
|
2158
|
-
if (this.
|
|
2159
|
-
const old = this.
|
|
2160
|
-
this.
|
|
2202
|
+
if (this.bonjourService) {
|
|
2203
|
+
const old = this.bonjourService;
|
|
2204
|
+
this.bonjourService = null;
|
|
2161
2205
|
old.stop?.(() => republish());
|
|
2162
2206
|
} else {
|
|
2163
2207
|
republish();
|
|
2164
2208
|
}
|
|
2165
2209
|
}
|
|
2166
2210
|
};
|
|
2211
|
+
function getLanAddresses(networkInterfacesFn) {
|
|
2212
|
+
const results = [];
|
|
2213
|
+
for (const [name, addrs] of Object.entries(networkInterfacesFn())) {
|
|
2214
|
+
if (name.startsWith("utun") || name === "lo") continue;
|
|
2215
|
+
for (const addr of addrs ?? []) {
|
|
2216
|
+
if (addr.family === "IPv4" && !addr.internal) {
|
|
2217
|
+
results.push(addr.address);
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
}
|
|
2221
|
+
return results;
|
|
2222
|
+
}
|
|
2167
2223
|
|
|
2168
2224
|
// src/hooks/HookInstaller.ts
|
|
2169
2225
|
var import_promises2 = require("fs/promises");
|
|
@@ -2637,7 +2693,7 @@ var NotificationService = class {
|
|
|
2637
2693
|
};
|
|
2638
2694
|
|
|
2639
2695
|
// src/notification/DesktopNotificationChannel.ts
|
|
2640
|
-
var
|
|
2696
|
+
var import_node_child_process4 = require("child_process");
|
|
2641
2697
|
var DesktopNotificationChannel = class {
|
|
2642
2698
|
isAvailable() {
|
|
2643
2699
|
return process.platform === "darwin";
|
|
@@ -2649,7 +2705,7 @@ var DesktopNotificationChannel = class {
|
|
|
2649
2705
|
const sound = payload.sound ?? "Ping";
|
|
2650
2706
|
const script = `display notification "${body}" with title "${title}" sound name "${sound}"`;
|
|
2651
2707
|
return new Promise((resolve) => {
|
|
2652
|
-
(0,
|
|
2708
|
+
(0, import_node_child_process4.execFile)("osascript", ["-e", script], (err) => {
|
|
2653
2709
|
if (err) {
|
|
2654
2710
|
console.warn("[DesktopNotificationChannel] Send notification failed:", err.message);
|
|
2655
2711
|
}
|
|
@@ -2975,16 +3031,23 @@ async function getHistoricalSessions(projectPath) {
|
|
|
2975
3031
|
const entries = await (0, import_promises3.readdir)(projectDir, { withFileTypes: true });
|
|
2976
3032
|
const jsonlFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl"));
|
|
2977
3033
|
const mtimeMap = /* @__PURE__ */ new Map();
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
3034
|
+
await Promise.all(
|
|
3035
|
+
jsonlFiles.map(async (entry) => {
|
|
3036
|
+
const sessionId = entry.name.slice(0, -6);
|
|
3037
|
+
const filePath = (0, import_path.join)(projectDir, entry.name);
|
|
3038
|
+
try {
|
|
3039
|
+
const contentTs = await extractLastTimestamp(filePath);
|
|
3040
|
+
if (contentTs) {
|
|
3041
|
+
mtimeMap.set(sessionId, contentTs);
|
|
3042
|
+
} else {
|
|
3043
|
+
const fileStat = await (0, import_promises3.stat)(filePath);
|
|
3044
|
+
mtimeMap.set(sessionId, fileStat.mtimeMs);
|
|
3045
|
+
}
|
|
3046
|
+
} catch {
|
|
3047
|
+
mtimeMap.set(sessionId, 0);
|
|
3048
|
+
}
|
|
3049
|
+
})
|
|
3050
|
+
);
|
|
2988
3051
|
const uuidDirs = entries.filter(
|
|
2989
3052
|
(e) => e.isDirectory() && UUID_RE.test(e.name) && !mtimeMap.has(e.name)
|
|
2990
3053
|
);
|
|
@@ -3135,6 +3198,32 @@ async function getSessionHistory(projectPath, sessionId) {
|
|
|
3135
3198
|
};
|
|
3136
3199
|
}
|
|
3137
3200
|
}
|
|
3201
|
+
async function extractLastTimestamp(filePath) {
|
|
3202
|
+
let fileHandle;
|
|
3203
|
+
try {
|
|
3204
|
+
fileHandle = await (0, import_promises3.open)(filePath, "r");
|
|
3205
|
+
const fileStat = await fileHandle.stat();
|
|
3206
|
+
const readSize = Math.min(fileStat.size, 8192);
|
|
3207
|
+
const buffer = Buffer.alloc(readSize);
|
|
3208
|
+
await fileHandle.read(buffer, 0, readSize, fileStat.size - readSize);
|
|
3209
|
+
const tail = buffer.toString("utf-8");
|
|
3210
|
+
const lines = tail.split("\n").filter((l) => l.trim());
|
|
3211
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
3212
|
+
try {
|
|
3213
|
+
const obj = JSON.parse(lines[i]);
|
|
3214
|
+
if (obj.timestamp) {
|
|
3215
|
+
const ts = new Date(obj.timestamp).getTime();
|
|
3216
|
+
if (!isNaN(ts)) return ts;
|
|
3217
|
+
}
|
|
3218
|
+
} catch {
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
} catch {
|
|
3222
|
+
} finally {
|
|
3223
|
+
await fileHandle?.close();
|
|
3224
|
+
}
|
|
3225
|
+
return void 0;
|
|
3226
|
+
}
|
|
3138
3227
|
async function extractFirstPrompt(filePath) {
|
|
3139
3228
|
let fileHandle;
|
|
3140
3229
|
try {
|
|
@@ -3203,17 +3292,24 @@ async function countJsonlFilesWithMtime(dirPath) {
|
|
|
3203
3292
|
(e) => e.isDirectory() && UUID_RE.test(e.name) && !jsonlNames.has(e.name)
|
|
3204
3293
|
);
|
|
3205
3294
|
let latestMtime = 0;
|
|
3206
|
-
const
|
|
3207
|
-
|
|
3208
|
-
...
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
}
|
|
3216
|
-
|
|
3295
|
+
const jsonlEntries = entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl"));
|
|
3296
|
+
await Promise.all([
|
|
3297
|
+
...jsonlEntries.map(async (entry) => {
|
|
3298
|
+
try {
|
|
3299
|
+
const contentTs = await extractLastTimestamp((0, import_path.join)(dirPath, entry.name));
|
|
3300
|
+
const ts = contentTs ?? (await (0, import_promises3.stat)((0, import_path.join)(dirPath, entry.name))).mtimeMs;
|
|
3301
|
+
if (ts > latestMtime) latestMtime = ts;
|
|
3302
|
+
} catch {
|
|
3303
|
+
}
|
|
3304
|
+
}),
|
|
3305
|
+
...uuidDirs.map(async (entry) => {
|
|
3306
|
+
try {
|
|
3307
|
+
const fileStat = await (0, import_promises3.stat)((0, import_path.join)(dirPath, entry.name));
|
|
3308
|
+
if (fileStat.mtimeMs > latestMtime) latestMtime = fileStat.mtimeMs;
|
|
3309
|
+
} catch {
|
|
3310
|
+
}
|
|
3311
|
+
})
|
|
3312
|
+
]);
|
|
3217
3313
|
return { count: jsonlNames.size + uuidDirs.length, latestMtime };
|
|
3218
3314
|
} catch {
|
|
3219
3315
|
return { count: 0, latestMtime: 0 };
|
|
@@ -3401,7 +3497,7 @@ var AuthManager = class extends import_events2.EventEmitter {
|
|
|
3401
3497
|
var import_promises5 = require("fs/promises");
|
|
3402
3498
|
|
|
3403
3499
|
// src/terminal/TerminalExecutor.ts
|
|
3404
|
-
var
|
|
3500
|
+
var import_node_child_process5 = require("child_process");
|
|
3405
3501
|
var import_uuid4 = require("uuid");
|
|
3406
3502
|
var EXEC_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
3407
3503
|
var TerminalExecutor = class {
|
|
@@ -3427,7 +3523,7 @@ var TerminalExecutor = class {
|
|
|
3427
3523
|
const execId = (0, import_uuid4.v4)();
|
|
3428
3524
|
const shell = isWindows ? "powershell" : "bash";
|
|
3429
3525
|
const args = isWindows ? ["-Command", command] : ["-c", command];
|
|
3430
|
-
const proc = (0,
|
|
3526
|
+
const proc = (0, import_node_child_process5.spawn)(shell, args, {
|
|
3431
3527
|
cwd,
|
|
3432
3528
|
stdio: ["ignore", "pipe", "pipe"],
|
|
3433
3529
|
env: { ...process.env }
|
|
@@ -3490,7 +3586,7 @@ var TerminalExecutor = class {
|
|
|
3490
3586
|
// src/server.ts
|
|
3491
3587
|
var WS_PORT = 3745;
|
|
3492
3588
|
var HTTP_PORT = 3746;
|
|
3493
|
-
var execAsync = (0, import_node_util.promisify)(
|
|
3589
|
+
var execAsync = (0, import_node_util.promisify)(import_node_child_process6.exec);
|
|
3494
3590
|
async function killPortProcess(port) {
|
|
3495
3591
|
try {
|
|
3496
3592
|
if (isWindows) {
|
|
@@ -3847,9 +3943,9 @@ async function start(opts = {}) {
|
|
|
3847
3943
|
}
|
|
3848
3944
|
case "terminal_exec": {
|
|
3849
3945
|
const activeSession = sessionManager.getActiveSessions().find((s) => s.id === event.sessionId);
|
|
3850
|
-
const cwd = activeSession?.projectPath ?? sessionManager.getSessionProjectPath(event.sessionId);
|
|
3946
|
+
const cwd = activeSession?.projectPath ?? sessionManager.getSessionProjectPath(event.sessionId) ?? event.projectPath;
|
|
3851
3947
|
if (!cwd) {
|
|
3852
|
-
wsBridge.send(ws, { type: "error", code: "TERMINAL_EXEC_ERROR", message:
|
|
3948
|
+
wsBridge.send(ws, { type: "error", code: "TERMINAL_EXEC_ERROR", message: `Session not found (id: ${event.sessionId.slice(0, 8)}\u2026)`, sessionId: event.sessionId });
|
|
3853
3949
|
break;
|
|
3854
3950
|
}
|
|
3855
3951
|
terminalExecutor.exec(event.sessionId, event.command, cwd);
|