pi-link 0.1.15 → 0.1.17

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-link",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "WebSocket-based inter-terminal communication for Pi. Connect multiple Pi terminals over a local link network.",
5
5
  "author": "alvivar",
6
6
  "license": "MIT",
@@ -1,12 +1,14 @@
1
1
  ---
2
2
  name: pi-link-coordination
3
- description: Guidance for coordinating work across Pi terminals using pi-link. Use when delegating tasks, choosing between link_prompt and link_send, planning async vs sync work, batching parallel jobs, or avoiding busy/conflict patterns.
3
+ description: Guidance for coordinating work across Pi terminals using pi-link. Use when delegating tasks, choosing between link_prompt and link_send, planning async vs sync work, batching parallel jobs, managing a remote terminal's context with link_compact, or avoiding busy/conflict patterns.
4
4
  ---
5
5
 
6
6
  # Pi-Link Coordination
7
7
 
8
8
  How to coordinate work across Pi terminals via pi-link.
9
9
 
10
+ Each terminal is an independent agent: they share no memory or conversation history — link only passes messages and prompts between them. Anything a remote terminal needs — file paths, task state, expected output, where to send its callback — must be in the message itself.
11
+
10
12
  ---
11
13
 
12
14
  ## Tool Selection Rule
@@ -14,6 +16,7 @@ How to coordinate work across Pi terminals via pi-link.
14
16
  - Need the answer back now? → `link_prompt`
15
17
  - Need autonomous work done? → `link_send(triggerTurn: true)`
16
18
  - Need to notify only? → `link_send(triggerTurn: false)`
19
+ - Need to free a terminal's context? → `link_compact`
17
20
 
18
21
  ---
19
22
 
@@ -21,7 +24,9 @@ How to coordinate work across Pi terminals via pi-link.
21
24
 
22
25
  > After `link_send(triggerTurn: true)` to terminal X, do not `link_prompt` X until X sends a completion callback.
23
26
 
24
- Pick one mode per terminal per task. Mixing sync and async on the same terminal is the most common coordination failure.
27
+ The `DONE` / `BLOCKED` callback arrives as a normal later user message; treat that callback as the signal that it is safe to send a follow-up `link_prompt`.
28
+
29
+ Pick one mode per terminal per task. Mixing sync and async on the same terminal is a common coordination failure.
25
30
 
26
31
  ---
27
32
 
@@ -29,7 +34,7 @@ Pick one mode per terminal per task. Mixing sync and async on the same terminal
29
34
 
30
35
  ### `link_list`
31
36
 
32
- Returns connected terminals with names, live status (`idle`, `thinking`, `tool:<name>`), and working directory (cwd). Use before delegating when availability or path context is uncertain. Your own entry is marked `(you)` — use this to discover your link name when replying to broadcast tasks.
37
+ Returns connected terminals with names, live status (`idle`, `thinking`, `tool:<name>`), and working directory (cwd). Some terminals also report context usage as `45K/272K (17%)` — how full that window is: high usage means less room remaining, though a loaded terminal may also be the one already holding the relevant task state. Your own entry is marked `(you)` — use this to discover your link name when replying to broadcast tasks.
33
38
 
34
39
  Only currently connected terminals are visible. If a target is missing, it is offline; messages to offline terminals are not queued.
35
40
 
@@ -37,53 +42,50 @@ Only currently connected terminals are visible. If a target is missing, it is of
37
42
 
38
43
  Synchronous RPC. Send a prompt, wait for the response.
39
44
 
40
- - Fails immediately if target is missing, self, disconnects, or busy (local work or another remote prompt)
45
+ - Fails fast if the target is yourself, not connected, or busy (local work, another remote prompt, or compaction); a mid-wait disconnect resolves as an error
41
46
  - 90s inactivity timeout, 30min hard ceiling
42
- - Remote agent doesn't share your context — prompts must be self-contained
43
- - Include: goal, scope, constraints, output format, done condition
47
+ - Remote agent doesn't share your context — include enough detail to complete the task
44
48
 
