<feed xmlns='http://www.w3.org/2005/Atom'>
<title>dot.git, branch master</title>
<subtitle>Shell, editor and terminal configuration, and the tools that go with them
</subtitle>
<id>https://git.soarez.net/sz/dot.git/atom?h=master</id>
<link rel='self' href='https://git.soarez.net/sz/dot.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/'/>
<updated>2026-11-06T11:58:14+00:00</updated>
<entry>
<title>pi compact-tools: let the forum tool draw its own rows</title>
<updated>2026-11-06T11:58:14+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-11-06T11:58:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=179de57cd3389f5c87d1fa951f9c393fe6da5f8e'/>
<id>urn:sha1:179de57cd3389f5c87d1fa951f9c393fe6da5f8e</id>
<content type='text'>
Compacted, a forum send showed only its name; its own renderer shows
the message, folded to 10 lines.
</content>
</entry>
<entry>
<title>pi forum: give a fresh session its notice with the first run</title>
<updated>2026-11-06T11:58:14+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-11-06T11:58:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=e01393235ef52fc05f2a4a3768f22e73eb12cd73'/>
<id>urn:sha1:e01393235ef52fc05f2a4a3768f22e73eb12cd73</id>
<content type='text'>
Appended to a session with no conversation yet -- a new pi, or just
after /new -- the join notice sat ahead of the system message pi records
at the first run, and pi then sent that message without its content: the
provider refused every request with a 400. Queue it for the next turn
instead, which pi places after the system message.
</content>
</entry>
<entry>
<title>pi forum: fold long messages in the transcript, whole on expand</title>
<updated>2026-11-06T11:58:14+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-11-06T11:58:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=3cfe984ab7e26aaad4a2442501526b6a2f232bc0'/>
<id>urn:sha1:3cfe984ab7e26aaad4a2442501526b6a2f232bc0</id>
<content type='text'>
A message of up to 4000 characters printed in full in both panes; show
its first 10 lines, or 1000 characters, and how much more there is,
as pi does for tool output. The model still gets the whole text.
</content>
</entry>
<entry>
<title>pi forum: let agents the user puts in a forum find and message each other</title>
<updated>2026-11-04T13:28:11+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-11-04T13:28:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=6c96aca6839ce75e380321bb861452bc987e06c3'/>
<id>urn:sha1:6c96aca6839ce75e380321bb861452bc987e06c3</id>
<content type='text'>
/forum &lt;name&gt; puts this pi in a forum; its members can list each other,
post to it (waking only those mentioned), read its history, set its pin,
and send each other direct messages, delivered the way alarm.ts delivers
alarms. Only the user adds an agent; any pane can remove one. Forums and
their posts live in ~/.pi/forum until /forum delete; membership lasts as
long as the pi process.
</content>
</entry>
<entry>
<title>yubikey-git: three keys, one per YubiKey; any one of them will do</title>
<updated>2026-11-02T11:09:27+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-11-02T11:09:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=cee12b2bd16b001153051fa8cbaacb7b1fe1403b'/>
<id>urn:sha1:cee12b2bd16b001153051fa8cbaacb7b1fe1403b</id>
<content type='text'>
</content>
</entry>
<entry>
<title>pi alarm: keep pending alarms across /reload</title>
<updated>2026-10-30T16:42:18+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-10-30T16:36:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=6c7059865a615cf27226fa09562e6f1deb9beccb'/>
<id>urn:sha1:6c7059865a615cf27226fa09562e6f1deb9beccb</id>
<content type='text'>
/reload dropped every pending alarm and stopped its when_done command,
without a word. An agent that had ended its turn to wait for one was never
woken -- nor a pi-goal goal_wait counting on it.

The old copy of the extension now leaves what is pending on globalThis
instead: each alarm as plain data, the due queue, the next id, and a
when_done command's ChildProcess with its own listeners removed. The copy
pi loads next arms fresh timers from each alarm's absolute time, listens
on the command again (one that exited meanwhile still holds its status),
and resumes polling PIDs. Nothing crosses that would reach the old,
stale pi or ctx.

A handoff from another session or another HANDOFF_VERSION is refused and
its commands stopped, with a notice. If nothing takes it within 30s --
the file failed to load, or was removed -- the old copy stops its
commands. Quitting, /new, /resume and /fork still drop everything.
</content>
</entry>
<entry>
<title>pi: generate mcp.json from ~/.config/pi/mcp.d fragments</title>
<updated>2026-10-29T21:40:43+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-10-29T21:40:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=b3448031088447d76d80ac6b2bfa08320973a2d9'/>
<id>urn:sha1:b3448031088447d76d80ac6b2bfa08320973a2d9</id>
<content type='text'>
pi reads user-level MCP servers from one file, and a private layer
linked that file to the same copy on every host -- so every host got a
server only one machine could run. Build it the way models.json is
built, from fragments another layer or one machine drops in mcp.d; this
repo ships none, and with none the file is left absent.

pi-models.py becomes pi-merge.py, which takes the key to merge and an
optional base file, and serves both.
</content>
</entry>
<entry>
<title>sz-final-review-loop: wait with a wake armed, not blocked in sz-wait-for</title>
<updated>2026-10-27T09:36:43+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-10-27T09:36:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=b5100c2e088ef5c966b114f968847de779ed852f'/>
<id>urn:sha1:b5100c2e088ef5c966b114f968847de779ed852f</id>
<content type='text'>
The loop's agents blocked in a foreground sz-wait-for because nothing could
bring an agent back from a background one. Both harnesses now can: pi's
alarm fires when a when_done command exits, and Claude Code starts a new
turn when a run_in_background Bash task exits (checked on 2.1.310). So an
agent arms sz-wait-for as a wake and ends its turn: no context resent every
30 minutes to re-arm, the human can talk to it while it waits, and "arm,
then signal" becomes literal. The foreground wait stays for a harness with
neither.

The invariant is unchanged in substance: never idle, where idle now means
the other side's turn with no wake armed. sz-wait-for stays the watcher, for
its settle window.

pi-subagent: §5 says how to be woken in Claude Code too.
</content>
</entry>
<entry>
<title>pi alarm: fire when a command exits or when processes exit</title>
<updated>2026-10-27T09:12:21+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-10-27T09:12:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=11adcd3f5c6b2d60578096b039426ab21d171bda'/>
<id>urn:sha1:11adcd3f5c6b2d60578096b039426ab21d171bda</id>
<content type='text'>
when_done runs a command (bash -c, in pi's cwd, output to a log file) and
fires when it exits, with its exit status; cancelling the alarm or ending
the session stops it. when_exits polls PIDs already running and fires once
all are gone. Either takes an optional deadline, 24 hours by default, at
which the alarm fires anyway and a still-running command is stopped.

A process exiting is a signal any condition can be turned into -- gh run
watch, sz-wait-for, an until-curl loop -- so the agent can start something
long, end its turn and be woken, instead of blocking on it. The delivery
path is the existing one, unchanged.

pi-subagent: §5 sets an alarm on the runs' PIDs instead of waiting.
</content>
</entry>
<entry>
<title>tmux: advertise OSC 8 hyperlinks so pi and other TUIs link under tmux</title>
<updated>2026-10-27T09:07:27+00:00</updated>
<author>
<name>Igor Soarez</name>
<email>igor@soarez.org</email>
</author>
<published>2026-10-27T09:07:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.soarez.net/sz/dot.git/commit/?id=1613e5d0316af273f050f60c12f0b4726051b70a'/>
<id>urn:sha1:1613e5d0316af273f050f60c12f0b4726051b70a</id>
<content type='text'>
</content>
</entry>
</feed>
