@termhub/agent 0.2.4 → 0.3.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.
Files changed (2) hide show
  1. package/dist/cli.js +31 -7
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -56,8 +56,12 @@ var RPC = {
56
56
  "tmux.capture": def(z.object({ session: sessionName, lines: z.number().int().min(1).max(5e3) }), z.object({ text: z.string() })),
57
57
  /** Idempotent: creates the detached session in `cwd` when it is missing. `created` says whether it had to. */
58
58
  "tmux.ensure": def(z.object({ session: sessionName, cwd: machinePath }), z.object({ created: z.boolean() }), 1e4),
59
- /** Types `text` literally, then (with `enter`) presses Enter on its own after a short pause. */
60
- "tmux.sendText": def(z.object({ session: sessionName, text: z.string().max(TEXT_MAX_CHARS), enter: z.boolean() }), z.object({ sent: z.literal(true) }), 1e4),
59
+ /**
60
+ * Types `text` literally, then (with `enter`) presses Enter on its own after a short pause.
61
+ * `paste`: deliver `text` as a tmux buffer paste instead of typed keystrokes, so a TUI reads
62
+ * an embedded newline as part of the pasted text rather than as Enter (since agent 0.3.0).
63
+ */
64
+ "tmux.sendText": def(z.object({ session: sessionName, text: z.string().max(TEXT_MAX_CHARS), enter: z.boolean(), paste: z.boolean().optional() }), z.object({ sent: z.literal(true) }), 1e4),
61
65
  "tmux.sendKey": def(z.object({ session: sessionName, key: tmuxKey }), z.object({ sent: z.literal(true) }), 1e4),
62
66
  "tools.detect": def(z.object({}), z.object({ os: z.string().nullable(), tools: z.array(z.string().max(32)) })),
63
67
  "hw.probe": def(z.object({}), z.object({ stdout: z.string() }), 15e3),
@@ -1238,6 +1242,7 @@ async function pasteFile(params) {
1238
1242
  }
1239
1243
 
1240
1244
  // src/rpc/tmux.ts
1245
+ import { randomUUID } from "crypto";
1241
1246
  var ENTER_PAUSE_MS = 300;
1242
1247
  function processFailure2(r) {
1243
1248
  if (r.timedOut) return new RpcFailure("timeout", "tmux timed out");
@@ -1279,12 +1284,31 @@ async function ensure(params) {
1279
1284
  if (made.code !== 0) throw new RpcFailure("failed", why(made.stderr, "tmux new-session falhou"), params.cwd);
1280
1285
  return { created: true };
1281
1286
  }
1287
+ async function pasteText(session, text) {
1288
+ const bufferName = `termhub-paste-${randomUUID()}`;
1289
+ try {
1290
+ const loaded = await run(tmuxPath(), ["load-buffer", "-b", bufferName, "-"], { input: Buffer.from(text, "utf8") });
1291
+ const loadFailure = processFailure2(loaded);
1292
+ if (loadFailure) throw loadFailure;
1293
+ if (loaded.code !== 0) throw new RpcFailure("internal", why(loaded.stderr, "tmux load-buffer failed"));
1294
+ const pasted = await run(tmuxPath(), ["paste-buffer", "-p", "-d", "-b", bufferName, "-t", pane(session)]);
1295
+ const pasteFailure = processFailure2(pasted);
1296
+ if (pasteFailure) throw pasteFailure;
1297
+ if (pasted.code !== 0) throw new RpcFailure("notfound", why(pasted.stderr, "session not found"));
1298
+ } finally {
1299
+ await run(tmuxPath(), ["delete-buffer", "-b", bufferName]);
1300
+ }
1301
+ }
1282
1302
  async function sendText(params) {
1283
1303
  if (params.text) {
1284
- const typed = await run(tmuxPath(), ["send-keys", "-t", pane(params.session), "-l", "--", params.text]);
1285
- const failure = processFailure2(typed);
1286
- if (failure) throw failure;
1287
- if (typed.code !== 0) throw new RpcFailure("notfound", why(typed.stderr, "session not found"));
1304
+ if (params.paste) {
1305
+ await pasteText(params.session, params.text);
1306
+ } else {
1307
+ const typed = await run(tmuxPath(), ["send-keys", "-t", pane(params.session), "-l", "--", params.text]);
1308
+ const failure = processFailure2(typed);
1309
+ if (failure) throw failure;
1310
+ if (typed.code !== 0) throw new RpcFailure("notfound", why(typed.stderr, "session not found"));
1311
+ }
1288
1312
  if (params.enter) await new Promise((r) => setTimeout(r, ENTER_PAUSE_MS));
1289
1313
  }
1290
1314
  if (params.enter) {
@@ -1533,7 +1557,7 @@ async function status3() {
1533
1557
  }
1534
1558
 
1535
1559
  // src/version.ts
1536
- var AGENT_VERSION = "0.2.4";
1560
+ var AGENT_VERSION = "0.3.0";
1537
1561
 
1538
1562
  // src/rpc/update.ts
1539
1563
  var PACKAGE = "@termhub/agent";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@termhub/agent",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "description": "Agente do termhub: conecta esta máquina ao servidor por WebSocket de saída (sem SSH) e expõe os terminais tmux no navegador.",
5
5
  "license": "MIT",
6
6
  "private": false,