@agfpd/iapeer 0.4.21 → 0.4.22
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/CHANGELOG.md +17 -1
- package/package.json +1 -1
- package/src/cli/index.ts +16 -0
- package/src/transport/index.ts +27 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
10
10
|
|
|
11
11
|
## [Unreleased]
|
|
12
12
|
|
|
13
|
+
## [0.4.22] - 2026-06-22
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **`iapeer live-runtime <peer>`** — prints the peer's CURRENT live runtime: the
|
|
18
|
+
freshest-pane-log among its **pid-alive** supervisor sessions (a peer can be alive on
|
|
19
|
+
more than one runtime at once — a `/codex` flip can leave the old session running
|
|
20
|
+
alongside the new). This is the authoritative, real-time signal for "what runtime is
|
|
21
|
+
this peer running right now" — NOT `default_runtime` (only the wake-default) and NOT a
|
|
22
|
+
`.session` wake-record (alive-filtered only on a supervise-tick latency). Exit 0 + the
|
|
23
|
+
runtime on stdout when one is live; exit 1 + no output when none is alive. For external
|
|
24
|
+
consumers (e.g. telegram-runtime's typing/tool-use indicator) that must resolve the live
|
|
25
|
+
runtime of a peer running on a non-default runtime, instead of inferring it. Exposed as
|
|
26
|
+
`resolveLiveRuntime` (transport).
|
|
27
|
+
|
|
13
28
|
## [0.4.21] - 2026-06-22
|
|
14
29
|
|
|
15
30
|
### Fixed
|
|
@@ -325,7 +340,8 @@ Initial public release — the foundation core of the iapeer multi-agent ecosyst
|
|
|
325
340
|
- **Heterogeneous peers** — AI agents (Claude, Codex), humans (Telegram), and services
|
|
326
341
|
(timer = cron, watcher = event) are all first-class and addressed the same way.
|
|
327
342
|
|
|
328
|
-
[Unreleased]: https://github.com/agfpd/iapeer/compare/v0.4.
|
|
343
|
+
[Unreleased]: https://github.com/agfpd/iapeer/compare/v0.4.22...HEAD
|
|
344
|
+
[0.4.22]: https://github.com/agfpd/iapeer/compare/v0.4.21...v0.4.22
|
|
329
345
|
[0.4.21]: https://github.com/agfpd/iapeer/compare/v0.4.20...v0.4.21
|
|
330
346
|
[0.4.20]: https://github.com/agfpd/iapeer/compare/v0.4.19...v0.4.20
|
|
331
347
|
[0.4.19]: https://github.com/agfpd/iapeer/compare/v0.4.18...v0.4.19
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -1139,6 +1139,7 @@ const VERBS: ReadonlyArray<{ sig: string; desc: string }> = [
|
|
|
1139
1139
|
desc: 'backbone host-phase: marketplace → notifier → telegram (human peer) → memory → voice (all default YES). --accept-risk (or IAPEER_ACCEPT_RISK=1) accepts the security warning non-interactively',
|
|
1140
1140
|
},
|
|
1141
1141
|
{ sig: 'status', desc: 'host snapshot: version, daemon health, memory + voice slots (<provider> | none)' },
|
|
1142
|
+
{ sig: 'live-runtime <peer>', desc: 'print the peer\'s CURRENT live runtime (freshest pane-log among pid-alive sessions; NOT default_runtime). Exit 1 + no output if none alive' },
|
|
1142
1143
|
{ sig: 'install-runtime <runtime> [--package pkg] [--npx]', desc: 'npx-install a runtime package + deploy its declared peer-set' },
|
|
1143
1144
|
{ sig: 'update-runtime <runtime> | --all [--force]', desc: "version-gate → re-install + re-provision declared set → restart the runtime's peers" },
|
|
1144
1145
|
{ sig: 'init [cwd] [--runtime r] [--description d]', desc: 'onboard the CURRENT folder as a peer (name = folder name; identity + MCP + doctrine)' },
|
|
@@ -1501,6 +1502,21 @@ export async function runCli(argv: string[], env: NodeJS.ProcessEnv = process.en
|
|
|
1501
1502
|
out(formatHostStatus(s))
|
|
1502
1503
|
return s.daemon.healthy ? 0 : 1
|
|
1503
1504
|
}
|
|
1505
|
+
case 'live-runtime': {
|
|
1506
|
+
// The AUTHORITATIVE current live runtime of a peer (machine-readable, for external
|
|
1507
|
+
// consumers like telegram-runtime's typing indicator). Prints the runtime the peer
|
|
1508
|
+
// is RUNNING right now — the freshest-pane-log among its PID-alive supervisor
|
|
1509
|
+
// sessions — NOT default_runtime (the wake-default) and NOT a .session wake-record.
|
|
1510
|
+
// A peer can be alive on >1 runtime (a /codex flip leaves both); this picks the
|
|
1511
|
+
// currently-active. Exit 0 + the runtime on stdout when one is live; exit 1 + no
|
|
1512
|
+
// output when none is alive (queryable: `rt=$(iapeer live-runtime <p>) || handle-down`).
|
|
1513
|
+
if (!positionals[0]) return argErr(errOut, 'live-runtime needs a peer name — usage: iapeer live-runtime <peer>')
|
|
1514
|
+
const { resolveLiveRuntime } = await import('../transport/index.ts')
|
|
1515
|
+
const rt = resolveLiveRuntime(positionals[0])
|
|
1516
|
+
if (!rt) return 1 // no live session — no output, non-zero
|
|
1517
|
+
out(`${rt}\n`)
|
|
1518
|
+
return 0
|
|
1519
|
+
}
|
|
1504
1520
|
case 'install-runtime': {
|
|
1505
1521
|
// §6 onboard a runtime END-TO-END: npx-install the package (auto-resolved from
|
|
1506
1522
|
// the built-in runtime→package registry, or --package; self-deploys bin +
|
package/src/transport/index.ts
CHANGED
|
@@ -279,6 +279,33 @@ function defaultPaneLogMtime(address: string): number | null {
|
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
+
/**
|
|
283
|
+
* The CURRENT live runtime of a peer — the AUTHORITATIVE, real-time signal for "what
|
|
284
|
+
* runtime is this peer running right now" (NOT default_runtime, which is only the wake
|
|
285
|
+
* DEFAULT, and NOT a `.session` file, a wake-record cleaned on a supervise-tick latency).
|
|
286
|
+
*
|
|
287
|
+
* Resolution: among the peer's PID-ALIVE supervisor sessions (listHostedPeers — the same
|
|
288
|
+
* source delivery uses; `sessionAlive` = pidfile exists AND kill-0), pick the one with the
|
|
289
|
+
* FRESHEST pane-log. A peer can be alive on >1 runtime at once (a `/codex` flip can leave
|
|
290
|
+
* the old session running alongside the new), so the freshest-pane-log among the alive set
|
|
291
|
+
* is the currently-active surface. The alive-filter is what fixes the flip-race: a
|
|
292
|
+
* just-died runtime's pane-log / .sock / .session all LINGER, but its pid is dead → it is
|
|
293
|
+
* excluded here. Returns null when no session is alive.
|
|
294
|
+
*
|
|
295
|
+
* Deps are injectable for hermetic tests (the defaults read the real run-dir + pane-logs).
|
|
296
|
+
*/
|
|
297
|
+
export function resolveLiveRuntime(
|
|
298
|
+
personality: string,
|
|
299
|
+
deps: { aliveRuntimes?: (p: string) => string[]; paneLogMtime?: (address: string) => number | null } = {},
|
|
300
|
+
): string | null {
|
|
301
|
+
const aliveOf = deps.aliveRuntimes ?? ((p: string) => listHostedPeers().filter(h => h.personality === p).map(h => h.runtime))
|
|
302
|
+
const paneMt = deps.paneLogMtime ?? defaultPaneLogMtime
|
|
303
|
+
const alive = aliveOf(personality)
|
|
304
|
+
if (alive.length <= 1) return alive[0] ?? null
|
|
305
|
+
// >1 alive → the freshest pane-log mtime (the currently-rendering turn surface).
|
|
306
|
+
return alive.reduce((best, rt) => ((paneMt(`${rt}-${personality}`) ?? 0) > (paneMt(`${best}-${personality}`) ?? 0) ? rt : best))
|
|
307
|
+
}
|
|
308
|
+
|
|
282
309
|
|
|
283
310
|
// ─── Compact done gate (dialogue control must report FACT, not keystroke delivery) ──
|
|
284
311
|
|