45
49
  ### `link_send`
46
50
 
47
- Fire-and-forget. Send to one terminal or `to: "*"` to broadcast (excludes sender).
51
+ Fire-and-forget. Send to one terminal or `to: "*"` to broadcast to every other connected terminal; there is no exclusion filter. Sending to yourself is rejected. A send to a name that isn't connected fails with an error listing who _is_ connected — delivery failure is visible to the sender, not silent.
48
52
 
49
- Set `triggerTurn: true` to queue async work on the receiver. Delivery happens at turn boundaries: pending messages are batched and surface together when the receiver next becomes idle. The sender does **not** get the response back.
53
+ Set `triggerTurn: true` to queue async work on the receiver. The sender does **not** get an automatic response back.
50
54
 
51
- Batched callback shape: `[Link: N message(s) received]` then one or more `From "name":` / `content` blocks.
55
+ Delivery shape depends on the message's `triggerTurn`:
52
56
 
53
- **Callback contract for `triggerTurn: true`:** ask the receiver to reply via `link_send` with:
57
+ - **`triggerTurn: true`** messages go through the receiver's idle-gated inbox and surface at a turn boundary wrapped as `[Link: N message(s) received]` followed by one `From "name":` block per message. Multiple pending messages are batched into one turn.
58
+ - **`triggerTurn: false`** messages bypass the inbox and surface directly as raw content — no wrapper, no `From` block. The receiver sees only the message text, so the sender must include their own identity, task tag, or artifact paths in the body.
59
+
60
+ **Callback convention for `triggerTurn: true`:** the sender gets no automatic response, so ask the receiver to report back via `link_send(..., triggerTurn: true)` (which lands at a proper turn boundary with the wrapper intact). A useful convention:
54
61
 
55
62
  - `DONE` / `BLOCKED`
56
63
  - Output paths / artifacts created
57
- - Short result summary or next question
64
+ - Result summary or next question
65
+
66
+ Use `triggerTurn: false` for fire-and-forget status notifications only — when you don't need to act on the reply.
58
67
 
59
- Keep callbacks concise. Put long details in files and return the paths.
68
+ **Receiver rule:** If your turn opens with `[Link: N message(s) received]`, treat each `From "name":` block as assigned work. When done, send the sender a `DONE` / `BLOCKED` callback via `link_send(..., triggerTurn: true)` — unless the task says otherwise.
69
+
70
+ ### `link_compact`
71
+
72
+ Blocks until the target finishes compacting, then returns (3 min ceiling — the call then errors for you, though the target may still finish compacting on its own; check it before assuming failure). Ask another terminal to compact its context window into a summary, freeing space. `link_list` exposes context usage; `link_compact` is the lever when you decide a terminal should free context — and because the call only returns once compaction is done, you can immediately hand it more work with `link_send`/`link_prompt` (no sleep, no busy-bounce). Busy targets (mid-turn or already compacting) decline; retry when `link_list` shows them idle. You decide the threshold; pi-link just runs the compaction you ask for. Its optional `instructions` add an extra focus to that summary.
60
73
 
61
74
  ---
62
75
 
63
76
  ## Operating Constraints
64
77
 
65
78
  - **One remote prompt at a time per target.** Concurrent requests rejected as busy.
66
- - **No shared context.** Every remote prompt must be self-contained.
67
79
  - **Messages are ephemeral.** Offline terminals lose messages.
68
80
  - **Localhost only.** Same machine.
69
81
  - **Cwd is a hint, not proof.** Same cwd ≠ same workspace/branch/access. Use explicit paths; absolute when cwds differ or shared-root assumptions are unclear.
70
- - **Naming:** `role@domain` (e.g., `builder@pi-link`). Only talk to your own domain unless told otherwise.
82
+ - **Naming:** Link names are user-defined identities (often `role@domain`, e.g. `builder@pi-link`); the hub keeps them unique, suffixing collisions (`builder@pi-link-2`). Use `link_list` to confirm a target's exact name, and its cwd to tell similar-named terminals apart.
71
83
 
