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 (!origin || config.allowedOrigins.length === 0) return config.allowedOrigins.length === 0 || (host ? config.allowedOrigins.includes(host) : true);
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
- if (isDangerousCommand(text, dangerPatterns)) return {
2361
- ok: false,
2362
- error: buildError("DANGEROUS_COMMAND", "dangerous command blocked")
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",