@spoons-and-mirrors/iam 0.1.0 → 0.1.1

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
@@ -4,24 +4,27 @@ Inter-agent messaging for parallel subagents.
4
4
 
5
5
  ## The `iam` Tool
6
6
 
7
- | Action | Args | Description |
8
- |--------|------|-------------|
9
- | `sessions` | - | List agents you can message |
7
+ | Action | Parameters | Description |
8
+ |--------|------------|-------------|
9
+ | `announce` | `message` | Announce what you're working on |
10
+ | `sessions` | - | List agents and what they're working on |
10
11
  | `read` | - | Read your messages (marks as read) |
11
- | `write` | `--to <id> --message "..."` | Send a message |
12
+ | `write` | `to`, `message` | Send a message |
12
13
 
13
14
  ## Examples
14
15
 
15
- ```bash
16
- iam sessions
17
- iam read
18
- iam write --to ses_abc123 --message "What approach are you using?"
16
+ ```
17
+ iam(action="announce", message="Implementing user authentication")
18
+ iam(action="sessions")
19
+ iam(action="read")
20
+ iam(action="write", to="agentA", message="What approach are you using?")
19
21
  ```
20
22
 
21
23
  ## How It Works
22
24
 
23
25
  - **In-memory** - fast, no file clutter, resets on restart
24
26
  - **Auto-discovery** - agents register on first iam use, see each other immediately
27
+ - **Simple aliases** - agents get friendly names (agentA, agentB, ...) instead of session IDs
25
28
  - **Urgent alerts** - recipients get `<system-reminder>` when they have unread mail
26
29
 
27
30
  ## Files
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AA0GjD,QAAA,MAAM,MAAM,EAAE,MAwIb,CAAA;AAED,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAiJjD,QAAA,MAAM,MAAM,EAAE,MAmKb,CAAA;AAED,eAAe,MAAM,CAAA"}
package/dist/index.js CHANGED
@@ -5,13 +5,14 @@ import { tool } from "@opencode-ai/plugin";
5
5
  var TOOL_DESCRIPTION = `Inter-agent messaging. Use this to communicate with other parallel agents (task tools).
6
6
 
7
7
  Actions:
8
- - "sessions": Show session IDs of agents you can message
8
+ - "sessions": Show agents you can message (e.g., agentA, agentB)
9
9
  - "read": Read all your messages (marks them as read)
10
- - "write": Send a message to another agent`;
10
+ - "write": Send a message (requires 'to' and 'message' parameters)
11
+ - "announce": Announce what you're working on (requires 'message' parameter)`;
11
12
  var ARG_DESCRIPTIONS = {
12
13
  action: "Action to perform",
13
- to: "Recipient session ID (required for 'write')",
14
- message: "Message content (required for 'write')"
14
+ to: "Recipient agent name, e.g. 'agentA' (required for 'write')",
15
+ message: "Message content (required for 'write'), or self-description (required for 'announce')"
15
16
  };
16
17
  var SESSIONS_EMPTY = `No other agents available yet.
17
18
 
@@ -19,18 +20,23 @@ Agents will appear here when:
19
20
  - Parallel tasks are spawned by the same parent
20
21
  - Another agent sends you a message`;
