diff options
| -rw-r--r-- | crates/dinggerd/assets/pi/pi-agent-state.ts | 21 | ||||
| -rw-r--r-- | crates/dinggerd/src/hooks.rs | 2 | ||||
| -rwxr-xr-x | tests/e2e.sh | 32 |
3 files changed, 37 insertions, 18 deletions
diff --git a/crates/dinggerd/assets/pi/pi-agent-state.ts b/crates/dinggerd/assets/pi/pi-agent-state.ts index 49d4b9c..df9e4e2 100644 --- a/crates/dinggerd/assets/pi/pi-agent-state.ts +++ b/crates/dinggerd/assets/pi/pi-agent-state.ts @@ -3,29 +3,16 @@ // add custom hooks/plugins beside this file instead of editing it. import net from "node:net"; -import path from "node:path"; -import { execSync } from "node:child_process"; // The dingger hook receiver listens here; override with DINGGER_AGENT_SOCKET. const socketPath = process.env.DINGGER_AGENT_SOCKET || `${process.env.HOME}/.local/state/dingger/agent.sock`; -// The extension runs inside a tmux pane, so it finds its own pane id. -function discoverPaneId(): string | undefined { - try { - const out = execSync('tmux display-message -p "#{pane_id}"', { - encoding: "utf8", - stdio: ["ignore", "pipe", "ignore"], - }); - const paneId = out.trim(); - return paneId.startsWith("%") ? paneId : undefined; - } catch { - return undefined; - } -} - -const paneId = process.env.DINGGER_PANE_ID || discoverPaneId(); +// tmux sets TMUX_PANE in the environment of every process it starts in a +// pane, so it names exactly the pane this pi runs in. (Asking tmux for "the +// current pane" is wrong: that is the session's active pane, not ours.) +const paneId = process.env.DINGGER_PANE_ID || process.env.TMUX_PANE; const source = "dingger:pi"; function enabled() { diff --git a/crates/dinggerd/src/hooks.rs b/crates/dinggerd/src/hooks.rs index 40f0f20..524fb2d 100644 --- a/crates/dinggerd/src/hooks.rs +++ b/crates/dinggerd/src/hooks.rs @@ -124,7 +124,7 @@ fn handle_stream(stream: UnixStream) { continue; } }; - debug!(pane = %params.pane_id, ?state, "hook report"); + info!(pane = %params.pane_id, ?state, "hook report"); { let mut reports = reports(); let pane = reports.entry(params.pane_id).or_default(); diff --git a/tests/e2e.sh b/tests/e2e.sh index d74d73b..b63260c 100755 --- a/tests/e2e.sh +++ b/tests/e2e.sh @@ -239,6 +239,38 @@ else fail "menu bar binary not found at $MENUBAR" fi +# --- 12. the shipped pi extension reports for its own pane ------------------- +echo "12. pi extension" +cat >"$DIR/ext-harness.mjs" <<'JS' +// Loads the shipped extension with a fake pi and fires lifecycle events. +const ext = await import(process.env.EXTENSION); +const on = {}; +ext.default({ on: (name, fn) => (on[name] = fn), events: { on: () => {} } }); +const ctx = { mode: "tui", isIdle: () => true }; +for (const event of process.argv.slice(2)) { + await on[event]?.({ type: event, reason: "reload" }, ctx); + await new Promise((r) => setTimeout(r, 300)); +} +JS +ext() { # pane events... (run "inside" a pane: tmux sets TMUX_PANE there) + local pane=$1; shift + TMUX_PANE="$pane" EXTENSION="$ROOT/crates/dinggerd/assets/pi/pi-agent-state.ts" \ + node --experimental-strip-types --no-warnings "$DIR/ext-harness.mjs" "$@" +} +if command -v node >/dev/null; then + # A2 is not the active pane of session a (wa1 is the active window), the + # case where asking tmux for "the current pane" picks the wrong pane. + [ "$(t display -p -t a: '#{pane_id}')" != "$A2" ] && pass "A2 is not session a's active pane" || fail "test setup: A2 is active" + before_a1=$(opt "$A1" @agent_state) + ext "$A2" session_start agent_start + expect "extension report lands on A2 (working)" "opt $A2 @agent_state" working + expect "A1 untouched" "opt $A1 @agent_state" "$before_a1" + ext "$A2" agent_settled + expect "extension completion away from the window: A2 done" "opt $A2 @agent_state" done +else + fail "node not found; cannot test the pi extension" +fi + echo echo "$PASSES passed, $FAILS failed" [ "$FAILS" -eq 0 ] || { echo "--- daemon log tail"; tail -30 "$DIR/daemon.log"; exit 1; } |
