@termhub/agent 0.5.1 → 0.5.3

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 +21 -7
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -60,7 +60,12 @@ var def = (params, result, timeoutMs = DEFAULT_TIMEOUT) => ({ params, result, ti
60
60
  var RPC = {
61
61
  "tmux.list": def(z.object({}), z.object({ sessions: z.array(sessionName) })),
62
62
  "tmux.kill": def(z.object({ session: sessionName }), z.object({ killed: z.boolean() })),
63
- "tmux.capture": def(z.object({ session: sessionName, lines: z.number().int().min(1).max(5e3) }), z.object({ text: z.string() })),
63
+ /**
64
+ * `escapes`: keep the SGR attributes (`capture-pane -e`) so the server can tell dimmed text from typed
65
+ * text (since agent 0.5.2). An older agent strips the unknown param and answers plain text with no
66
+ * `escapes` in the result — which is how the server knows.
67
+ */
68
+ "tmux.capture": def(z.object({ session: sessionName, lines: z.number().int().min(1).max(5e3), escapes: z.boolean().optional() }), z.object({ text: z.string(), escapes: z.boolean().optional() })),
64
69
  /** Idempotent: creates the detached session in `cwd` when it is missing. `created` says whether it had to. */
65
70
  "tmux.ensure": def(z.object({ session: sessionName, cwd: machinePath }), z.object({ created: z.boolean() }), 1e4),
66
71
  /**
@@ -688,6 +693,15 @@ if [ "$KIND_REST" != "$EVENT" ]; then
688
693
  else
689
694
  KIND=
690
695
  fi
696
+ # A subagent's event (Claude Code 2.1.69+) carries an "agent_id" key before its own "hook_event_name" \u2014
697
+ # the order is session_id, transcript_path, cwd, prompt_id, permission_mode, agent_id, agent_type,
698
+ # hook_event_name, \u2026 \u2014 and the main thread's never does. Only that prefix is searched, and only for the
699
+ # key form: a value holding the text "agent_id": would have its quotes escaped. The reduced bodies below
700
+ # carry the flag; the server never lets a subagent's event close a card (spec 2026-09-26 \xA74.5). The
701
+ # dedupe marker ignores it.
702
+ BEFORE_KIND=\${EVENT%%'"hook_event_name"'*}
703
+ SUB=
704
+ case "$BEFORE_KIND" in *'"agent_id":'*) SUB=',"subagent":true' ;; esac
691
705
  case "$KIND" in
692
706
  PreToolUse)
693
707
  # The event's own tool name is the FIRST "tool_name" of the payload (Claude Code serialises it
@@ -737,9 +751,9 @@ case "$KIND" in
737
751
  [ "$(cat "$MARK" 2>/dev/null)" = "$KEY" ] && exit 0
738
752
  printf '%s' "$KEY" 2>/dev/null > "$MARK"
739
753
  if [ -n "$VERB" ]; then
740
- EVENT=$(printf '{"hook_event_name":"PreToolUse","tool_name":"%s","verb":"%s"}' "$NAME" "$VERB")
754
+ EVENT=$(printf '{"hook_event_name":"PreToolUse","tool_name":"%s","verb":"%s"%s}' "$NAME" "$VERB" "$SUB")
741
755
  else
742
- EVENT=$(printf '{"hook_event_name":"PreToolUse","tool_name":"%s"}' "$NAME")
756
+ EVENT=$(printf '{"hook_event_name":"PreToolUse","tool_name":"%s"%s}' "$NAME" "$SUB")
743
757
  fi
744
758
  fi
745
759
  ;;
@@ -752,7 +766,7 @@ case "$KIND" in
752
766
  REST=\${REST#*'"'}
753
767
  NAME=\${REST%%'"'*}
754
768
  case "$NAME" in '' | *[!A-Za-z0-9_.-]* | AskUserQuestion) exit 0 ;; esac
755
- EVENT=$(printf '{"hook_event_name":"PermissionRequest","tool_name":"%s"}' "$NAME")
769
+ EVENT=$(printf '{"hook_event_name":"PermissionRequest","tool_name":"%s"%s}' "$NAME" "$SUB")
756
770
  ;;
757
771
  # A new turn starts fresh, and so does an answered notification: a permission prompt takes the tab
758
772
  # out of working, and the tool the person approves is the same one that set the marker, so without
@@ -2020,11 +2034,11 @@ async function kill(params) {
2020
2034
  return { killed: r.code === 0 };
2021
2035
  }
2022
2036
  async function capture(params) {
2023
- const r = await run(tmuxPath(), ["capture-pane", "-p", "-S", `-${params.lines}`, "-t", `=${params.session}:`]);
2037
+ const r = await run(tmuxPath(), ["capture-pane", "-p", ...params.escapes ? ["-e"] : [], "-S", `-${params.lines}`, "-t", `=${params.session}:`]);
2024
2038
  const failure = processFailure2(r);
2025
2039
  if (failure) throw failure;
2026
2040
  if (r.code !== 0) throw new RpcFailure("notfound", "session not found");
2027
- return { text: r.stdout };
2041
+ return params.escapes ? { text: r.stdout, escapes: true } : { text: r.stdout };
2028
2042
  }
2029
2043
  var pane = (session) => `=${session}:`;
2030
2044
  var why = (stderr, fallback) => stderr.trim().split("\n")[0] || fallback;
@@ -2312,7 +2326,7 @@ async function status3() {
2312
2326
  }
2313
2327
 
2314
2328
  // src/version.ts
2315
- var AGENT_VERSION = "0.5.1";
2329
+ var AGENT_VERSION = "0.5.3";
2316
2330
 
2317
2331
  // src/rpc/update.ts
2318
2332
  var PACKAGE = "@termhub/agent";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@termhub/agent",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
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,