72
84
  ---
73
85
 
74
- ## Coordination Modes
75
-
76
- ### Sync ask — `link_prompt`
77
-
78
- For answers, review, analysis you need back now. One terminal at a time. Keep scope focused to avoid timeout.
86
+ ## Parallel batch
79
87
 
80
- ### Async delegate — `link_send(triggerTurn: true)`
81
-
82
- For autonomous work. Require the callback contract (DONE/BLOCKED + paths + short summary). Do your own work in parallel. Expect the callback at a turn boundary, possibly batched with others. Don't `link_prompt` the target until the callback arrives.
83
-
84
- ### Parallel batch — async to multiple terminals
85
-
86
- Distribute independent tasks. Worker callbacks may return together in one batched turn when you become idle. Use explicit paths (absolute if cwds differ), require short callbacks + artifact paths, wait for all callbacks, then synthesize. Don't prompt any dispatched terminal until its callback arrives.
88
+ `link_send(triggerTurn: true)` can dispatch independent tasks to several terminals at once. Their callbacks may arrive separately or batched into one turn when you next become idle — track which workers are still outstanding. Each task must be self-contained (explicit paths, absolute if cwds differ). Don't `link_prompt` a dispatched terminal until its callback arrives (Golden Rule).
87
89
 
88
90
  ---
89
91
 
@@ -92,32 +94,21 @@ Distribute independent tasks. Worker callbacks may return together in one batche
92
94
  **❌ Mixing async and sync on the same terminal**
93
95
  Dispatched with `link_send(triggerTurn: true)` then sent a `link_prompt` → rejected as busy. See Golden Rule.
94
96
 
95
- **❌ Using `link_send` when you need the response now**
96
- No direct response comes back to the sender. Use `link_prompt` when you need the answer in the same turn.
97
-
98
- **❌ Vague prompts**
99
- "Fix the bug" is useless. Include file, line, root cause, expected fix.
100
-
101
97
  **❌ No completion callback on async work**
102
- Always require DONE/BLOCKED + artifact paths + short summary.
98
+ `triggerTurn: true` returns no result to the sender — without an agreed callback you never learn the outcome.
103
99
 
104
100
  **❌ Circular delegation**
105
- A → B → C → A = deadlock. Maintain clear hierarchy.
106
-
107
- **❌ Skipping `link_list` before retrying a busy target**
108
- Check status before re-sending.
109
-
110
- **❌ Long async callbacks**
111
- Long callbacks crowd a whole batched turn. Ask workers to write detailed output to files and return paths + short summaries.
101
+ A → B → C → A won't complete — the cycle-closing `link_prompt` hits a busy target (rejected), and an async `link_send` cycle just loops. Keep delegation acyclic.
112
102
 
113
103
  ---
114
104
 
115
105
  ## Quick Reference
116
106
 
117
- | I need to... | Tool | Mode |
118
- | -------------------------------- | ------------------------------- | --------------- |
119
- | See who's available | `link_list` | — |
120
- | Get an answer from another agent | `link_prompt` | Synchronous |
121
- | Delegate autonomous work | `link_send(triggerTurn: true)` | Asynchronous |
122
- | Notify without activating | `link_send(triggerTurn: false)` | Fire-and-forget |
123
- | Broadcast to all | `link_send(to: "*")` | Broadcast |
107
+ | I need to... | Tool | Mode |
108
+ | -------------------------------- | ------------------------------- | ---------------- |
109
+ | See who's available | `link_list` | — |
110
+ | Get an answer from another agent | `link_prompt` | Synchronous |
111
+ | Delegate autonomous work | `link_send(triggerTurn: true)` | Asynchronous |
112
+ | Notify without activating | `link_send(triggerTurn: false)` | Fire-and-forget |
113
+ | Broadcast to all | `link_send(to: "*")` | Broadcast |
114
+ | Free a loaded worker's context | `link_compact` | Await-completion |