agents-can-communicate 0.1.7 → 0.1.8

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/adapter-claude-code",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/adapter-codex",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/adapter-gemini-cli",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/adapter-kimi",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/adapter-sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -33,6 +33,12 @@ function escapePeerText(value) {
33
33
  return String(value)
34
34
  .replaceAll(new RegExp(`${FENCE}${BLOCK}`, "g"), `'${FENCE}${BLOCK}`)
35
35
  .replaceAll(FENCE, `'${FENCE}`)
36
+ // The labels that frame this block are ACC's words at the start of a line.
37
+ // A peer writing one would otherwise produce a second line reading as ACC
38
+ // framing a different message - the same break-out the fence rule prevents,
39
+ // and neutralised the same way rather than by reflowing the text, which a
40
+ // handoff body cannot survive.
41
+ .replace(/^(subject:|body:)/gm, "'$1")
36
42
  .replace(CONTROL_CHARACTERS,
37
43
  character => `\\u${character.codePointAt(0).toString(16).padStart(4, "0")}`);
38
44
  }
@@ -118,12 +124,25 @@ function peerBlocks(messages) {
118
124
  `${FENCE}${BLOCK}`,
119
125
  `id ${message.messageId} | from ${message.fromSessionId} | type ${message.type}`
120
126
  + " | untrusted peer message",
121
- escapePeerText(message.subject),
127
+ `subject: ${oneLine(escapePeerText(message.subject))}`,
128
+ "body:",
122
129
  escapePeerText(message.body),
123
130
  FENCE,
124
131
  ]);
125
132
  }
126
133
 
134
+ /**
135
+ * A subject is one line, whatever the peer sent.
136
+ *
137
+ * The subject sits on the label's own line, so a newline inside it would push
138
+ * peer text to column 0 where ACC's labels live. Rendering the break visibly
139
+ * keeps the text readable and the frame ACC's.
140
+ */
141
+ function oneLine(value) {
142
+ return value.replaceAll("\r\n", "\\n").replaceAll("\n", "\\n").replaceAll("\r", "\\n");
143
+ }
144
+
145
+
127
146
  /**
128
147
  * Project a SyncResult into bounded text for one adapter to inject.
129
148
  *
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/cli",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/core",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -108,12 +108,22 @@ export function createStatusService(ports, sessions) {
108
108
  state: workstream.state,
109
109
  coordinatorSessionId: workstream.coordinatorSessionId,
110
110
  })),
111
+ // The owner is named twice on purpose. Every command that reaches a peer
112
+ // takes a participant id, so a claim that gave only a session id sent the
113
+ // reader back through the roster to answer "who is holding this, and how
114
+ // do I ask them for it". The session id stays because it is what
115
+ // `acc release --authority` acts on, and because two sessions of one
116
+ // participant are still two holders.
111
117
  claims: claims.map(claim => ({
112
118
  claimId: claim.claimId,
113
119
  resource: claim.resource,
114
120
  mode: claim.mode,
115
121
  enforcement: claim.enforcement,
116
122
  ownerSessionId: claim.ownerSessionId,
123
+ // Read from every session on record, not only the live ones: a claim
124
+ // outliving its session is exactly when this question gets asked.
125
+ ownerParticipantId: sessionRecords
126
+ .find(session => session.sessionId === claim.ownerSessionId)?.participantId ?? null,
117
127
  expiresAt: claim.expiresAt,
118
128
  })),
119
129
  attention: computeAttention(snapshot, { session: null,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/hook-runner",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/installer",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": { ".": "./src/index.mjs" },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/mcp-server",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/protocol",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/storage-filesystem",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-can-communicate",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "type": "module",
5
5
  "description": "Local-first coordination for independently opened AI agent sessions.",
6
6
  "keywords": [