@ctliz/agent-intercom-pi 0.14.1 → 0.14.4
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 +20 -8
- package/cli-send.ts +41 -3
- package/package.json +1 -1
- package/skills/pi-intercom/SKILL.md +2 -0
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
## Pi 1.1 compatibility and codemode
|
|
21
21
|
|
|
22
|
-
Version 0.14.
|
|
22
|
+
Version 0.14.3 is tested with Pi 1.1.0. Version 0.14.0 was tested with Pi 1.0.0, and 0.13.0 with Pi 0.99.1. The development test baseline now uses Pi 1.1.0; host-provided Pi modules remain peer dependencies, not runtime dependencies. The existing protocol v4 broker, durable queues, acknowledgements, and cross-harness routing are unchanged.
|
|
23
23
|
|
|
24
24
|
Pi 1.0 defaults to fullscreen; set `tuiMode` to `"regular"` or launch with `--tui-mode regular` to retain terminal scrollback. Codemode's shorter declarations preserve Intercom's structured `{ ok, text, data }` results and team guidelines. To check tool existence in a script, use `"intercom_send" in tools`, not `typeof tools.intercom_send`, because unknown members now throw. Restart existing Pi processes to use a newly installed Pi version; `/reload` only reloads resources inside the running version.
|
|
25
25
|
|
|
@@ -41,9 +41,11 @@ Concurrent sends and independent asks are supported; do not create two unresolve
|
|
|
41
41
|
The package includes an `intercom-send` executable. Install the alias globally for a shell command, or run it without relying on Pi's private installation path:
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
npm exec --yes --package=@ctliz/
|
|
44
|
+
npm exec --yes --package=@ctliz/agent-intercom-pi@0.14.3 -- intercom-send worker 'Tests passed.'
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
The default command disconnects after delivery and cannot receive a later reply. For a shell handoff requiring an acknowledgement, use `intercom-send --wait-reply 60 worker 'Please acknowledge this task.'`. It keeps its independent identity connected until the first message from that recipient or the timeout, prints delivery and reply as separate JSON lines, and exits with code 2 if no reply arrives. The recipient can use either `send` or a correlated reply. For ongoing delegation, use a persistent Codex MCP/`coi` session so questions and completion reports remain reachable after the acknowledgement. Do not send a task from a temporary `IntercomClient` and immediately disconnect when you expect responses.
|
|
48
|
+
|
|
47
49
|
It prints one JSON result with `accepted`, `delivered`, `messageId`, and optional failure `code`/`reason`. Exit status is zero only for acknowledged delivery. It inherits the routing scope, but never inherits `PI_INTERCOM_SESSION_ID` or `AGENT_INTERCOM_SESSION_ID`: every invocation registers an independent sender, leaves running Pi sessions intact, and disconnects after sending. It is send-only; use the session tools for reply-tracked asks.
|
|
48
50
|
|
|
49
51
|
When a second runtime claims the same stable session ID, Intercom reports `SESSION_ID_IN_USE`, pauses automatic reconnect, and preserves the original owner. Switch to a different session, or release the duplicate owner and `/reload`. `intercom_status` exposes the conflict as structured data rather than silently treating it as a temporary outage. Updating this adapter does not require restarting a compatible v4 broker.
|
|
@@ -163,7 +165,18 @@ Each pi session that has `pi-intercom` loaded and enabled connects to a tiny loc
|
|
|
163
165
|
## Install
|
|
164
166
|
|
|
165
167
|
```bash
|
|
166
|
-
pi install npm:@ctliz/
|
|
168
|
+
pi install npm:@ctliz/agent-intercom-pi
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Starting with 0.14.3, `@ctliz/agent-intercom-pi` is the only npm release name. The legacy `@ctliz/pi-intercom` alias receives no new versions; its published history remains available. The 0.14.2 rename candidate was not published to npm. The GitHub repository and existing Git sources remain unchanged.
|
|
172
|
+
|
|
173
|
+
Existing `@ctliz/agent-intercom-pi` users do not need to switch packages. Update with `pi update npm:@ctliz/agent-intercom-pi`, then run `/reload` in open Pi sessions. If the configured source is pinned to a version, reinstall the unpinned source above to receive future update notifications.
|
|
174
|
+
|
|
175
|
+
If you installed the legacy alias, remove it before installing the supported name to avoid loading the same extension twice:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pi remove npm:@ctliz/pi-intercom
|
|
179
|
+
pi install npm:@ctliz/agent-intercom-pi
|
|
167
180
|
```
|
|
168
181
|
|
|
169
182
|
If you are coming from `connect.1`, read [Upgrading from `connect.1`](#upgrading-from-connect1-to-connect2) first — the package namespace changed and the two versions must not be installed side by side.
|
|
@@ -916,7 +929,7 @@ Use pi-messenger for multi-agent swarms working on a shared task. Use pi-interco
|
|
|
916
929
|
|
|
917
930
|
The `connect.1` tags, source commits, and published release assets are immutable and are not modified by this migration. Release notes may carry an explicit erratum, which corrects the description only and never moves a tag or replaces an asset.
|
|
918
931
|
|
|
919
|
-
|
|
932
|
+
The historical `connect.*` Git tags shown above remain available. For current Pi installations, use the npm package in [Install](#install).
|
|
920
933
|
|
|
921
934
|
## Limitations
|
|
922
935
|
|
|
@@ -939,10 +952,9 @@ git tag -a vX.Y.Z -m "vX.Y.Z"
|
|
|
939
952
|
git push origin vX.Y.Z
|
|
940
953
|
```
|
|
941
954
|
|
|
942
|
-
The release workflow verifies that the tag points into `main`, runs typecheck and
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
when a workflow is rerun.
|
|
955
|
+
The release workflow verifies that the tag points into `main` and the manifest name is `@ctliz/agent-intercom-pi`, runs typecheck and tests, publishes that one npm package with trusted OIDC provenance, and creates the GitHub Release. It does not publish or rewrite a second alias. Existing npm versions and GitHub Releases are skipped safely when a workflow is rerun.
|
|
956
|
+
|
|
957
|
+
The npm trusted publisher is configured on **`@ctliz/agent-intercom-pi`** for GitHub owner `ctliz`, repository `agent-intercom-pi`, workflow filename `release.yml`, with no environment name (this workflow does not use one). Authorization is package-specific. Changing this account-side setting requires npm package-owner access; a repository commit alone cannot grant it. The workflow uses OIDC without a placeholder registry token.
|
|
946
958
|
|
|
947
959
|
## License
|
|
948
960
|
|
package/cli-send.ts
CHANGED
|
@@ -2,18 +2,31 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { IntercomClient } from "./broker/client.ts";
|
|
3
3
|
import { spawnBrokerIfNeeded } from "./broker/spawn.ts";
|
|
4
4
|
import { loadConfig } from "./config.ts";
|
|
5
|
+
import type { Message, SessionInfo } from "./types.ts";
|
|
5
6
|
|
|
6
7
|
async function main(): Promise<void> {
|
|
7
|
-
const
|
|
8
|
+
const args = process.argv.slice(2);
|
|
9
|
+
let waitMs = 0;
|
|
10
|
+
if (args[0] === "--wait-reply") {
|
|
11
|
+
args.shift();
|
|
12
|
+
const seconds = Number(args.shift());
|
|
13
|
+
if (!Number.isFinite(seconds) || seconds <= 0 || seconds > 86400) {
|
|
14
|
+
throw new Error("--wait-reply requires a timeout in seconds (0 < seconds <= 86400)");
|
|
15
|
+
}
|
|
16
|
+
waitMs = seconds * 1000;
|
|
17
|
+
}
|
|
18
|
+
const [to, ...parts] = args;
|
|
8
19
|
const message = parts.join(" ");
|
|
9
20
|
if (!to?.trim() || !message.trim()) {
|
|
10
|
-
throw new Error("Usage: intercom-send <session-name-or-id> <message>");
|
|
21
|
+
throw new Error("Usage: intercom-send [--wait-reply <seconds>] <session-name-or-id> <message>");
|
|
11
22
|
}
|
|
12
23
|
const config = loadConfig();
|
|
13
24
|
if (!config.enabled) throw new Error("Intercom disabled");
|
|
14
25
|
await spawnBrokerIfNeeded(config.brokerCommand, config.brokerArgs);
|
|
15
26
|
const client = new IntercomClient();
|
|
27
|
+
const messageId = randomUUID();
|
|
16
28
|
const now = Date.now();
|
|
29
|
+
let timer: NodeJS.Timeout | undefined;
|
|
17
30
|
try {
|
|
18
31
|
// Never inherit the calling Pi's session ID or take over its mailbox.
|
|
19
32
|
await client.connect({
|
|
@@ -25,10 +38,35 @@ async function main(): Promise<void> {
|
|
|
25
38
|
lastActivity: now,
|
|
26
39
|
runtimeInstanceId: randomUUID(),
|
|
27
40
|
});
|
|
28
|
-
|
|
41
|
+
let reply: Promise<{ from: SessionInfo; message: Message } | null> | undefined;
|
|
42
|
+
let target = to;
|
|
43
|
+
if (waitMs) {
|
|
44
|
+
const sessions = await client.listSessions();
|
|
45
|
+
const matches = sessions.filter((session) => session.id === to || session.name?.toLowerCase() === to.toLowerCase());
|
|
46
|
+
if (matches.length !== 1) throw new Error(matches.length ? "Ambiguous target; use the session ID" : "Session not found");
|
|
47
|
+
target = matches[0]!.id;
|
|
48
|
+
reply = new Promise((resolve) => {
|
|
49
|
+
timer = setTimeout(() => resolve(null), waitMs);
|
|
50
|
+
client.on("message", (from: SessionInfo, incoming: Message, deliveryId: string) => {
|
|
51
|
+
if (from.id !== target || (incoming.replyTo && incoming.replyTo !== messageId)) return;
|
|
52
|
+
client.acknowledgeMessage(deliveryId);
|
|
53
|
+
resolve({ from, message: incoming });
|
|
54
|
+
});
|
|
55
|
+
client.once("disconnected", () => resolve(null));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const result = await client.send(target, { text: message, messageId, ...(waitMs ? { expectsReply: true } : {}) });
|
|
29
59
|
console.log(JSON.stringify({ messageId: result.id, ...result }));
|
|
30
60
|
if (!result.delivered) process.exitCode = 1;
|
|
61
|
+
else if (reply) {
|
|
62
|
+
const response = await reply;
|
|
63
|
+
console.log(JSON.stringify(response
|
|
64
|
+
? { type: "reply", ...response }
|
|
65
|
+
: { type: "reply_wait_failed", code: client.isConnected() ? "REPLY_TIMEOUT" : "DISCONNECTED", messageId: result.id }));
|
|
66
|
+
if (!response) process.exitCode = 2;
|
|
67
|
+
}
|
|
31
68
|
} finally {
|
|
69
|
+
clearTimeout(timer);
|
|
32
70
|
await client.disconnect();
|
|
33
71
|
}
|
|
34
72
|
}
|
package/package.json
CHANGED
|
@@ -91,6 +91,8 @@ A deferred ask has `ok: true` and `data.pending: true`; it is not a failure. Do
|
|
|
91
91
|
|
|
92
92
|
For shell notifications, use `intercom-send <session-name-or-id> <message>`. It registers an independent send-only identity and prints JSON; it does not take over the current Pi session or track replies.
|
|
93
93
|
|
|
94
|
+
For a shell handoff requiring an acknowledgement, use `intercom-send --wait-reply 60 <recipient> <message>` to keep the sender connected until the first response or timeout. Use a persistent agent session for ongoing questions and completion reports. A temporary sender that disconnects after delivery cannot receive replies; `Session not found` on the return path does not mean the original task was undelivered.
|
|
95
|
+
|
|
94
96
|
## Core Patterns
|
|
95
97
|
|
|
96
98
|
### Pattern 1: Planner-Worker Delegation
|