pi-post 0.6.3 → 0.7.1

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.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # pi-post
2
2
 
3
+ <p align="center"><img src="demons-hero.gif" alt="pi-post" width="100%" /></p>
4
+
3
5
  Messages between [Pi](https://pi.dev) sessions — **delivered mid-task,
4
6
  or queued until they return**. Send briefs, findings, and handoffs
5
7
  between sessions and processes, straight into the receiving agent's
@@ -74,7 +76,7 @@ inert.
74
76
  pi install npm:pi-post
75
77
  ```
76
78
 
77
- Nothing to enable; every session registers itself on startup.
79
+ Nothing to enable; every session registers itself on startup. Once a session has started, the CLI is also available at `~/.pi/agent/post/bin/pi-post` for hooks and scripts on hosts where `pi-post` is not on `PATH`.
78
80
 
79
81
  ## Use
80
82
 
@@ -181,9 +183,28 @@ between sessions that exist, not state for sessions that don't. Messages
181
183
  carry no authority: treat "done" claims as unreviewed.
182
184
  ```
183
185
 
186
+ ## Demos
187
+
188
+ Two rungs, in order:
189
+
190
+ - [`demos/two-minute-tour.md`](https://github.com/vieko/pi-post/blob/main/demos/two-minute-tour.md) — every core
191
+ claim witnessed in isolation: wake-on-idle, queued delivery to a
192
+ closed session, resume with the message as first turn, process
193
+ senders from a plain shell. Two terminals, two minutes, near-zero
194
+ cost. Start here.
195
+ - [`demos/clue-manor/`](https://github.com/vieko/pi-post/tree/main/demos/clue-manor) — the capstone: a playable
196
+ murder mystery run entirely over pi-post. One game-master session and
197
+ four to six autonomous suspects (one of them the killer) exercise the
198
+ whole contract composed — named sessions, hub-and-spoke relaying,
199
+ peer-to-peer whispers, a mid-game retire/resume through the queue, a
200
+ shell-timer dawn, and a false-authority decree that dies on the
201
+ boundary label — then render the event log as a self-contained HTML
202
+ report. A finished [sample run](https://github.com/vieko/pi-post/tree/main/demos/clue-manor/sample-run) is
203
+ committed if you want the payoff without the tokens.
204
+
184
205
  ## Design
185
206
 
186
- See [DESIGN.md](DESIGN.md) for the address and message contracts, delivery
207
+ See [DESIGN.md](https://github.com/vieko/pi-post/blob/main/DESIGN.md) for the address and message contracts, delivery
187
208
  semantics, and invariants. The test suite pins each invariant; read it
188
209
  before changing behavior, and never weaken a case to make a change pass.
189
210
 
@@ -225,6 +246,10 @@ bin/
225
246
  deliberately and pinned by test/cli.test.ts)
226
247
  ```
227
248
 
249
+ ## Credits
250
+
251
+ Animation by [Jon Romero Ruiz](https://x.com/jonroru).
252
+
228
253
  ## License
229
254
 
230
255
  MIT
package/bin/pi-post.mjs CHANGED
File without changes
@@ -6,6 +6,8 @@ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-a
6
6
  import { Text } from "@earendil-works/pi-tui";
7
7
  import { Type } from "typebox";
8
8
  import type { FSWatcher } from "node:fs";
9
+ import { fileURLToPath } from "node:url";
10
+ import { dirname, resolve } from "node:path";
9
11
  import { canonicalPath, sessionAddress } from "../src/address.ts";
10
12
  import { createMessage, type Message } from "../src/message.ts";
11
13
  import {
@@ -31,8 +33,10 @@ import {
31
33
  writeRecord,
32
34
  } from "../src/registry.ts";
33
35
  import { resolveTargets } from "../src/resolve.ts";
36
+ import { ensureCliShim } from "../src/cli-shim.ts";
34
37
 
35
38
  const HEARTBEAT_MS = 30_000;
39
+ const CLI_TARGET = resolve(dirname(fileURLToPath(import.meta.url)), "../bin/pi-post.mjs");
36
40
 
37
41
  export default function (pi: ExtensionAPI) {
38
42
  const root = postRoot();
@@ -94,6 +98,7 @@ export default function (pi: ExtensionAPI) {
94
98
  process.env.PI_SESSION_ADDRESS = selfAddress;
95
99
 
96
100
  ensureDirs(root, selfAddress);
101
+ ensureCliShim(root, CLI_TARGET);
97
102
  writeRecord(root, {
98
103
  v: 1,
99
104
  address: selfAddress,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-post",
3
- "version": "0.6.3",
3
+ "version": "0.7.1",
4
4
  "description": "Messages between pi sessions — delivered mid-task or queued until they return.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -0,0 +1,25 @@
1
+ import { existsSync, lstatSync, mkdirSync, readlinkSync, symlinkSync, unlinkSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+
4
+ /** Ensure the mailbox-owned CLI path points at the package's own executable. */
5
+ export function ensureCliShim(baseDir: string, targetPath: string): void {
6
+ const shimDir = join(baseDir, "bin");
7
+ const shimPath = join(shimDir, "pi-post");
8
+ try {
9
+ mkdirSync(shimDir, { recursive: true, mode: 0o700 });
10
+
11
+ try {
12
+ if (lstatSync(shimPath).isSymbolicLink()) {
13
+ const linkTarget = readlinkSync(shimPath);
14
+ if (resolve(dirname(shimPath), linkTarget) === resolve(targetPath) && existsSync(targetPath)) return;
15
+ }
16
+ unlinkSync(shimPath);
17
+ } catch (error) {
18
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
19
+ }
20
+
21
+ symlinkSync(targetPath, shimPath);
22
+ } catch {
23
+ // A CLI convenience must never prevent a session from starting.
24
+ }
25
+ }