@awebai/claude-channel 1.4.3 → 1.4.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/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +53 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22437,7 +22437,9 @@ async function* streamAgentEvents(client, signal) {
|
|
|
22437
22437
|
} catch (err2) {
|
|
22438
22438
|
if (signal.aborted)
|
|
22439
22439
|
return;
|
|
22440
|
-
|
|
22440
|
+
if (!isExpectedStreamTermination(err2)) {
|
|
22441
|
+
console.error(`[aw-channel] events stream parse failed: ${err2}`);
|
|
22442
|
+
}
|
|
22441
22443
|
await sleep(1e3, signal);
|
|
22442
22444
|
} finally {
|
|
22443
22445
|
resp.body?.cancel().catch(() => {
|
|
@@ -22523,6 +22525,13 @@ function parseAgentEvent(eventName, data) {
|
|
|
22523
22525
|
return { type: eventName };
|
|
22524
22526
|
}
|
|
22525
22527
|
}
|
|
22528
|
+
function isExpectedStreamTermination(err2) {
|
|
22529
|
+
if (!(err2 instanceof Error))
|
|
22530
|
+
return false;
|
|
22531
|
+
const name = err2.name.toLowerCase();
|
|
22532
|
+
const message = err2.message.toLowerCase();
|
|
22533
|
+
return name === "aborterror" || message === "terminated";
|
|
22534
|
+
}
|
|
22526
22535
|
function sleep(ms, signal) {
|
|
22527
22536
|
return new Promise((resolve) => {
|
|
22528
22537
|
if (signal.aborted) {
|
|
@@ -22879,6 +22888,9 @@ function hydrateAddressesFromSignedPayload(msg) {
|
|
|
22879
22888
|
} catch {
|
|
22880
22889
|
}
|
|
22881
22890
|
}
|
|
22891
|
+
async function ackMessage(client, messageId) {
|
|
22892
|
+
await client.post(`/v1/messages/${encodeURIComponent(messageId)}/ack`);
|
|
22893
|
+
}
|
|
22882
22894
|
async function verifyInboxMessage(msg) {
|
|
22883
22895
|
if (msg.signed_payload && msg.signature && msg.from_did) {
|
|
22884
22896
|
const status2 = await verifySignedPayload(msg.signed_payload, msg.signature, msg.from_did, msg.signing_key_id || "");
|
|
@@ -22954,6 +22966,9 @@ function hydrateAddressesFromSignedPayload2(msg) {
|
|
|
22954
22966
|
} catch {
|
|
22955
22967
|
}
|
|
22956
22968
|
}
|
|
22969
|
+
async function markRead(client, sessionId, upToMessageId) {
|
|
22970
|
+
await client.post(`/v1/chat/sessions/${encodeURIComponent(sessionId)}/read`, { up_to_message_id: upToMessageId });
|
|
22971
|
+
}
|
|
22957
22972
|
async function verifyChatMessage(msg) {
|
|
22958
22973
|
if (msg.signed_payload && msg.signature && msg.from_did) {
|
|
22959
22974
|
const status2 = await verifySignedPayload(msg.signed_payload, msg.signature, msg.from_did, msg.signing_key_id || "");
|
|
@@ -25749,9 +25764,9 @@ import { mkdir, open, rename, rm } from "node:fs/promises";
|
|
|
25749
25764
|
var PinStore = class _PinStore {
|
|
25750
25765
|
pins = /* @__PURE__ */ new Map();
|
|
25751
25766
|
addresses = /* @__PURE__ */ new Map();
|
|
25752
|
-
/** Check whether a DID matches the stored pin for
|
|
25753
|
-
checkPin(address, did,
|
|
25754
|
-
if (
|
|
25767
|
+
/** Check whether a DID matches the stored pin for a global address. */
|
|
25768
|
+
checkPin(address, did, identityScope) {
|
|
25769
|
+
if (identityScope === "local")
|
|
25755
25770
|
return "skipped";
|
|
25756
25771
|
const pinnedDID = this.addresses.get(address);
|
|
25757
25772
|
if (pinnedDID === void 0)
|
|
@@ -25947,7 +25962,7 @@ var RegistryResolver = class {
|
|
|
25947
25962
|
address: `${split2.domain}/${split2.name}`,
|
|
25948
25963
|
controllerDid: authority.controllerDid,
|
|
25949
25964
|
custody: "self",
|
|
25950
|
-
|
|
25965
|
+
identityScope: "global"
|
|
25951
25966
|
};
|
|
25952
25967
|
}
|
|
25953
25968
|
async discoverRegistry(domain2) {
|
|
@@ -26338,6 +26353,17 @@ function escapeJSON2(s) {
|
|
|
26338
26353
|
// ../channel-core/dist/identity/trust.js
|
|
26339
26354
|
etc.sha512Sync = (...m) => sha512(etc.concatBytes(...m));
|
|
26340
26355
|
var ANNOUNCEMENT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
26356
|
+
function normalizeIdentityScope(identityScope, legacyLifetime, defaultScope) {
|
|
26357
|
+
const normalizedScope = (identityScope || "").trim().toLowerCase();
|
|
26358
|
+
if (normalizedScope === "global" || normalizedScope === "local")
|
|
26359
|
+
return normalizedScope;
|
|
26360
|
+
const normalizedLegacy = (legacyLifetime || "").trim().toLowerCase();
|
|
26361
|
+
if (normalizedLegacy === "persistent")
|
|
26362
|
+
return "global";
|
|
26363
|
+
if (normalizedLegacy === "ephemeral")
|
|
26364
|
+
return "local";
|
|
26365
|
+
return defaultScope;
|
|
26366
|
+
}
|
|
26341
26367
|
var SenderTrustManager = class {
|
|
26342
26368
|
client;
|
|
26343
26369
|
registry;
|
|
@@ -26399,7 +26425,7 @@ var SenderTrustManager = class {
|
|
|
26399
26425
|
if (!status || status !== "verified" && status !== "verified_custodial" || !fromDID || !trustAddress || !meta3.resolved) {
|
|
26400
26426
|
return { status, stored: false };
|
|
26401
26427
|
}
|
|
26402
|
-
if (meta3.
|
|
26428
|
+
if (meta3.identityScope === "local") {
|
|
26403
26429
|
let removed = store.removeAddress(trustAddress);
|
|
26404
26430
|
if (rawAddress && rawAddress !== trustAddress) {
|
|
26405
26431
|
removed = store.removeAddress(rawAddress) || removed;
|
|
@@ -26426,7 +26452,7 @@ var SenderTrustManager = class {
|
|
|
26426
26452
|
}
|
|
26427
26453
|
}
|
|
26428
26454
|
}
|
|
26429
|
-
const pinResult = store.checkPin(trustAddress, pinKey, meta3.
|
|
26455
|
+
const pinResult = store.checkPin(trustAddress, pinKey, meta3.identityScope);
|
|
26430
26456
|
switch (pinResult) {
|
|
26431
26457
|
case "new":
|
|
26432
26458
|
store.storePin(pinKey, trustAddress, "", "");
|
|
@@ -26552,7 +26578,7 @@ var SenderTrustManager = class {
|
|
|
26552
26578
|
const rawAddress = address.trim();
|
|
26553
26579
|
const trustAddress = this.canonicalTrustAddress(rawAddress);
|
|
26554
26580
|
if (!trustAddress) {
|
|
26555
|
-
return {
|
|
26581
|
+
return { identityScope: "global", custody: "self", resolved: false };
|
|
26556
26582
|
}
|
|
26557
26583
|
const cached2 = this.metaCache.get(trustAddress);
|
|
26558
26584
|
if (cached2)
|
|
@@ -26560,7 +26586,7 @@ var SenderTrustManager = class {
|
|
|
26560
26586
|
try {
|
|
26561
26587
|
const identity = await this.resolveIdentity(rawAddress);
|
|
26562
26588
|
const meta3 = {
|
|
26563
|
-
|
|
26589
|
+
identityScope: identity.identityScope,
|
|
26564
26590
|
custody: identity.custody || "self",
|
|
26565
26591
|
controllerDid: identity.controllerDid,
|
|
26566
26592
|
resolved: true
|
|
@@ -26568,7 +26594,7 @@ var SenderTrustManager = class {
|
|
|
26568
26594
|
this.metaCache.set(trustAddress, meta3);
|
|
26569
26595
|
return meta3;
|
|
26570
26596
|
} catch {
|
|
26571
|
-
return {
|
|
26597
|
+
return { identityScope: "global", custody: "self", resolved: false };
|
|
26572
26598
|
}
|
|
26573
26599
|
}
|
|
26574
26600
|
async resolveIdentity(address) {
|
|
@@ -26588,7 +26614,7 @@ var SenderTrustManager = class {
|
|
|
26588
26614
|
stableID: response.did_aw,
|
|
26589
26615
|
address: response.address || `${this.teamID}/${trimmed}`,
|
|
26590
26616
|
custody: "self",
|
|
26591
|
-
|
|
26617
|
+
identityScope: normalizeIdentityScope(response.identity_scope, response.lifetime, "local")
|
|
26592
26618
|
};
|
|
26593
26619
|
}
|
|
26594
26620
|
};
|
|
@@ -26659,9 +26685,11 @@ function escapeJSON3(s) {
|
|
|
26659
26685
|
}
|
|
26660
26686
|
|
|
26661
26687
|
// ../channel-core/dist/channel.js
|
|
26662
|
-
import { join as join2 } from "node:path";
|
|
26688
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
26663
26689
|
import { homedir } from "node:os";
|
|
26664
26690
|
var DEFAULT_PIN_STORE_PATH = join2(homedir(), ".config", "aw", "known_agents.yaml");
|
|
26691
|
+
var DEFAULT_DELIVERY_STORE_PATH = join2(homedir(), ".config", "aw", "channel-delivered-ids.json");
|
|
26692
|
+
var DELIVERED_IDS_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
26665
26693
|
|
|
26666
26694
|
// src/index.ts
|
|
26667
26695
|
var PIN_STORE_PATH = join3(homedir2(), ".config", "aw", "known_agents.yaml");
|
|
@@ -26719,7 +26747,7 @@ async function main() {
|
|
|
26719
26747
|
},
|
|
26720
26748
|
instructions: `Events from the aweb channel are coordination messages from other agents in your team. Use the aw CLI to respond, not MCP tools.
|
|
26721
26749
|
|
|
26722
|
-
Mail events (type="mail") are async. Read them and act if needed.
|
|
26750
|
+
Mail events (type="mail") are async. Read them and act if needed. Confirmed channel delivery marks the source message handled so reconnects do not replay stale mail. Reply with: aw mail reply <message_id> --body "<reply>".
|
|
26723
26751
|
|
|
26724
26752
|
Chat events (type="chat") may have sender_waiting="true", meaning the sender is blocked waiting for your reply. Respond promptly with: aw chat send-and-wait <from> "<reply>"
|
|
26725
26753
|
If you need more time, send a status update the same way.
|
|
@@ -26777,7 +26805,10 @@ async function dispatchEvent(mcp, client, pinStore, trust, self, dispatched, eve
|
|
|
26777
26805
|
if (isSelfSender(msg.from_alias, msg.from_address, msg.from_stable_id, msg.from_did, self)) continue;
|
|
26778
26806
|
const conversationID = msg.conversation_id || event.conversation_id;
|
|
26779
26807
|
const key = dispatchKey("mail", conversationID, msg.message_id);
|
|
26780
|
-
if (dispatched.has(key))
|
|
26808
|
+
if (dispatched.has(key)) {
|
|
26809
|
+
if (!msg.read_at) await ackMessage(client, msg.message_id);
|
|
26810
|
+
continue;
|
|
26811
|
+
}
|
|
26781
26812
|
dispatched.add(key);
|
|
26782
26813
|
const from = senderDisplayAddress(msg.from_alias, msg.from_address);
|
|
26783
26814
|
const tofu = await trust.normalizeTrust(
|
|
@@ -26807,6 +26838,7 @@ async function dispatchEvent(mcp, client, pinStore, trust, self, dispatched, eve
|
|
|
26807
26838
|
method: "notifications/claude/channel",
|
|
26808
26839
|
params: { content: msg.body, meta: meta3 }
|
|
26809
26840
|
});
|
|
26841
|
+
await ackMessage(client, msg.message_id);
|
|
26810
26842
|
}
|
|
26811
26843
|
if (pinsDirty) await pinStore.save(PIN_STORE_PATH);
|
|
26812
26844
|
break;
|
|
@@ -26815,11 +26847,15 @@ async function dispatchEvent(mcp, client, pinStore, trust, self, dispatched, eve
|
|
|
26815
26847
|
if (!event.session_id) break;
|
|
26816
26848
|
const messages = await fetchHistory(client, event.session_id, true, CHAT_FETCH_LIMIT, event.message_id);
|
|
26817
26849
|
let pinsDirty = false;
|
|
26850
|
+
let lastMessageId;
|
|
26818
26851
|
for (const msg of messages) {
|
|
26819
26852
|
if (isSelfSender(msg.from_agent, msg.from_address, msg.from_stable_id, msg.from_did, self)) continue;
|
|
26820
26853
|
const conversationID = msg.conversation_id || event.conversation_id || event.session_id;
|
|
26821
26854
|
const key = dispatchKey("chat", conversationID, msg.message_id);
|
|
26822
|
-
if (dispatched.has(key))
|
|
26855
|
+
if (dispatched.has(key)) {
|
|
26856
|
+
lastMessageId = msg.message_id;
|
|
26857
|
+
continue;
|
|
26858
|
+
}
|
|
26823
26859
|
dispatched.add(key);
|
|
26824
26860
|
const from = senderDisplayAddress(msg.from_agent, msg.from_address);
|
|
26825
26861
|
const tofu = await trust.normalizeTrust(
|
|
@@ -26850,7 +26886,9 @@ async function dispatchEvent(mcp, client, pinStore, trust, self, dispatched, eve
|
|
|
26850
26886
|
method: "notifications/claude/channel",
|
|
26851
26887
|
params: { content: msg.body, meta: meta3 }
|
|
26852
26888
|
});
|
|
26889
|
+
lastMessageId = msg.message_id;
|
|
26853
26890
|
}
|
|
26891
|
+
if (lastMessageId) await markRead(client, event.session_id, lastMessageId);
|
|
26854
26892
|
if (pinsDirty) await pinStore.save(PIN_STORE_PATH);
|
|
26855
26893
|
break;
|
|
26856
26894
|
}
|