@staff0rd/assist 0.287.0 → 0.288.0
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 +138 -41
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.288.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -18570,6 +18570,33 @@ function shutdownSessions(sessions) {
|
|
|
18570
18570
|
}
|
|
18571
18571
|
}
|
|
18572
18572
|
|
|
18573
|
+
// src/commands/sessions/daemon/autoHealWindowsDaemon.ts
|
|
18574
|
+
async function autoHealWindowsDaemon(conn, state, heal, version2) {
|
|
18575
|
+
daemonLog(`windows proxy: auto-healing windows daemon (mismatch ${version2})`);
|
|
18576
|
+
notifyHealing(state);
|
|
18577
|
+
try {
|
|
18578
|
+
conn.dispose();
|
|
18579
|
+
await heal();
|
|
18580
|
+
daemonLog("windows proxy: heal complete, reconnecting to windows daemon");
|
|
18581
|
+
await conn.ensure();
|
|
18582
|
+
} catch (e) {
|
|
18583
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
18584
|
+
daemonLog(`windows proxy: auto-heal failed: ${message}`);
|
|
18585
|
+
state.broadcast({
|
|
18586
|
+
type: "error",
|
|
18587
|
+
message: `Windows host auto-update failed: ${message}`
|
|
18588
|
+
});
|
|
18589
|
+
}
|
|
18590
|
+
}
|
|
18591
|
+
function notifyHealing(state) {
|
|
18592
|
+
for (const client of state.pendingCreators)
|
|
18593
|
+
sendTo(client, {
|
|
18594
|
+
type: "error",
|
|
18595
|
+
message: "Windows host is out of date; updating it now \u2014 reselect the repo once the update finishes."
|
|
18596
|
+
});
|
|
18597
|
+
state.pendingCreators = [];
|
|
18598
|
+
}
|
|
18599
|
+
|
|
18573
18600
|
// src/commands/sessions/daemon/connectToWindowsDaemon.ts
|
|
18574
18601
|
import * as net2 from "net";
|
|
18575
18602
|
|
|
@@ -18600,18 +18627,6 @@ async function isWindowsDaemonRunning() {
|
|
|
18600
18627
|
}
|
|
18601
18628
|
}
|
|
18602
18629
|
|
|
18603
|
-
// src/commands/sessions/daemon/discoverWindowsSessions.ts
|
|
18604
|
-
async function discoverWindowsSessions(conn) {
|
|
18605
|
-
if (conn.connected || !await isWindowsDaemonRunning()) return;
|
|
18606
|
-
daemonLog("windows proxy: discovering sessions on running windows daemon");
|
|
18607
|
-
try {
|
|
18608
|
-
await conn.ensure();
|
|
18609
|
-
} catch (e) {
|
|
18610
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
18611
|
-
daemonLog(`windows proxy: discovery failed: ${message}`);
|
|
18612
|
-
}
|
|
18613
|
-
}
|
|
18614
|
-
|
|
18615
18630
|
// src/commands/sessions/daemon/ensureWindowsDaemonRunning.ts
|
|
18616
18631
|
import { spawn as spawn10 } from "child_process";
|
|
18617
18632
|
var SPAWN_TIMEOUT_MS2 = 3e4;
|
|
@@ -18661,6 +18676,24 @@ function delay2(ms) {
|
|
|
18661
18676
|
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
18662
18677
|
}
|
|
18663
18678
|
|
|
18679
|
+
// src/commands/sessions/daemon/defaultConnect.ts
|
|
18680
|
+
async function defaultConnect() {
|
|
18681
|
+
await ensureWindowsDaemonRunning();
|
|
18682
|
+
return connectToWindowsDaemon();
|
|
18683
|
+
}
|
|
18684
|
+
|
|
18685
|
+
// src/commands/sessions/daemon/discoverWindowsSessions.ts
|
|
18686
|
+
async function discoverWindowsSessions(conn) {
|
|
18687
|
+
if (conn.connected || !await isWindowsDaemonRunning()) return;
|
|
18688
|
+
daemonLog("windows proxy: discovering sessions on running windows daemon");
|
|
18689
|
+
try {
|
|
18690
|
+
await conn.ensure();
|
|
18691
|
+
} catch (e) {
|
|
18692
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
18693
|
+
daemonLog(`windows proxy: discovery failed: ${message}`);
|
|
18694
|
+
}
|
|
18695
|
+
}
|
|
18696
|
+
|
|
18664
18697
|
// src/commands/sessions/daemon/forwardWindowsCreate.ts
|
|
18665
18698
|
async function forwardWindowsCreate(conn, state, client, data) {
|
|
18666
18699
|
daemonLog(`windows proxy: routing ${data.type} (cwd=${data.cwd})`);
|
|
@@ -18693,13 +18726,14 @@ function versionsMatch(a, b) {
|
|
|
18693
18726
|
|
|
18694
18727
|
// src/commands/sessions/daemon/WindowsProxyState.ts
|
|
18695
18728
|
var MAX_SCROLLBACK2 = 256 * 1024;
|
|
18696
|
-
function createState(broadcast2, onSessionsChanged) {
|
|
18729
|
+
function createState(broadcast2, onSessionsChanged, onVersionMismatch) {
|
|
18697
18730
|
return {
|
|
18698
18731
|
windowsSessions: [],
|
|
18699
18732
|
scrollback: /* @__PURE__ */ new Map(),
|
|
18700
18733
|
pendingCreators: [],
|
|
18701
18734
|
broadcast: broadcast2,
|
|
18702
|
-
onSessionsChanged
|
|
18735
|
+
onSessionsChanged,
|
|
18736
|
+
onVersionMismatch
|
|
18703
18737
|
};
|
|
18704
18738
|
}
|
|
18705
18739
|
function resetState(state) {
|
|
@@ -18730,7 +18764,7 @@ function handleInbound(state, line) {
|
|
|
18730
18764
|
inbound[msg.type]?.(state, msg);
|
|
18731
18765
|
}
|
|
18732
18766
|
var inbound = {
|
|
18733
|
-
hello:
|
|
18767
|
+
hello: handleHello,
|
|
18734
18768
|
created: handleCreated,
|
|
18735
18769
|
sessions: handleSessions,
|
|
18736
18770
|
output: handleOutput,
|
|
@@ -18740,11 +18774,13 @@ var inbound = {
|
|
|
18740
18774
|
state.broadcast(msg);
|
|
18741
18775
|
}
|
|
18742
18776
|
};
|
|
18743
|
-
function handleHello(msg) {
|
|
18744
|
-
if (isHello(msg) && !versionsMatch(msg.version, ASSIST_VERSION))
|
|
18777
|
+
function handleHello(state, msg) {
|
|
18778
|
+
if (isHello(msg) && !versionsMatch(msg.version, ASSIST_VERSION)) {
|
|
18745
18779
|
daemonLog(
|
|
18746
18780
|
`windows daemon version mismatch: ${msg.version} (wsl ${ASSIST_VERSION})`
|
|
18747
18781
|
);
|
|
18782
|
+
state.onVersionMismatch(msg.version);
|
|
18783
|
+
}
|
|
18748
18784
|
}
|
|
18749
18785
|
function handleCreated(state, msg) {
|
|
18750
18786
|
daemonLog(`windows daemon: created session ${nsId(msg)}`);
|
|
@@ -18775,6 +18811,57 @@ function nsId(msg) {
|
|
|
18775
18811
|
return toWindowsSessionId(msg.sessionId);
|
|
18776
18812
|
}
|
|
18777
18813
|
|
|
18814
|
+
// src/commands/sessions/daemon/healWindowsDaemon.ts
|
|
18815
|
+
import { spawn as spawn11 } from "child_process";
|
|
18816
|
+
import { createInterface as createInterface5 } from "readline";
|
|
18817
|
+
var UPDATE_TIMEOUT_MS = 5 * 6e4;
|
|
18818
|
+
var STOP_TIMEOUT_MS2 = 3e4;
|
|
18819
|
+
async function healWindowsDaemon() {
|
|
18820
|
+
daemonLog("windows daemon: auto-heal: running `assist update` on host");
|
|
18821
|
+
await runOnWindowsHost("assist update", UPDATE_TIMEOUT_MS);
|
|
18822
|
+
daemonLog("windows daemon: auto-heal: update done, stopping stale daemon");
|
|
18823
|
+
await runOnWindowsHost("assist daemon stop", STOP_TIMEOUT_MS2);
|
|
18824
|
+
daemonLog("windows daemon: auto-heal: stale daemon stopped");
|
|
18825
|
+
}
|
|
18826
|
+
function runOnWindowsHost(command, timeoutMs) {
|
|
18827
|
+
return new Promise((resolve16, reject) => {
|
|
18828
|
+
const child = spawn11("pwsh.exe", ["-Command", command], {
|
|
18829
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
18830
|
+
});
|
|
18831
|
+
logStream(child.stdout, command);
|
|
18832
|
+
logStream(child.stderr, command);
|
|
18833
|
+
const timer = setTimeout(() => {
|
|
18834
|
+
child.kill();
|
|
18835
|
+
reject(
|
|
18836
|
+
new Error(
|
|
18837
|
+
`'${command}' on the Windows host timed out after ${timeoutMs}ms`
|
|
18838
|
+
)
|
|
18839
|
+
);
|
|
18840
|
+
}, timeoutMs);
|
|
18841
|
+
child.on("error", (e) => {
|
|
18842
|
+
clearTimeout(timer);
|
|
18843
|
+
reject(e);
|
|
18844
|
+
});
|
|
18845
|
+
child.on("exit", (code) => {
|
|
18846
|
+
clearTimeout(timer);
|
|
18847
|
+
if (code === 0) resolve16();
|
|
18848
|
+
else
|
|
18849
|
+
reject(
|
|
18850
|
+
new Error(
|
|
18851
|
+
`'${command}' on the Windows host exited with code ${code}`
|
|
18852
|
+
)
|
|
18853
|
+
);
|
|
18854
|
+
});
|
|
18855
|
+
});
|
|
18856
|
+
}
|
|
18857
|
+
function logStream(stream, command) {
|
|
18858
|
+
if (!stream) return;
|
|
18859
|
+
const lines = createInterface5({ input: stream });
|
|
18860
|
+
lines.on("line", (line) => daemonLog(`[windows ${command}] ${line}`));
|
|
18861
|
+
lines.on("error", () => {
|
|
18862
|
+
});
|
|
18863
|
+
}
|
|
18864
|
+
|
|
18778
18865
|
// src/commands/sessions/daemon/isWindowsCwd.ts
|
|
18779
18866
|
function isWindowsCwd(cwd) {
|
|
18780
18867
|
return /^[A-Za-z]:[\\/]/.test(cwd);
|
|
@@ -18783,8 +18870,16 @@ function shouldProxyToWindows(cwd) {
|
|
|
18783
18870
|
return detectPlatform() === "wsl" && isWindowsCwd(cwd);
|
|
18784
18871
|
}
|
|
18785
18872
|
|
|
18873
|
+
// src/commands/sessions/daemon/isWindowsCreate.ts
|
|
18874
|
+
function isWindowsCreate(data) {
|
|
18875
|
+
return typeof data.cwd === "string" && shouldProxyToWindows(data.cwd);
|
|
18876
|
+
}
|
|
18877
|
+
function isWindowsIo(data) {
|
|
18878
|
+
return typeof data.sessionId === "string" && isWindowsSessionId(data.sessionId);
|
|
18879
|
+
}
|
|
18880
|
+
|
|
18786
18881
|
// src/commands/sessions/daemon/WindowsConnection.ts
|
|
18787
|
-
import { createInterface as
|
|
18882
|
+
import { createInterface as createInterface6 } from "readline";
|
|
18788
18883
|
var WindowsConnection = class {
|
|
18789
18884
|
constructor(deps2) {
|
|
18790
18885
|
this.deps = deps2;
|
|
@@ -18821,7 +18916,7 @@ var WindowsConnection = class {
|
|
|
18821
18916
|
const socket = await this.deps.connect();
|
|
18822
18917
|
daemonLog("windows connection: tcp connected, sending hello");
|
|
18823
18918
|
this.socket = socket;
|
|
18824
|
-
const lines =
|
|
18919
|
+
const lines = createInterface6({ input: socket });
|
|
18825
18920
|
lines.on("error", () => {
|
|
18826
18921
|
});
|
|
18827
18922
|
lines.on("line", (line) => this.deps.onLine(line));
|
|
@@ -18842,12 +18937,12 @@ var WindowsConnection = class {
|
|
|
18842
18937
|
|
|
18843
18938
|
// src/commands/sessions/daemon/WindowsProxy.ts
|
|
18844
18939
|
var WindowsProxy = class {
|
|
18845
|
-
|
|
18846
|
-
|
|
18847
|
-
constructor(clients, onSessionsChanged, connect3 = defaultConnect) {
|
|
18940
|
+
constructor(clients, onSessionsChanged, connect3 = defaultConnect, heal = healWindowsDaemon) {
|
|
18941
|
+
this.heal = heal;
|
|
18848
18942
|
this.state = createState(
|
|
18849
18943
|
(msg) => broadcast(clients, msg),
|
|
18850
|
-
onSessionsChanged
|
|
18944
|
+
onSessionsChanged,
|
|
18945
|
+
(version2) => void this.handleVersionMismatch(version2)
|
|
18851
18946
|
);
|
|
18852
18947
|
this.conn = new WindowsConnection({
|
|
18853
18948
|
connect: connect3,
|
|
@@ -18855,6 +18950,11 @@ var WindowsProxy = class {
|
|
|
18855
18950
|
onClose: () => this.handleClose()
|
|
18856
18951
|
});
|
|
18857
18952
|
}
|
|
18953
|
+
state;
|
|
18954
|
+
conn;
|
|
18955
|
+
// why: heal runs once per proxy lifetime; if WSL is the older side, updating Windows can't close the gap, so a repeat mismatch must not loop
|
|
18956
|
+
healAttempted = false;
|
|
18957
|
+
healing = false;
|
|
18858
18958
|
sessions() {
|
|
18859
18959
|
return this.state.windowsSessions;
|
|
18860
18960
|
}
|
|
@@ -18868,7 +18968,7 @@ var WindowsProxy = class {
|
|
|
18868
18968
|
// windows-origin cwd is forwarded, as is I/O for a namespaced session id.
|
|
18869
18969
|
route(client, data) {
|
|
18870
18970
|
if (isWindowsCreate(data)) {
|
|
18871
|
-
void this.
|
|
18971
|
+
void forwardWindowsCreate(this.conn, this.state, client, data);
|
|
18872
18972
|
return true;
|
|
18873
18973
|
}
|
|
18874
18974
|
if (isWindowsIo(data)) {
|
|
@@ -18881,8 +18981,15 @@ var WindowsProxy = class {
|
|
|
18881
18981
|
dispose() {
|
|
18882
18982
|
this.conn.dispose();
|
|
18883
18983
|
}
|
|
18884
|
-
async
|
|
18885
|
-
|
|
18984
|
+
async handleVersionMismatch(version2) {
|
|
18985
|
+
if (this.healing || this.healAttempted) return;
|
|
18986
|
+
this.healing = true;
|
|
18987
|
+
this.healAttempted = true;
|
|
18988
|
+
try {
|
|
18989
|
+
await autoHealWindowsDaemon(this.conn, this.state, this.heal, version2);
|
|
18990
|
+
} finally {
|
|
18991
|
+
this.healing = false;
|
|
18992
|
+
}
|
|
18886
18993
|
}
|
|
18887
18994
|
handleClose() {
|
|
18888
18995
|
daemonLog("windows proxy: connection to windows daemon closed");
|
|
@@ -18895,16 +19002,6 @@ var WindowsProxy = class {
|
|
|
18895
19002
|
this.state.onSessionsChanged();
|
|
18896
19003
|
}
|
|
18897
19004
|
};
|
|
18898
|
-
function isWindowsCreate(data) {
|
|
18899
|
-
return typeof data.cwd === "string" && shouldProxyToWindows(data.cwd);
|
|
18900
|
-
}
|
|
18901
|
-
function isWindowsIo(data) {
|
|
18902
|
-
return typeof data.sessionId === "string" && isWindowsSessionId(data.sessionId);
|
|
18903
|
-
}
|
|
18904
|
-
async function defaultConnect() {
|
|
18905
|
-
await ensureWindowsDaemonRunning();
|
|
18906
|
-
return connectToWindowsDaemon();
|
|
18907
|
-
}
|
|
18908
19005
|
|
|
18909
19006
|
// src/commands/sessions/daemon/watchClaudeSessionId.ts
|
|
18910
19007
|
import * as fs27 from "fs";
|
|
@@ -19300,7 +19397,7 @@ import { unlinkSync as unlinkSync19 } from "fs";
|
|
|
19300
19397
|
import * as net3 from "net";
|
|
19301
19398
|
|
|
19302
19399
|
// src/commands/sessions/daemon/handleConnection.ts
|
|
19303
|
-
import { createInterface as
|
|
19400
|
+
import { createInterface as createInterface7 } from "readline";
|
|
19304
19401
|
|
|
19305
19402
|
// src/commands/sessions/shared/parseTranscript.ts
|
|
19306
19403
|
import * as fs28 from "fs";
|
|
@@ -19394,10 +19491,10 @@ function safeParse2(line) {
|
|
|
19394
19491
|
}
|
|
19395
19492
|
|
|
19396
19493
|
// src/commands/sessions/daemon/dispatchMessage.ts
|
|
19397
|
-
function creator(
|
|
19494
|
+
function creator(spawn12) {
|
|
19398
19495
|
return (client, m, d) => {
|
|
19399
19496
|
if (m.windowsProxy.route(client, d)) return;
|
|
19400
|
-
sendTo(client, { type: "created", sessionId:
|
|
19497
|
+
sendTo(client, { type: "created", sessionId: spawn12(m, d) });
|
|
19401
19498
|
};
|
|
19402
19499
|
}
|
|
19403
19500
|
function handleHistory(client) {
|
|
@@ -19478,7 +19575,7 @@ function handleConnection(socket, manager) {
|
|
|
19478
19575
|
}
|
|
19479
19576
|
};
|
|
19480
19577
|
manager.addClient(client);
|
|
19481
|
-
const lines =
|
|
19578
|
+
const lines = createInterface7({ input: socket });
|
|
19482
19579
|
lines.on("error", () => {
|
|
19483
19580
|
});
|
|
19484
19581
|
lines.on("line", (line) => {
|