@ctliz/agent-intercom-claude 0.14.0 → 0.15.0
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/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +10 -0
- package/README.md +17 -10
- package/broker/broker.ts +3 -2
- package/broker/client.ts +5 -2
- package/claude/inbox.ts +3 -1
- package/claude/mcp-protocol.ts +31 -9
- package/claude/named-team-membership.ts +124 -0
- package/claude/named-teams.ts +11 -0
- package/claude/native-bridge.ts +13 -4
- package/claude/reply-context.ts +49 -0
- package/claude/runtime.ts +45 -31
- package/claude/server.ts +2 -1
- package/claude/team-guidance.ts +7 -0
- package/claude/worker-daemon.ts +4 -0
- package/commands/intercom-create.md +4 -2
- package/commands/intercom-join.md +1 -1
- package/dist/broker.mjs +3 -2
- package/dist/cci.mjs +23 -8
- package/dist/ccim.mjs +23 -8
- package/dist/claude-server.mjs +244 -85
- package/dist/inbox-monitor.mjs +2 -1
- package/dist/worker-daemon.mjs +11 -5
- package/package.json +1 -1
- package/skills/claude-intercom/SKILL.md +5 -5
- package/types.ts +1 -0
package/dist/worker-daemon.mjs
CHANGED
|
@@ -1190,14 +1190,15 @@ function isMessage(value) {
|
|
|
1190
1190
|
}
|
|
1191
1191
|
if (message.replyTo !== void 0 || message.expectsReply !== void 0) return false;
|
|
1192
1192
|
}
|
|
1193
|
-
if (!hasExactDataKeys(message.content, ["text"], ["attachments"])) {
|
|
1193
|
+
if (!hasExactDataKeys(message.content, ["text"], ["attachments", "team"])) {
|
|
1194
1194
|
return false;
|
|
1195
1195
|
}
|
|
1196
1196
|
const content = message.content;
|
|
1197
1197
|
if (typeof content.text !== "string") {
|
|
1198
1198
|
return false;
|
|
1199
1199
|
}
|
|
1200
|
-
if (
|
|
1200
|
+
if (content.team !== void 0 && (typeof content.team !== "string" || !/^[A-Za-z][A-Za-z0-9_-]{0,31}$/.test(content.team))) return false;
|
|
1201
|
+
if (message.control !== void 0 && (content.text !== "" || content.attachments !== void 0 || content.team !== void 0)) return false;
|
|
1201
1202
|
return content.attachments === void 0 || isDenseArrayOf(content.attachments, isAttachment);
|
|
1202
1203
|
}
|
|
1203
1204
|
function isSessionInfo(value) {
|
|
@@ -1820,6 +1821,7 @@ var IntercomClient = class extends EventEmitter {
|
|
|
1820
1821
|
...options.control === void 0 ? {} : { control: options.control },
|
|
1821
1822
|
content: {
|
|
1822
1823
|
text: options.text,
|
|
1824
|
+
...options.team === void 0 ? {} : { team: options.team },
|
|
1823
1825
|
...options.attachments === void 0 ? {} : { attachments: options.attachments }
|
|
1824
1826
|
}
|
|
1825
1827
|
};
|
|
@@ -2479,6 +2481,7 @@ ${agent.instructions}` : "";
|
|
|
2479
2481
|
return [
|
|
2480
2482
|
`Intercom message for ${agent.name}.`,
|
|
2481
2483
|
`From: ${formatSessionDisplay(from)} (${from.id})`,
|
|
2484
|
+
...message.content.team ? [`[Team: ${message.content.team}]`] : [],
|
|
2482
2485
|
`Message id: ${message.id}`,
|
|
2483
2486
|
"",
|
|
2484
2487
|
message.content.text,
|
|
@@ -2631,7 +2634,8 @@ var VirtualClaudeAgent = class {
|
|
|
2631
2634
|
if (message.expectsReply) {
|
|
2632
2635
|
void this.client.send(from.id, {
|
|
2633
2636
|
text: "This worker is rate limited (too many wakes this minute). Please try again shortly.",
|
|
2634
|
-
replyTo: message.id
|
|
2637
|
+
replyTo: message.id,
|
|
2638
|
+
...message.content.team === void 0 ? {} : { team: message.content.team }
|
|
2635
2639
|
}).catch((error) => {
|
|
2636
2640
|
process.stderr.write(`worker ${this.agent.id}: rate-limit reply failed: ${error instanceof Error ? error.message : String(error)}
|
|
2637
2641
|
`);
|
|
@@ -2693,7 +2697,8 @@ var VirtualClaudeAgent = class {
|
|
|
2693
2697
|
if (message.expectsReply) {
|
|
2694
2698
|
await this.client.send(from.id, {
|
|
2695
2699
|
text: result.result || "(the worker finished without a final message)",
|
|
2696
|
-
replyTo: message.id
|
|
2700
|
+
replyTo: message.id,
|
|
2701
|
+
...message.content.team === void 0 ? {} : { team: message.content.team }
|
|
2697
2702
|
});
|
|
2698
2703
|
process.stderr.write(`worker ${this.agent.id}: replied to ${from.name || from.id} (session ${this.sessionId ?? "none"})
|
|
2699
2704
|
`);
|
|
@@ -2705,7 +2710,8 @@ var VirtualClaudeAgent = class {
|
|
|
2705
2710
|
if (message.expectsReply) {
|
|
2706
2711
|
await this.client.send(from.id, {
|
|
2707
2712
|
text: `Worker error: ${text}`,
|
|
2708
|
-
replyTo: message.id
|
|
2713
|
+
replyTo: message.id,
|
|
2714
|
+
...message.content.team === void 0 ? {} : { team: message.content.team }
|
|
2709
2715
|
}).catch((sendError) => {
|
|
2710
2716
|
process.stderr.write(`worker ${this.agent.id}: error reply failed: ${sendError instanceof Error ? sendError.message : String(sendError)}
|
|
2711
2717
|
`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ctliz/agent-intercom-claude",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Claude Code MCP plugin and wakeable worker for local messaging with Pi, Codex, OpenCode, Grok Build, and AGY agents.",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"type": "module",
|
|
@@ -29,8 +29,8 @@ proxy-backed Claude profiles; `ccim` safe mode intentionally does not.
|
|
|
29
29
|
## Tools
|
|
30
30
|
|
|
31
31
|
- `intercom_whoami`: show this session's intercom ID, name, cwd, and model.
|
|
32
|
-
- `intercom_team`:
|
|
33
|
-
- `intercom_join`: list, join, or create
|
|
32
|
+
- `intercom_team({ team? })`: inspect one task team or list all memberships; falls back to managed-team discovery.
|
|
33
|
+
- `intercom_join({ name?, create?, members?, work? })`: list, join, or create an additive task team; the manager adds connected peers in one call.
|
|
34
34
|
- `intercom_status`: connection, active session count, unread messages, pending asks.
|
|
35
35
|
- `intercom_list`: list connected Pi, Codex, and Claude sessions.
|
|
36
36
|
- `intercom_set_summary`: publish a short discoverable status.
|
|
@@ -43,8 +43,8 @@ proxy-backed Claude profiles; `ccim` safe mode intentionally does not.
|
|
|
43
43
|
|
|
44
44
|
1. Call `intercom_status` or `intercom_whoami` to confirm this session is connected.
|
|
45
45
|
2. Call `intercom_set_summary` with a concise status so peers can discover your role.
|
|
46
|
-
3.
|
|
47
|
-
4. Use `intercom_send` for non-blocking updates and handoffs.
|
|
46
|
+
3. When the user delegates to named peers and this task has no approved team, ask once whether to form a team with you and those peers. Wait for approval. An explicit create/join request is approval; never ask again for an approved task or inbound team message. After approval, discover peers and call `intercom_join({ name: "billing", create: true, members: ["front", "writer"], work: "Current task" })`. Do not ask the user to join each terminal manually. Reuse the approved team for the same task; new tasks may need new teams. Joining preserves all previous memberships and each team's manager/member roles.
|
|
47
|
+
4. Use `intercom_send` for non-blocking updates and handoffs. Include `team` for task messages, especially when multiple teams are shared. Without a shared team, omit `team` for initial ungrouped contact; unrelated memberships do not block contact or silently create teams.
|
|
48
48
|
5. Use `intercom_ask` only when you need the answer before continuing. Assignments, progress/status checkpoints, notifications, and completion reports use `intercom_send`.
|
|
49
49
|
6. Call `intercom_pending` before ending a coordination turn, then answer blocking asks with `intercom_reply`.
|
|
50
50
|
|
|
@@ -75,7 +75,7 @@ intercom_pending({ mark_read: false })
|
|
|
75
75
|
intercom_reply({ message: "Use GET/PUT/DELETE only, max 3 retries." })
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
Replies inherit the original message's team, never a mutable current team. Prefer `askId` or `contextId` returned by `intercom_pending` (contextId also selects ordinary messages). Mixed-team pending contexts require explicit selection; `team` cannot override the original. Within one task, `to` plus `oldest`/`latest` also selects an ask:
|
|
79
79
|
|
|
80
80
|
```typescript
|
|
81
81
|
intercom_reply({ to: "planner", which: "oldest", message: "Proceed." })
|