@agfpd/iapeer 0.4.6 → 0.4.7

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
@@ -9,6 +9,12 @@
9
9
 
10
10
  iapeer keeps a team of AI agents, humans, and services on one host **always reachable — every one of them a single message away.** Each participant is a **peer**: a Claude Code or Codex CLI agent, a person on Telegram, or a scheduler/watcher service. Any agent reaches any other with one call — `send_to_peer(<name>, <text>)` — and a peer that is asleep is still reachable: the daemon wakes it and delivers. Agents on Claude and on Codex — different AI runtimes from different vendors — talk as equal peers; humans take part over Telegram, or directly in the terminal — attached to a peer's live session with `iapeer attach`.
11
11
 
12
+ <p align="center">
13
+ <img src=".github/assets/iapeer-pingpong.gif" width="800" alt="A person messages one peer on Telegram; heterogeneous peers (Claude + Codex) relay a baton over one protocol and report back to Telegram.">
14
+ <br>
15
+ <em>One Telegram message in → Claude and Codex peers pass a baton over the same protocol → a report back in Telegram.</em>
16
+ </p>
17
+
12
18
  ## How it works
13
19
 
14
20
  ```text
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agfpd/iapeer",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "Foundation core for the iapeer multi-agent ecosystem: identity, registry, storage, codec.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "agfpd",
@@ -134,9 +134,15 @@ export async function paneLogViewport(log: string, cols: number, rows: number, s
134
134
  * validated `composerOccupancyFromModel` (REUSED, not reimplemented). The hosted equivalent of
135
135
  * `targetComposerBlocksDelivery`'s capture-pane occupancy. @xterm loads dynamically here (flag-on
136
136
  * hosted only; the leaf `composerOccupancyFromModel` import is type-only at runtime, so the warm path
137
- * stays @xterm-free with the flip off). UNCERTAINTY → BUSY (true): a model-build failure mirrors the
138
- * tmux predicate's capture-fail-is-busy stance — prefer a false-busy hold over a false-free paste into
139
- * a human composer.
137
+ * stays @xterm-free with the flip off). UNREADABLE PANE-LOG → NOT busy (false): the hold exists ONLY to
138
+ * avoid clobbering VISIBLE human composer text; if the model can't be built there is NO observed text to
139
+ * protect. This deliberately does NOT mirror the tmux predicate's capture-fail-is-busy stance: tmux
140
+ * `capture-pane` fails ~only when the session is GONE (then the queue's session-token/alive check fails
141
+ * the job loudly), but a hosted pane-log can be absent/unreadable while the session is ALIVE (e.g. a
142
+ * long-lived session whose lifecycle pane-log was rotated/removed) — so "uncertainty → busy" would stall
143
+ * EVERY delivery to such a peer until the 120 s force-timeout, starving the core addressed-delivery
144
+ * feature. The narrow cost (no composer protection while the log is unreadable) is acceptable: a session
145
+ * actively being typed into is precisely one whose pane-log IS being written.
140
146
  *
141
147
  * NB (sequence): this is the DETECTION primitive. The end-to-end gate (attached-supervisor-
142
148
  * client + enqueue + host-aware drain) lands with the attach client in Ф0b-3 — until a human can
@@ -145,7 +151,7 @@ export async function paneLogViewport(log: string, cols: number, rows: number, s
145
151
  */
146
152
  export async function paneLogComposerOccupied(log: string, cols: number, rows: number, runtime: string): Promise<boolean> {
147
153
  const term = await loadPaneLogModel(log, cols, rows)
148
- if (!term) return true // uncertainty → busy: never paste into a maybe-occupied composer
154
+ if (!term) return false // unreadable pane-log → no observed human composer text → deliver, never stall (see JSDoc)
149
155
  const { composerOccupancyFromModel } = await import('../shadow/render.ts')
150
156
  return composerOccupancyFromModel(term, cols, rows, runtime)
151
157
  }