contextswitch 0.1.5 → 0.1.7
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/archive-HW56NYMR.js +10 -0
- package/dist/{chunk-YMFZWGZO.js → chunk-72MK25T3.js} +71 -32
- package/dist/{chunk-A7YXSI66.js → chunk-F36TGFK2.js} +21 -2
- package/dist/{chunk-756VUR5T.js → chunk-GBKMEML7.js} +205 -81
- package/dist/{chunk-GHF4FLJV.js → chunk-GDWJEQJQ.js} +6 -7
- package/dist/{chunk-KBKALWDX.js → chunk-MGIXKKM6.js} +3 -0
- package/dist/cli.js +117 -34
- package/dist/{process-E35QFSO6.js → process-7O6IL3T4.js} +2 -2
- package/dist/{reset-GZKUYPZR.js → reset-O67AMVTV.js} +8 -4
- package/dist/{session-IWXAKW6Z.js → session-H5HPE5OT.js} +1 -1
- package/dist/{switch-RZCXBTPC.js → switch-RRK6CHOB.js} +91 -81
- package/package.json +3 -3
- package/dist/archive-64CFJ3P5.js +0 -10
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
+
debug,
|
|
2
3
|
paths
|
|
3
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-F36TGFK2.js";
|
|
4
5
|
|
|
5
6
|
// src/core/process.ts
|
|
6
|
-
import { execSync, spawn } from "child_process";
|
|
7
|
+
import { execFileSync, execSync, spawn } from "child_process";
|
|
7
8
|
import { platform } from "os";
|
|
8
9
|
import { existsSync, readFileSync, writeFileSync, unlinkSync } from "fs";
|
|
9
10
|
import { join } from "path";
|
|
@@ -47,9 +48,11 @@ var ProcessManager = class {
|
|
|
47
48
|
const basename = command.split("/").pop() || "";
|
|
48
49
|
const isClaudeBinary = basename === "claude" || basename === "claude.exe";
|
|
49
50
|
if (isClaudeBinary) {
|
|
51
|
+
debug("process", `Found Claude process: PID=${pid} cmd=${command} args=${args.join(" ")}`);
|
|
50
52
|
processes.push({ pid, command, args });
|
|
51
53
|
}
|
|
52
54
|
}
|
|
55
|
+
debug("process", `Unix process scan found ${processes.length} Claude process(es)`);
|
|
53
56
|
return processes;
|
|
54
57
|
} catch (error) {
|
|
55
58
|
console.error(`Unix process detection failed: ${error}`);
|
|
@@ -73,11 +76,17 @@ var ProcessManager = class {
|
|
|
73
76
|
const match = line.match(/^"?(\d+)"?,"?(.*?)"?$/);
|
|
74
77
|
if (match) {
|
|
75
78
|
const pid = parseInt(match[1], 10);
|
|
79
|
+
if (!Number.isInteger(pid) || pid <= 0) continue;
|
|
76
80
|
const commandLine = match[2] || "";
|
|
77
|
-
if (commandLine.includes("
|
|
81
|
+
if (commandLine.includes("cs switch")) continue;
|
|
82
|
+
const exe = commandLine.split(/[\s"]+/)[0] || "";
|
|
83
|
+
const bin = exe.split(/[/\\]/).pop() || "";
|
|
84
|
+
const isClaudeBinary = bin === "claude" || bin === "claude.exe";
|
|
85
|
+
if (isClaudeBinary) {
|
|
86
|
+
debug("process", `Found Claude process: PID=${pid} cmd=${commandLine}`);
|
|
78
87
|
processes.push({
|
|
79
88
|
pid,
|
|
80
|
-
command:
|
|
89
|
+
command: exe,
|
|
81
90
|
args: commandLine.split(" ").slice(1)
|
|
82
91
|
});
|
|
83
92
|
}
|
|
@@ -93,6 +102,10 @@ var ProcessManager = class {
|
|
|
93
102
|
* Kill a process by PID
|
|
94
103
|
*/
|
|
95
104
|
killProcess(pid, force = false) {
|
|
105
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
106
|
+
debug("process", `Invalid PID: ${pid}`);
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
96
109
|
try {
|
|
97
110
|
if (this.platform === "win32") {
|
|
98
111
|
const flag = force ? "/F" : "";
|
|
@@ -114,124 +127,119 @@ var ProcessManager = class {
|
|
|
114
127
|
if (processes.length === 0) {
|
|
115
128
|
return;
|
|
116
129
|
}
|
|
130
|
+
debug("process", `Found ${processes.length} Claude process(es) to terminate`);
|
|
117
131
|
console.log(`Found ${processes.length} Claude process(es) to terminate`);
|
|
118
132
|
for (const proc of processes) {
|
|
133
|
+
debug("process", `Sending SIGTERM to PID ${proc.pid}`);
|
|
119
134
|
this.killProcess(proc.pid, false);
|
|
120
135
|
}
|
|
121
136
|
await new Promise((resolve) => setTimeout(resolve, Math.min(timeout, 1e3)));
|
|
122
137
|
const remaining = this.findClaudeProcesses();
|
|
123
138
|
for (const proc of remaining) {
|
|
139
|
+
debug("process", `Force killing PID ${proc.pid} (still alive after grace period)`);
|
|
124
140
|
console.log(`Force killing process ${proc.pid}`);
|
|
125
141
|
this.killProcess(proc.pid, true);
|
|
126
142
|
}
|
|
127
143
|
}
|
|
128
144
|
/**
|
|
129
|
-
* Spawn
|
|
145
|
+
* Spawn a shell script in a terminal.
|
|
146
|
+
* @param mode - 'window' (new window), 'tab' (new tab), or 'inline' (current terminal)
|
|
130
147
|
*/
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
148
|
+
spawnTerminalScript(script, _cwd, mode = "window") {
|
|
149
|
+
const scriptFile = join(paths.baseDir, `launch-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.sh`);
|
|
150
|
+
debug("process", `Writing launch script to ${scriptFile} (mode: ${mode})`);
|
|
151
|
+
debug("process", `Script contents:
|
|
152
|
+
${script}`);
|
|
153
|
+
writeFileSync(scriptFile, script, { mode: 493 });
|
|
154
|
+
if (mode === "inline") {
|
|
155
|
+
debug("process", "Running inline \u2014 taking over current terminal");
|
|
156
|
+
try {
|
|
157
|
+
execFileSync("bash", [scriptFile], { stdio: "inherit" });
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
return 0;
|
|
135
161
|
}
|
|
136
162
|
if (this.platform === "darwin") {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
163
|
+
const escapedPath = scriptFile.replace(/"/g, '\\"');
|
|
164
|
+
let appleScript;
|
|
165
|
+
if (mode === "tab") {
|
|
166
|
+
appleScript = [
|
|
167
|
+
'tell application "Terminal"',
|
|
168
|
+
" activate",
|
|
169
|
+
` tell application "System Events" to keystroke "t" using command down`,
|
|
170
|
+
` do script "bash \\"${escapedPath}\\"" in front window`,
|
|
171
|
+
"end tell"
|
|
172
|
+
].join("\n");
|
|
173
|
+
} else {
|
|
174
|
+
appleScript = `tell app "Terminal" to do script "bash \\"${escapedPath}\\""`;
|
|
175
|
+
}
|
|
176
|
+
const proc2 = spawn("osascript", ["-e", appleScript], {
|
|
141
177
|
detached: true,
|
|
142
178
|
stdio: "ignore"
|
|
143
179
|
});
|
|
144
|
-
|
|
145
|
-
return
|
|
180
|
+
proc2.unref();
|
|
181
|
+
return proc2.pid || 0;
|
|
146
182
|
}
|
|
147
183
|
if (this.platform === "linux") {
|
|
148
|
-
const
|
|
149
|
-
const claudeCommand = `${claudeCmd} ${args.join(" ")}`;
|
|
184
|
+
const tabFlag = mode === "tab";
|
|
150
185
|
const terminals = ["gnome-terminal", "xterm", "konsole", "xfce4-terminal"];
|
|
151
186
|
for (const term of terminals) {
|
|
152
187
|
try {
|
|
153
|
-
const
|
|
188
|
+
const args = term === "gnome-terminal" && tabFlag ? ["--tab", "--", "bash", scriptFile] : ["--", "bash", scriptFile];
|
|
189
|
+
const proc2 = spawn(term, args, {
|
|
154
190
|
detached: true,
|
|
155
191
|
stdio: "ignore"
|
|
156
192
|
});
|
|
157
|
-
|
|
158
|
-
return
|
|
193
|
+
proc2.unref();
|
|
194
|
+
return proc2.pid || 0;
|
|
159
195
|
} catch {
|
|
160
196
|
}
|
|
161
197
|
}
|
|
162
198
|
}
|
|
163
199
|
if (this.platform === "win32") {
|
|
164
|
-
const
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
200
|
+
const psScriptFile = scriptFile.replace(/\.sh$/, ".ps1");
|
|
201
|
+
const psScript = this.convertToPowerShell(script);
|
|
202
|
+
writeFileSync(psScriptFile, psScript, { mode: 493 });
|
|
203
|
+
debug("process", `PowerShell script:
|
|
204
|
+
${psScript}`);
|
|
205
|
+
const useTab = mode === "tab";
|
|
206
|
+
try {
|
|
207
|
+
const wtArgs = useTab ? ["-w", "0", "nt", "powershell", "-ExecutionPolicy", "Bypass", "-File", psScriptFile] : ["powershell", "-ExecutionPolicy", "Bypass", "-File", psScriptFile];
|
|
208
|
+
const proc2 = spawn("wt.exe", wtArgs, {
|
|
169
209
|
detached: true,
|
|
170
210
|
stdio: "ignore",
|
|
171
211
|
windowsHide: false
|
|
172
212
|
});
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
213
|
+
proc2.unref();
|
|
214
|
+
debug("process", "Launched via Windows Terminal (wt.exe)");
|
|
215
|
+
return proc2.pid || 0;
|
|
216
|
+
} catch {
|
|
217
|
+
debug("process", "Windows Terminal not available, falling back");
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const proc2 = spawn("cmd.exe", ["/c", "start", "powershell", "-ExecutionPolicy", "Bypass", "-File", psScriptFile], {
|
|
178
221
|
detached: true,
|
|
179
222
|
stdio: "ignore",
|
|
180
223
|
windowsHide: false
|
|
181
224
|
});
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
detached: true,
|
|
188
|
-
stdio: "ignore",
|
|
189
|
-
...options
|
|
190
|
-
});
|
|
191
|
-
claudeProcess.unref();
|
|
192
|
-
return claudeProcess.pid || 0;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Spawn a shell script in a new terminal window
|
|
196
|
-
*/
|
|
197
|
-
spawnTerminalScript(script, _cwd) {
|
|
198
|
-
const scriptFile = join(paths.baseDir, "launch.sh");
|
|
199
|
-
writeFileSync(scriptFile, script, { mode: 493 });
|
|
200
|
-
if (this.platform === "darwin") {
|
|
201
|
-
const escapedPath = scriptFile.replace(/"/g, '\\"');
|
|
202
|
-
const appleScript = `tell app "Terminal" to do script "bash \\"${escapedPath}\\""`;
|
|
203
|
-
const proc2 = spawn("osascript", ["-e", appleScript], {
|
|
204
|
-
detached: true,
|
|
205
|
-
stdio: "ignore"
|
|
206
|
-
});
|
|
207
|
-
proc2.unref();
|
|
208
|
-
return proc2.pid || 0;
|
|
209
|
-
}
|
|
210
|
-
if (this.platform === "linux") {
|
|
211
|
-
const terminals = ["gnome-terminal", "xterm", "konsole", "xfce4-terminal"];
|
|
212
|
-
for (const term of terminals) {
|
|
213
|
-
try {
|
|
214
|
-
const proc2 = spawn(term, ["--", "bash", scriptFile], {
|
|
215
|
-
detached: true,
|
|
216
|
-
stdio: "ignore"
|
|
217
|
-
});
|
|
218
|
-
proc2.unref();
|
|
219
|
-
return proc2.pid || 0;
|
|
220
|
-
} catch {
|
|
221
|
-
}
|
|
225
|
+
proc2.unref();
|
|
226
|
+
debug("process", "Launched via PowerShell (cmd start)");
|
|
227
|
+
return proc2.pid || 0;
|
|
228
|
+
} catch {
|
|
229
|
+
debug("process", "PowerShell launch failed, trying Git Bash");
|
|
222
230
|
}
|
|
223
|
-
}
|
|
224
|
-
if (this.platform === "win32") {
|
|
225
231
|
const gitBash = this.findGitBash();
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
if (gitBash) {
|
|
233
|
+
const scriptPath = scriptFile.replace(/\\/g, "/");
|
|
234
|
+
const proc2 = spawn("cmd.exe", ["/c", "start", "", gitBash, scriptPath], {
|
|
235
|
+
detached: true,
|
|
236
|
+
stdio: "ignore",
|
|
237
|
+
windowsHide: false
|
|
238
|
+
});
|
|
239
|
+
proc2.unref();
|
|
240
|
+
debug("process", "Launched via Git Bash");
|
|
241
|
+
return proc2.pid || 0;
|
|
242
|
+
}
|
|
235
243
|
}
|
|
236
244
|
const proc = spawn("bash", [scriptFile], {
|
|
237
245
|
detached: true,
|
|
@@ -249,6 +257,114 @@ var ProcessManager = class {
|
|
|
249
257
|
/**
|
|
250
258
|
* Find Git Bash executable on Windows
|
|
251
259
|
*/
|
|
260
|
+
/**
|
|
261
|
+
* Convert a simple bash launch script to PowerShell.
|
|
262
|
+
* Handles: cd, export, exec, echo, if/fi, and comments.
|
|
263
|
+
*/
|
|
264
|
+
convertToPowerShell(bashScript) {
|
|
265
|
+
const lines = bashScript.split("\n");
|
|
266
|
+
const psLines = [];
|
|
267
|
+
for (const line of lines) {
|
|
268
|
+
const trimmed = line.trim();
|
|
269
|
+
if (trimmed.startsWith("#!/")) continue;
|
|
270
|
+
if (trimmed.startsWith("#")) {
|
|
271
|
+
psLines.push(trimmed);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (trimmed === "") {
|
|
275
|
+
psLines.push("");
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
const cdMatch = trimmed.match(/^cd\s+(.+)$/);
|
|
279
|
+
if (cdMatch) {
|
|
280
|
+
const dir = cdMatch[1].replace(/^'|'$/g, "").replace(/'\\''/g, "'");
|
|
281
|
+
psLines.push(`Set-Location "${dir}"`);
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
const exportMatch = trimmed.match(/^export\s+([A-Za-z_][A-Za-z0-9_]*)="(.*)"$/);
|
|
285
|
+
if (exportMatch) {
|
|
286
|
+
psLines.push(`$env:${exportMatch[1]} = "${exportMatch[2]}"`);
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (trimmed.startsWith("exec ")) {
|
|
290
|
+
const cmd = trimmed.slice(5);
|
|
291
|
+
const parts = this.parseBashCommand(cmd);
|
|
292
|
+
psLines.push(`& ${parts.map((p) => `"${p}"`).join(" ")}`);
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (trimmed.startsWith("echo ")) {
|
|
296
|
+
const msg = trimmed.slice(5).replace(/^"|"$/g, "").replace(/^'|'$/g, "");
|
|
297
|
+
psLines.push(`Write-Host "${msg}"`);
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (trimmed.match(/^if\s+\[.*\];\s*then$/)) {
|
|
301
|
+
psLines.push("if ($LASTEXITCODE -ne 0) {");
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
if (trimmed === "fi") {
|
|
305
|
+
psLines.push("}");
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
if (trimmed === "RESUME_EXIT=$?") {
|
|
309
|
+
psLines.push("# Exit code captured automatically as $LASTEXITCODE");
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
const cmdLine = trimmed;
|
|
313
|
+
if (cmdLine.match(/^'?[A-Za-z\/\\:]/)) {
|
|
314
|
+
const parts = this.parseBashCommand(cmdLine);
|
|
315
|
+
psLines.push(`& ${parts.map((p) => `"${p}"`).join(" ")}`);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
psLines.push(`# ${trimmed}`);
|
|
319
|
+
}
|
|
320
|
+
return psLines.join("\r\n");
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Parse a bash command with shell-escaped single-quoted arguments into parts.
|
|
324
|
+
*/
|
|
325
|
+
parseBashCommand(cmd) {
|
|
326
|
+
const parts = [];
|
|
327
|
+
let current = "";
|
|
328
|
+
let inSingleQuote = false;
|
|
329
|
+
let i = 0;
|
|
330
|
+
while (i < cmd.length) {
|
|
331
|
+
const ch = cmd[i];
|
|
332
|
+
if (inSingleQuote) {
|
|
333
|
+
if (ch === "'") {
|
|
334
|
+
if (cmd.slice(i, i + 4) === "'\\''") {
|
|
335
|
+
current += "'";
|
|
336
|
+
i += 4;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
inSingleQuote = false;
|
|
340
|
+
i++;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
current += ch;
|
|
344
|
+
i++;
|
|
345
|
+
} else {
|
|
346
|
+
if (ch === "'") {
|
|
347
|
+
inSingleQuote = true;
|
|
348
|
+
i++;
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (ch === " " || ch === " ") {
|
|
352
|
+
if (current.length > 0) {
|
|
353
|
+
parts.push(current);
|
|
354
|
+
current = "";
|
|
355
|
+
}
|
|
356
|
+
i++;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
current += ch;
|
|
360
|
+
i++;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (current.length > 0) {
|
|
364
|
+
parts.push(current);
|
|
365
|
+
}
|
|
366
|
+
return parts;
|
|
367
|
+
}
|
|
252
368
|
findGitBash() {
|
|
253
369
|
if (this.platform !== "win32") return null;
|
|
254
370
|
const candidates = [
|
|
@@ -280,12 +396,15 @@ var ProcessManager = class {
|
|
|
280
396
|
if (this.platform === "win32") {
|
|
281
397
|
const output = execSync("where claude", { encoding: "utf-8" }).trim();
|
|
282
398
|
const firstLine = output.split("\n")[0];
|
|
399
|
+
debug("process", `Found Claude via 'where': ${firstLine}`);
|
|
283
400
|
return firstLine || null;
|
|
284
401
|
} else {
|
|
285
402
|
const output = execSync("which claude", { encoding: "utf-8" }).trim();
|
|
403
|
+
debug("process", `Found Claude via 'which': ${output}`);
|
|
286
404
|
return output || null;
|
|
287
405
|
}
|
|
288
406
|
} catch {
|
|
407
|
+
debug("process", "Claude not found via PATH, checking common install locations");
|
|
289
408
|
const commonPaths = this.platform === "win32" ? [
|
|
290
409
|
join(process.env.LOCALAPPDATA || "", "Programs", "Claude Code", "claude.exe"),
|
|
291
410
|
join(process.env.PROGRAMFILES || "C:\\Program Files", "Claude Code", "claude.exe"),
|
|
@@ -299,9 +418,11 @@ var ProcessManager = class {
|
|
|
299
418
|
];
|
|
300
419
|
for (const candidatePath of commonPaths) {
|
|
301
420
|
if (candidatePath && existsSync(candidatePath)) {
|
|
421
|
+
debug("process", `Found Claude at fallback path: ${candidatePath}`);
|
|
302
422
|
return candidatePath;
|
|
303
423
|
}
|
|
304
424
|
}
|
|
425
|
+
debug("process", "Claude executable not found anywhere");
|
|
305
426
|
return null;
|
|
306
427
|
}
|
|
307
428
|
}
|
|
@@ -340,6 +461,9 @@ var ProcessManager = class {
|
|
|
340
461
|
* Check if a process is still running
|
|
341
462
|
*/
|
|
342
463
|
isProcessRunning(pid) {
|
|
464
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
343
467
|
try {
|
|
344
468
|
if (this.platform === "win32") {
|
|
345
469
|
const output = execSync(`tasklist /FI "PID eq ${pid}"`, { encoding: "utf-8" });
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
configManager
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-72MK25T3.js";
|
|
4
4
|
import {
|
|
5
5
|
paths
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-F36TGFK2.js";
|
|
7
7
|
|
|
8
8
|
// src/commands/archive.ts
|
|
9
9
|
import picocolors from "picocolors";
|
|
@@ -26,18 +26,18 @@ async function archiveCommand(domainName) {
|
|
|
26
26
|
if (!existsSync(archiveDir)) {
|
|
27
27
|
mkdirSync(archiveDir, { recursive: true });
|
|
28
28
|
}
|
|
29
|
+
const domain = configManager.loadDomain(domainName);
|
|
29
30
|
const timestamp = /* @__PURE__ */ new Date();
|
|
30
31
|
const archiveMetadata = {
|
|
31
32
|
domain: domainName,
|
|
32
33
|
session,
|
|
33
34
|
timestamp: timestamp.toISOString(),
|
|
34
|
-
config:
|
|
35
|
+
config: domain
|
|
35
36
|
};
|
|
36
37
|
const dateStr = timestamp.toISOString().replace(/[:.]/g, "-").replace("T", "_").slice(0, -5);
|
|
37
38
|
const archiveName = `${dateStr}.json`;
|
|
38
39
|
const archivePath = join(archiveDir, archiveName);
|
|
39
40
|
writeFileSync(archivePath, JSON.stringify(archiveMetadata, null, 2), "utf-8");
|
|
40
|
-
const domain = configManager.loadDomain(domainName);
|
|
41
41
|
if (domain.claudeConfig?.memory) {
|
|
42
42
|
const memoryArchiveDir = join(archiveDir, dateStr, "memory");
|
|
43
43
|
mkdirSync(memoryArchiveDir, { recursive: true });
|
|
@@ -56,11 +56,10 @@ async function archiveCommand(domainName) {
|
|
|
56
56
|
console.log(pc.green(`\u2705 Session archived successfully`));
|
|
57
57
|
console.log(pc.gray(`Archive: ${archivePath}`));
|
|
58
58
|
console.log(pc.gray(`Size: ${sizeKB} KB`));
|
|
59
|
-
const { SessionManager } = await import("./session-
|
|
59
|
+
const { SessionManager } = await import("./session-H5HPE5OT.js");
|
|
60
60
|
console.log(pc.gray(`Session age: ${SessionManager.getSessionAge(session.started)}`));
|
|
61
61
|
} catch (error) {
|
|
62
|
-
|
|
63
|
-
process.exit(1);
|
|
62
|
+
throw new Error(`Failed to archive session: ${error}`);
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
65
|
function listArchives(domainName) {
|
|
@@ -59,6 +59,9 @@ var SessionManager = class {
|
|
|
59
59
|
return `${hours} hour${hours === 1 ? "" : "s"}`;
|
|
60
60
|
}
|
|
61
61
|
const minutes = Math.floor(diffMs / (1e3 * 60));
|
|
62
|
+
if (minutes === 0) {
|
|
63
|
+
return "just now";
|
|
64
|
+
}
|
|
62
65
|
return `${minutes} minute${minutes === 1 ? "" : "s"}`;
|
|
63
66
|
}
|
|
64
67
|
/**
|