@openscout/scout 0.2.69 → 0.2.72
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/README.md +22 -0
- package/bin/openscout-runtime.mjs +23 -2
- package/dist/client/assets/RepoDiffViewer-DRzXs-TP.js +1 -0
- package/dist/client/assets/{addon-fit-DtSNdpy5.js → addon-fit-C5ueiijZ.js} +1 -1
- package/dist/client/assets/{addon-webgl-YYNKPQUg.js → addon-webgl-Cm7sl8RO.js} +1 -1
- package/dist/client/assets/index-CYs6TkOv.js +191 -0
- package/dist/client/assets/index-n_fpvwq8.css +1 -0
- package/dist/client/assets/{xterm-fBtFsYpq.js → xterm-FFux-PdF.js} +1 -1
- package/dist/client/index.html +36 -2
- package/dist/main.mjs +24567 -18118
- package/dist/openscout-terminal-relay.mjs +14 -74
- package/dist/pair-supervisor.mjs +8810 -3328
- package/dist/runtime/base-daemon.mjs +96 -16
- package/dist/runtime/broker-daemon.mjs +9907 -2715
- package/dist/runtime/broker-process-manager.mjs +50 -11
- package/dist/runtime/mesh-discover.mjs +50 -11
- package/dist/scout-control-plane-web.mjs +11134 -1542
- package/dist/scout-web-server.mjs +11134 -1542
- package/package.json +2 -2
- package/dist/client/assets/index-5-XOQrKH.js +0 -186
- package/dist/client/assets/index-BnA2HAbt.css +0 -1
|
@@ -8,10 +8,10 @@ import { createRequire as createRequire2 } from "node:module";
|
|
|
8
8
|
// packages/web/server/terminal-relay-session.ts
|
|
9
9
|
import { createRequire } from "module";
|
|
10
10
|
import { execFileSync, execSync } from "child_process";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
12
|
+
import { join, dirname as pathDirname } from "path";
|
|
13
13
|
var require2 = createRequire(import.meta.url);
|
|
14
|
-
var pty = require2("node-pty");
|
|
14
|
+
var pty = require2("@lydell/node-pty");
|
|
15
15
|
var DEFAULT_ORPHAN_TTL_MS = 30 * 60 * 1000;
|
|
16
16
|
var MAX_BUFFER_SIZE = 512 * 1024;
|
|
17
17
|
var sessions = new Map;
|
|
@@ -93,78 +93,17 @@ function findBin(name, envOverride) {
|
|
|
93
93
|
return null;
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
-
function expandHomePath(value) {
|
|
97
|
-
const home = process.env.HOME || "/tmp";
|
|
98
|
-
if (value === "~")
|
|
99
|
-
return home;
|
|
100
|
-
if (value.startsWith("~/"))
|
|
101
|
-
return join(home, value.slice(2));
|
|
102
|
-
return value;
|
|
103
|
-
}
|
|
104
|
-
function isExecutablePath(candidate) {
|
|
105
|
-
if (!candidate)
|
|
106
|
-
return false;
|
|
107
|
-
try {
|
|
108
|
-
accessSync(candidate, constants.X_OK);
|
|
109
|
-
return true;
|
|
110
|
-
} catch {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
function findExecutableInDirectories(name, directories) {
|
|
115
|
-
const seen = new Set;
|
|
116
|
-
for (const directory of directories) {
|
|
117
|
-
if (!directory)
|
|
118
|
-
continue;
|
|
119
|
-
const normalizedDirectory = pathResolve(expandHomePath(directory));
|
|
120
|
-
if (seen.has(normalizedDirectory))
|
|
121
|
-
continue;
|
|
122
|
-
seen.add(normalizedDirectory);
|
|
123
|
-
const candidate = join(normalizedDirectory, name);
|
|
124
|
-
if (isExecutablePath(candidate))
|
|
125
|
-
return candidate;
|
|
126
|
-
}
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
function findExecutableOnPath(name) {
|
|
130
|
-
return findExecutableInDirectories(name, (process.env.PATH || "").split(pathDelimiter));
|
|
131
|
-
}
|
|
132
96
|
function findClaudeBin() {
|
|
133
|
-
|
|
134
|
-
const explicit = process.env[envKey]?.trim();
|
|
135
|
-
if (!explicit)
|
|
136
|
-
continue;
|
|
137
|
-
const expanded = expandHomePath(explicit);
|
|
138
|
-
if (isExecutablePath(expanded))
|
|
139
|
-
return pathResolve(expanded);
|
|
140
|
-
const foundOnPath = findExecutableOnPath(explicit);
|
|
141
|
-
if (foundOnPath)
|
|
142
|
-
return foundOnPath;
|
|
143
|
-
}
|
|
144
|
-
const home = process.env.HOME || "/tmp";
|
|
145
|
-
return findExecutableInDirectories("claude", [
|
|
146
|
-
join(home, ".local", "bin"),
|
|
147
|
-
join(home, ".claude", "local"),
|
|
148
|
-
"/opt/homebrew/bin",
|
|
149
|
-
"/usr/local/bin",
|
|
150
|
-
join(home, ".bun", "bin")
|
|
151
|
-
]) ?? findExecutableOnPath("claude");
|
|
97
|
+
return findBin("claude", "CLAUDE_BIN");
|
|
152
98
|
}
|
|
153
99
|
function findPiBin() {
|
|
154
100
|
return findBin("pi", "PI_BIN");
|
|
155
101
|
}
|
|
156
102
|
function findShellBin() {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
"/bin/sh"
|
|
162
|
-
].filter((candidate) => Boolean(candidate));
|
|
163
|
-
for (const candidate of candidates) {
|
|
164
|
-
if (existsSync(candidate))
|
|
165
|
-
return candidate;
|
|
166
|
-
}
|
|
167
|
-
return null;
|
|
103
|
+
const configured = process.env.SHELL;
|
|
104
|
+
if (configured && existsSync(configured))
|
|
105
|
+
return configured;
|
|
106
|
+
return findBin("zsh") ?? findBin("bash") ?? findBin("sh") ?? (existsSync("/bin/sh") ? "/bin/sh" : null);
|
|
168
107
|
}
|
|
169
108
|
function normalizePiProviderForCli(provider) {
|
|
170
109
|
if (!provider)
|
|
@@ -213,10 +152,10 @@ function bootstrapFiles(cwd, files, sessionId) {
|
|
|
213
152
|
}
|
|
214
153
|
}
|
|
215
154
|
}
|
|
216
|
-
function spawnTmuxSession(tmuxName, cols, rows, cwd,
|
|
155
|
+
function spawnTmuxSession(tmuxName, cols, rows, cwd, commandBin, commandArgs, env) {
|
|
217
156
|
const exists = tmuxSessionExists(tmuxName);
|
|
218
157
|
if (!exists) {
|
|
219
|
-
const shellCmd = [
|
|
158
|
+
const shellCmd = [commandBin, ...commandArgs].map((a) => a.includes(" ") ? `'${a}'` : a).join(" ");
|
|
220
159
|
execSync(`tmux new-session -d -s ${tmuxName} -x ${cols} -y ${rows} -c '${cwd}' '${shellCmd}'`, { env });
|
|
221
160
|
console.log(`[relay] Created tmux session: ${tmuxName}`);
|
|
222
161
|
} else {
|
|
@@ -242,7 +181,7 @@ function createSession(ws, msg) {
|
|
|
242
181
|
if (agent === "shell") {
|
|
243
182
|
agentBin = findShellBin();
|
|
244
183
|
if (!agentBin) {
|
|
245
|
-
const reason = "
|
|
184
|
+
const reason = "No login shell found. Set SHELL or install zsh, bash, or sh.";
|
|
246
185
|
console.error(`[relay] Session ${id} failed: ${reason}`);
|
|
247
186
|
send(ws, { type: "session:error", error: reason });
|
|
248
187
|
return null;
|
|
@@ -258,7 +197,7 @@ function createSession(ws, msg) {
|
|
|
258
197
|
} else {
|
|
259
198
|
agentBin = findClaudeBin();
|
|
260
199
|
if (!agentBin) {
|
|
261
|
-
const reason = "Claude CLI not found. Install it with:
|
|
200
|
+
const reason = "Claude CLI not found. Install it with: npm install -g @anthropic-ai/claude-code";
|
|
262
201
|
console.error(`[relay] Session ${id} failed: ${reason}`);
|
|
263
202
|
send(ws, { type: "session:error", error: reason });
|
|
264
203
|
return null;
|
|
@@ -282,7 +221,8 @@ function createSession(ws, msg) {
|
|
|
282
221
|
}
|
|
283
222
|
let agentArgs;
|
|
284
223
|
if (agent === "shell") {
|
|
285
|
-
|
|
224
|
+
const shellName = agentBin.split("/").pop() ?? "";
|
|
225
|
+
agentArgs = shellName === "sh" ? [] : ["-l"];
|
|
286
226
|
} else if (agent === "pi") {
|
|
287
227
|
agentArgs = ["--verbose"];
|
|
288
228
|
const provider = normalizePiProviderForCli(msg.provider);
|