@threahq/pi-remote0.2.2
A Pi extension that links a local Pi session to a Threa scratchpad, so you can drive Pi from Threa.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
Threa Pi remote extension
Pi package for linking a local Pi session to a Threa scratchpad.
End-to-end encrypted scratchpads
The extension serves sealed (E2EE) turns via @threahq/bot-runtime-client's sealed
module. On first presence write it mints a BIK (Bot Identity Key, an X25519
keypair persisted 0600 at ~/.pi/agent/threa-remote-bik.json) and registers
the public half on every hello/presence. Once the scratchpad owner invites this
bot into an encrypted scratchpad (which wraps the stream key to the BIK), claims
arrive sealed: the extension decrypts the trigger + history locally, runs the
turn, and seals every reply and trace step back under the stream key — the
server only ever stores ciphertext.
Messages while Pi is busy
A plain message sent while a turn runs is delivered into that turn as steering input (deliverAs: "steer"). /enqueue <message> waits instead: Pi claims it only when idle, with no turn pending and no rate-limit retry scheduled.
Invocation edits and deletion
The extension applies source-message edits to an active Pi turn as steering input. It rebuilds plaintext context and attachments from Threa; sealed turns decrypt updated attachment references locally. Completions carry the exact applied source revision, so stale output cannot replace a newer edit.
Deleting the source or losing its claim aborts the active Pi turn and suppresses late trace and completion writes. The shared runtime client owns claim renewal and control synchronization. /reload saves active revisions and retry prompts, then re-registers each claim before resuming work.
Trace detail
Plaintext traces default to traceMode: "headline". This records tool categories and safe file summaries but hides shell commands, file bodies, patches, and tool results.
Set traceMode: "commands" in ~/.pi/agent/threa-remote.json to include only the Bash command field. Commands are capped at 2,000 characters; write/edit payloads and every tool result remain hidden. Multiline commands show only their first line in the headline; the bounded command stays in the collapsed Details section. Inline scripts and heredocs are part of that command and may appear up to the cap. Plaintext commands are sent to Threa and stored with the trace, so leave headline mode enabled when commands may contain credentials or file content.
Because the server can't read sealed step content, sealed turns default to FULL
trace detail (real commands, file contents, tool output) instead of the
"omitted for safety" redactions headline mode keeps. Set sealedFullTrace: false to use the configured traceMode on sealed turns too. For command-only
traces everywhere, use traceMode: "commands" with sealedFullTrace: false.
The toggle can never enable full detail on a plaintext turn. Attachments
(THREA_ATTACH: lines, and markdown images outside code that point at a local
png, jpg, gif, webp or svg) work on sealed turns too: the file is encrypted
locally under a fresh single-use key,
only ciphertext is uploaded (placeholder name/mime on the server), and the key
rides sealed inside the reply payload — inbound attachments are likewise
fetched as ciphertext and decrypted locally. Deleting the BIK file orphans the
owner's key wraps; the owner must re-invite the bot after it registers a fresh
key.
Install
pi install npm:@threahq/pi-remote
Then run /reload in Pi, or start a new session, and /remote-control configure to paste the setup JSON. pi update --extensions picks up new releases.
Coming from the old install script? Remove its copy first so only one copy loads: rm -rf ~/.pi/agent/extensions/threa-remote.
Working on the extension itself? Run bun install in extensions/pi-remote, then pi install /ABSOLUTE/PATH/TO/threa/extensions/pi-remote. Pi loads src/threa-remote.ts straight from the checkout.
For harness-managed sessions, /kick in the linked scratchpad asks harnessd to send Enter to the session's recorded tmux pane, useful when Pi is waiting on a blocking prompt. /reconnect [--force] is offered only to a live, linked Pi running in tmux; it acknowledges first, then asks harnessd to replace the pane process and resume the same Pi session. --force may bypass only local Pi activity; an owned pending Threa invocation always fails closed and must be cleared with /stop first. The command cannot recover a disconnected runtime. Direct harnessd reconnect for Pi has no activity signal, so --force is currently inert there; this intentionally does not add IPC, status reporting, or another supervisor.
/key <name> sends one key to the exact live linked Pi pane. Allowed names are escape, enter, up, down, left, right, tab, backspace, ctrl-c, ctrl-d, and ctrl-u. Names are case-sensitive; text, aliases, sequences, and repeats are rejected.