tmux-agent-monitor 0.0.12 → 0.0.15
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
CHANGED
|
@@ -1262,12 +1262,21 @@ const createApp = ({ config, monitor, tmuxActions }) => {
|
|
|
1262
1262
|
return token === config.token;
|
|
1263
1263
|
};
|
|
1264
1264
|
const isOriginAllowed = (origin, host) => {
|
|
1265
|
-
if (
|
|
1265
|
+
if (config.allowedOrigins.length === 0) return true;
|
|
1266
|
+
if (!origin) return false;
|
|
1266
1267
|
return config.allowedOrigins.includes(origin) || (host ? config.allowedOrigins.includes(host) : false);
|
|
1267
1268
|
};
|
|
1268
1269
|
const sendWs = (ws, message) => {
|
|
1269
1270
|
ws.send(JSON.stringify(message));
|
|
1270
1271
|
};
|
|
1272
|
+
const closeAllWsClients = (code, reason) => {
|
|
1273
|
+
wsClients.forEach((ws) => {
|
|
1274
|
+
try {
|
|
1275
|
+
ws.close(code, reason);
|
|
1276
|
+
} catch {}
|
|
1277
|
+
});
|
|
1278
|
+
wsClients.clear();
|
|
1279
|
+
};
|
|
1271
1280
|
const broadcast = (message) => {
|
|
1272
1281
|
const payload = JSON.stringify(message);
|
|
1273
1282
|
wsClients.forEach((ws) => ws.send(payload));
|
|
@@ -1374,6 +1383,7 @@ const createApp = ({ config, monitor, tmuxActions }) => {
|
|
|
1374
1383
|
app.post("/api/admin/token/rotate", (c) => {
|
|
1375
1384
|
const next = rotateToken();
|
|
1376
1385
|
config.token = next.token;
|
|
1386
|
+
closeAllWsClients(1008, "token rotated");
|
|
1377
1387
|
return c.json({ token: next.token });
|
|
1378
1388
|
});
|
|
1379
1389
|
const wsHandler = upgradeWebSocket(() => ({
|
|
@@ -2345,6 +2355,8 @@ const buildError = (code, message) => ({
|
|
|
2345
2355
|
});
|
|
2346
2356
|
const createTmuxActions = (adapter, config) => {
|
|
2347
2357
|
const dangerPatterns = compileDangerPatterns(config.dangerCommandPatterns);
|
|
2358
|
+
const dangerKeys = new Set(config.dangerKeys);
|
|
2359
|
+
const pendingCommands = /* @__PURE__ */ new Map();
|
|
2348
2360
|
const enterKey = config.input.enterKey || "C-m";
|
|
2349
2361
|
const enterDelayMs = config.input.enterDelayMs ?? 0;
|
|
2350
2362
|
const bracketedPaste = (value) => `\u001b[200~${value}\u001b[201~`;
|
|
@@ -2357,10 +2369,22 @@ const createTmuxActions = (adapter, config) => {
|
|
|
2357
2369
|
ok: false,
|
|
2358
2370
|
error: buildError("INVALID_PAYLOAD", "text too long")
|
|
2359
2371
|
};
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2372
|
+
const normalized = text.replace(/\r\n/g, "\n");
|
|
2373
|
+
const combined = `${pendingCommands.get(paneId) ?? ""}${normalized}`;
|
|
2374
|
+
if (combined.length > config.input.maxTextLength) {
|
|
2375
|
+
pendingCommands.delete(paneId);
|
|
2376
|
+
return {
|
|
2377
|
+
ok: false,
|
|
2378
|
+
error: buildError("INVALID_PAYLOAD", "text too long")
|
|
2379
|
+
};
|
|
2380
|
+
}
|
|
2381
|
+
if (isDangerousCommand(combined, dangerPatterns)) {
|
|
2382
|
+
pendingCommands.delete(paneId);
|
|
2383
|
+
return {
|
|
2384
|
+
ok: false,
|
|
2385
|
+
error: buildError("DANGEROUS_COMMAND", "dangerous command blocked")
|
|
2386
|
+
};
|
|
2387
|
+
}
|
|
2364
2388
|
await adapter.run([
|
|
2365
2389
|
"if-shell",
|
|
2366
2390
|
"-t",
|
|
@@ -2368,7 +2392,6 @@ const createTmuxActions = (adapter, config) => {
|
|
|
2368
2392
|
"[ \"#{pane_in_mode}\" = \"1\" ]",
|
|
2369
2393
|
`copy-mode -q -t ${paneId}`
|
|
2370
2394
|
]);
|
|
2371
|
-
const normalized = text.replace(/\r\n/g, "\n");
|
|
2372
2395
|
if (normalized.includes("\n")) {
|
|
2373
2396
|
const result = await adapter.run([
|
|
2374
2397
|
"send-keys",
|
|
@@ -2394,6 +2417,7 @@ const createTmuxActions = (adapter, config) => {
|
|
|
2394
2417
|
error: buildError("INTERNAL", enterResult.stderr || "send-keys Enter failed")
|
|
2395
2418
|
};
|
|
2396
2419
|
}
|
|
2420
|
+
pendingCommands.delete(paneId);
|
|
2397
2421
|
return { ok: true };
|
|
2398
2422
|
}
|
|
2399
2423
|
const result = await adapter.run([
|
|
@@ -2419,7 +2443,10 @@ const createTmuxActions = (adapter, config) => {
|
|
|
2419
2443
|
ok: false,
|
|
2420
2444
|
error: buildError("INTERNAL", enterResult.stderr || "send-keys Enter failed")
|
|
2421
2445
|
};
|
|
2446
|
+
pendingCommands.delete(paneId);
|
|
2447
|
+
return { ok: true };
|
|
2422
2448
|
}
|
|
2449
|
+
pendingCommands.set(paneId, combined);
|
|
2423
2450
|
return { ok: true };
|
|
2424
2451
|
};
|
|
2425
2452
|
const sendKeys = async (paneId, keys) => {
|
|
@@ -2428,6 +2455,10 @@ const createTmuxActions = (adapter, config) => {
|
|
|
2428
2455
|
ok: false,
|
|
2429
2456
|
error: buildError("INVALID_PAYLOAD", "invalid keys")
|
|
2430
2457
|
};
|
|
2458
|
+
if (keys.some((key) => dangerKeys.has(key))) return {
|
|
2459
|
+
ok: false,
|
|
2460
|
+
error: buildError("DANGEROUS_COMMAND", "dangerous key blocked")
|
|
2461
|
+
};
|
|
2431
2462
|
for (const key of keys) {
|
|
2432
2463
|
const result = await adapter.run([
|
|
2433
2464
|
"send-keys",
|