21
22
  function sessionsResult(agents) {
22
- return [
23
- `Agents you can message:
24
- `,
25
- ...agents.map((id) => `- ${id}`),
26
- ``,
27
- `Use: iam write --to <session_id> --message "..."`
28
- ].join(`
23
+ const lines = [`Agents you can message:
24
+ `];
25
+ for (const agent of agents) {
26
+ if (agent.description) {
27
+ lines.push(`- ${agent.alias}: ${agent.description}`);
28
+ } else {
29
+ lines.push(`- ${agent.alias}`);
30
+ }
31
+ }
32
+ lines.push(``);
33
+ lines.push(`To send: use action="write" with to="<agent>" and message="..."`);
34
+ return lines.join(`
29
35
  `);
30
36
  }
31
- var READ_EMPTY = `No messages in your iam.`;
37
+ var READ_EMPTY = `No messages in your IAM inbox.`;
32
38
  function readResult(messages, unreadCount) {
33
- const lines = [`Your iam (${unreadCount} were unread):
39
+ const lines = [`Your IAM inbox (${unreadCount} were unread):
34
40
  `, `---`];
35
41
  for (const msg of messages) {
36
42
  const time = new Date(msg.timestamp).toISOString();
@@ -40,12 +46,22 @@ function readResult(messages, unreadCount) {
40
46
  lines.push(`---`);
41
47
  }
42
48
  lines.push(``);
43
- lines.push(`To reply: iam write --to <sender_session_id> --message "..."`);
49
+ lines.push(`To reply: use action="write" with to="<sender>" and message="..."`);
44
50
  return lines.join(`
45
51
  `);
46
52
  }
47
- var WRITE_MISSING_TO = `Error: 'to' is required. Use: iam write --to <session_id> --message "..."`;
48
- var WRITE_MISSING_MESSAGE = `Error: 'message' is required. Use: iam write --to <session_id> --message "..."`;
53
+ var WRITE_MISSING_TO = `Error: 'to' parameter is required for action="write".`;
54
+ var WRITE_MISSING_MESSAGE = `Error: 'message' parameter is required for action="write".`;
55
+ var ANNOUNCE_MISSING_MESSAGE = `Error: 'message' parameter is required for action="announce". Describe what you're working on.`;
56
+ function announceResult(alias) {
57
+ return `Announced! Other agents will see your description when they list sessions.
58
+
59
+ You are: ${alias}`;
60
+ }
61
+ function writeUnknownRecipient(to, known) {
62
+ const list = known.length > 0 ? `Known agents: ${known.join(", ")}` : "No agents available yet.";
63
+ return `Error: Unknown recipient "${to}". ${list}`;
64
+ }
49
65
  function writeResult(to, messageId) {
50
66
  return `Message sent!
51
67
 
@@ -58,21 +74,25 @@ function unknownAction(action) {
58
74
  return `Unknown action: ${action}`;
59
75
  }
60
76
  var SYSTEM_PROMPT = `
77
+ <instructions tool="iam">
61
78
  # Inter-Agent Messaging
62
79
 
63
80
  You have access to an \`iam\` tool for communicating with other parallel agents.
64
81
 
65
- Commands:
66
- - \`iam sessions\` - See agents you can message
67
- - \`iam read\` - Read all your messages
68
- - \`iam write --to <session_id> --message "..."\` - Send a message
82
+ Usage:
83
+ - action="announce", message="..." - Announce what you're working on (do this first!)
84
+ - action="sessions" - See other agents and what they're working on
85
+ - action="read" - Read your messages
86
+ - action="write", to="agentA", message="..." - Send a message
69
87
 
70
- Check your iam when notified about new messages.
88
+ At the start of your task, use announce to let other agents know what you're doing.
89
+ Check your inbox when notified about new messages.
90
+ </instructions>
71
91
  `;
72
92
  function urgentNotification(unreadCount) {
73
93
  return `<system-reminder priority="critical">
74
- URGENT: You have ${unreadCount} unread message(s) in your iam.
75
- Use \`iam read\` NOW to check your messages before continuing other work.
94
+ URGENT: You have ${unreadCount} unread message(s) in your IAM inbox.
95
+ Use the iam tool with action="read" NOW to check your messages before continuing other work.
76
96
  </system-reminder>`;
77
97
  }
78
98
 
@@ -116,6 +136,30 @@ var LOG = {
116
136
  // index.ts
117
137
  var inboxes = new Map;
118
138
  var activeSessions = new Set;
139
+ var sessionToAlias = new Map;
140
+ var aliasToSession = new Map;
141
+ var agentDescriptions = new Map;
142
+ var nextAgentIndex = 0;
143
+ function getNextAlias() {
144
+ const letter = String.fromCharCode(65 + nextAgentIndex % 26);
145
+ const suffix = nextAgentIndex >= 26 ? Math.floor(nextAgentIndex / 26).toString() : "";
146
+ nextAgentIndex++;
147
+ return `agent${letter}${suffix}`;
148
+ }
149
+ function getAlias(sessionId) {
150
+ return sessionToAlias.get(sessionId) || sessionId;
151
+ }
152
+ function setDescription(sessionId, description) {
153
+ const alias = getAlias(sessionId);
154
+ agentDescriptions.set(alias, description);
155
+ log.info(LOG.SESSION, `Agent announced`, { alias, description });
156
+ }
157
+ function getDescription(alias) {
158
+ return agentDescriptions.get(alias);
159
+ }
160
+ function resolveAlias(aliasOrSessionId) {
161
+ return aliasToSession.get(aliasOrSessionId) || (activeSessions.has(aliasOrSessionId) ? aliasOrSessionId : undefined);
162
+ }
119
163
  function generateId() {
120
164
  return Math.random().toString(36).substring(2, 10);
121
165
  }
@@ -156,7 +200,7 @@ function getKnownAgents(sessionId) {
156
200
  const agents = [];
157
201
  for (const id of activeSessions) {
158
202
  if (id !== sessionId) {
159
- agents.push(id);
203
+ agents.push(getAlias(id));
160
204
  }
161
205
  }
162
206
  return agents;
@@ -164,7 +208,10 @@ function getKnownAgents(sessionId) {
164
208
  function registerSession(sessionId) {
165
209
  if (!activeSessions.has(sessionId)) {
166
210
  activeSessions.add(sessionId);
167
- log.info(LOG.SESSION, `Session registered`, { sessionId, totalSessions: activeSessions.size });
211
+ const alias = getNextAlias();
212
+ sessionToAlias.set(sessionId, alias);
213
+ aliasToSession.set(alias, sessionId);
214
+ log.info(LOG.SESSION, `Session registered`, { sessionId, alias, totalSessions: activeSessions.size });
168
215
  }
169
216
  }
170
217
  var plugin = async () => {
@@ -174,7 +221,7 @@ var plugin = async () => {
174
221
  iam: tool({
175
222
  description: TOOL_DESCRIPTION,
176
223
  args: {
177
- action: tool.schema.enum(["sessions", "read", "write"]).describe(ARG_DESCRIPTIONS.action),
224
+ action: tool.schema.enum(["sessions", "read", "write", "announce"]).describe(ARG_DESCRIPTIONS.action),
178
225
  to: tool.schema.string().optional().describe(ARG_DESCRIPTIONS.to),
179
226
  message: tool.schema.string().optional().describe(ARG_DESCRIPTIONS.message)
180
227
  },
@@ -189,7 +236,11 @@ var plugin = async () => {
189
236
  if (agents.length === 0) {
190
237
  return SESSIONS_EMPTY;
191
238
  }
192
- return sessionsResult(agents);
239
+ const agentsWithDesc = agents.map((alias) => ({
240
+ alias,
241
+ description: getDescription(alias)
242
+ }));
243
+ return sessionsResult(agentsWithDesc);
193
244
  }
194
245
  case "read": {
195
246
  const messages = getAllMessages(sessionId);
@@ -210,9 +261,24 @@ var plugin = async () => {
210
261
  log.warn(LOG.TOOL, `write missing 'message'`, { sessionId });
211
262
  return WRITE_MISSING_MESSAGE;
212
263
  }
213
- const msg = sendMessage(sessionId, args.to, args.message);
264
+ const recipientSessionId = resolveAlias(args.to);
265
+ if (!recipientSessionId) {
266
+ log.warn(LOG.TOOL, `write unknown recipient`, { sessionId, to: args.to });
267
+ return writeUnknownRecipient(args.to, getKnownAgents(sessionId));
268
+ }
269
+ const senderAlias = getAlias(sessionId);
270
+ const msg = sendMessage(senderAlias, recipientSessionId, args.message);
214
271
  return writeResult(args.to, msg.id);
215
272
  }
273
+ case "announce": {
274
+ if (!args.message) {
275
+ log.warn(LOG.TOOL, `announce missing 'message'`, { sessionId });
276
+ return ANNOUNCE_MISSING_MESSAGE;
277
+ }
278
+ setDescription(sessionId, args.message);
279
+ const alias = getAlias(sessionId);
280
+ return announceResult(alias);
281
+ }
216
282
  default:
217
283
  return unknownAction(args.action);
218
284
  }
package/dist/prompt.d.ts CHANGED
@@ -1,22 +1,28 @@
1
- export declare const TOOL_DESCRIPTION = "Inter-agent messaging. Use this to communicate with other parallel agents (task tools).\n\nActions:\n- \"sessions\": Show session IDs of agents you can message\n- \"read\": Read all your messages (marks them as read)\n- \"write\": Send a message to another agent";
1
+ export declare const TOOL_DESCRIPTION = "Inter-agent messaging. Use this to communicate with other parallel agents (task tools).\n\nActions:\n- \"sessions\": Show agents you can message (e.g., agentA, agentB)\n- \"read\": Read all your messages (marks them as read)\n- \"write\": Send a message (requires 'to' and 'message' parameters)\n- \"announce\": Announce what you're working on (requires 'message' parameter)";
2
2
  export declare const ARG_DESCRIPTIONS: {
3
3
  readonly action: "Action to perform";
4
- readonly to: "Recipient session ID (required for 'write')";
5
- readonly message: "Message content (required for 'write')";
4
+ readonly to: "Recipient agent name, e.g. 'agentA' (required for 'write')";
5
+ readonly message: "Message content (required for 'write'), or self-description (required for 'announce')";
6
6
  };
7
7
  export declare const SESSIONS_EMPTY = "No other agents available yet.\n\nAgents will appear here when:\n- Parallel tasks are spawned by the same parent\n- Another agent sends you a message";
8
- export declare function sessionsResult(agents: string[]): string;
9
- export declare const READ_EMPTY = "No messages in your iam.";
8
+ export declare function sessionsResult(agents: {
9
+ alias: string;
10
+ description?: string;
11
+ }[]): string;
12
+ export declare const READ_EMPTY = "No messages in your IAM inbox.";
10
13
  export declare function readResult(messages: {
11
14
  from: string;
12
15
  body: string;
13
16
  timestamp: number;
14
17
  read: boolean;
15
18
  }[], unreadCount: number): string;
16
- export declare const WRITE_MISSING_TO = "Error: 'to' is required. Use: iam write --to <session_id> --message \"...\"";
17
- export declare const WRITE_MISSING_MESSAGE = "Error: 'message' is required. Use: iam write --to <session_id> --message \"...\"";
19
+ export declare const WRITE_MISSING_TO = "Error: 'to' parameter is required for action=\"write\".";
20
+ export declare const WRITE_MISSING_MESSAGE = "Error: 'message' parameter is required for action=\"write\".";
21
+ export declare const ANNOUNCE_MISSING_MESSAGE = "Error: 'message' parameter is required for action=\"announce\". Describe what you're working on.";
22
+ export declare function announceResult(alias: string): string;
23
+ export declare function writeUnknownRecipient(to: string, known: string[]): string;
18
24
  export declare function writeResult(to: string, messageId: string): string;
19
25
  export declare function unknownAction(action: string): string;
20
- export declare const SYSTEM_PROMPT = "\n# Inter-Agent Messaging\n\nYou have access to an `iam` tool for communicating with other parallel agents.\n\nCommands:\n- `iam sessions` - See agents you can message\n- `iam read` - Read all your messages\n- `iam write --to <session_id> --message \"...\"` - Send a message\n\nCheck your iam when notified about new messages.\n";
26
+ export declare const SYSTEM_PROMPT = "\n<instructions tool=\"iam\">\n# Inter-Agent Messaging\n\nYou have access to an `iam` tool for communicating with other parallel agents.\n\nUsage:\n- action=\"announce\", message=\"...\" - Announce what you're working on (do this first!)\n- action=\"sessions\" - See other agents and what they're working on\n- action=\"read\" - Read your messages\n- action=\"write\", to=\"agentA\", message=\"...\" - Send a message\n\nAt the start of your task, use announce to let other agents know what you're doing.\nCheck your inbox when notified about new messages.\n</instructions>\n";
21
27
  export declare function urgentNotification(unreadCount: number): string;
22
28
  //# sourceMappingURL=prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../prompt.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,2QAKc,CAAC;AAE5C,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAMX,eAAO,MAAM,cAAc,0JAIS,CAAC;AAErC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAOvD;AAED,eAAO,MAAM,UAAU,6BAA6B,CAAC;AAErD,wBAAgB,UAAU,CACxB,QAAQ,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,EAAE,EAC1E,WAAW,EAAE,MAAM,GAClB,MAAM,CAeR;AAED,eAAO,MAAM,gBAAgB,gFAA8E,CAAC;AAC5G,eAAO,MAAM,qBAAqB,qFAAmF,CAAC;AAEtH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAMD,eAAO,MAAM,aAAa,6UAWzB,CAAC;AAMF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK9D"}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../prompt.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,2XAMgD,CAAC;AAE9E,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAMX,eAAO,MAAM,cAAc,0JAIS,CAAC;AAErC,wBAAgB,cAAc,CAAC,MAAM,EAAE;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAC,EAAE,GAAG,MAAM,CAYtF;AAED,eAAO,MAAM,UAAU,mCAAmC,CAAC;AAE3D,wBAAgB,UAAU,CACxB,QAAQ,EAAE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC,EAAE,EAC1E,WAAW,EAAE,MAAM,GAClB,MAAM,CAiBR;AAED,eAAO,MAAM,gBAAgB,4DAA0D,CAAC;AACxF,eAAO,MAAM,qBAAqB,iEAA+D,CAAC;AAClG,eAAO,MAAM,wBAAwB,qGAAmG,CAAC;AAEzI,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAMzE;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAMD,eAAO,MAAM,aAAa,mkBAezB,CAAC;AAMF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK9D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spoons-and-mirrors/iam",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Inter-agent messaging for OpenCode parallel subagents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",