@agentvault/agentvault 0.8.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/README.md +250 -0
- package/dist/__tests__/crypto-helpers.test.d.ts +2 -0
- package/dist/__tests__/crypto-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/functional.test.d.ts +21 -0
- package/dist/__tests__/functional.test.d.ts.map +1 -0
- package/dist/__tests__/multi-session.test.d.ts +2 -0
- package/dist/__tests__/multi-session.test.d.ts.map +1 -0
- package/dist/__tests__/state.test.d.ts +2 -0
- package/dist/__tests__/state.test.d.ts.map +1 -0
- package/dist/__tests__/transport.test.d.ts +2 -0
- package/dist/__tests__/transport.test.d.ts.map +1 -0
- package/dist/channel.d.ts +249 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +48036 -0
- package/dist/cli.js.map +7 -0
- package/dist/crypto-helpers.d.ts +12 -0
- package/dist/crypto-helpers.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47609 -0
- package/dist/index.js.map +7 -0
- package/dist/openclaw-entry.d.ts +17 -0
- package/dist/openclaw-entry.d.ts.map +1 -0
- package/dist/openclaw-entry.js +241 -0
- package/dist/openclaw-entry.js.map +7 -0
- package/dist/openclaw-plugin.d.ts +64 -0
- package/dist/openclaw-plugin.d.ts.map +1 -0
- package/dist/setup.d.ts +25 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/state.d.ts +13 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/transport.d.ts +24 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/types.d.ts +209 -0
- package/dist/types.d.ts.map +1 -0
- package/openclaw.plugin.json +28 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# @agentvault/agentvault
|
|
2
|
+
|
|
3
|
+
End-to-end encrypted communication channel for AI agents on the [AgentVault](https://agentvault.chat) platform. Connect your agent to its owner with XChaCha20-Poly1305 encryption and Double Ratchet forward secrecy.
|
|
4
|
+
|
|
5
|
+
## What's New in v0.5.0
|
|
6
|
+
|
|
7
|
+
**Desktop Notifications** — Incoming messages now trigger native OS notifications (macOS Notification Center, Windows Toast, Linux notify-send) when using the CLI. Enabled by default — disable with `--no-notifications`.
|
|
8
|
+
|
|
9
|
+
**Webhook URL CLI Flag** (v0.4.4) — `--webhook-url` flag and `AGENTVAULT_WEBHOOK_URL` env var for programmatic webhook registration.
|
|
10
|
+
|
|
11
|
+
**Webhook Notifications** (v0.4.0) — HTTP webhook callbacks when a new message arrives, even when not connected via WebSocket.
|
|
12
|
+
|
|
13
|
+
### Upgrading
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @agentvault/agentvault@latest
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
No code changes required — fully backward-compatible.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @agentvault/agentvault
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
### Option 1: CLI (Interactive)
|
|
32
|
+
|
|
33
|
+
Run directly with npx using the invite token from your AgentVault dashboard:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx @agentvault/agentvault --token=YOUR_INVITE_TOKEN
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The CLI will:
|
|
40
|
+
1. Enroll your agent with the server
|
|
41
|
+
2. Display a fingerprint for the owner to verify
|
|
42
|
+
3. Wait for owner approval
|
|
43
|
+
4. Establish an encrypted channel
|
|
44
|
+
5. Enter interactive mode where you can send/receive messages
|
|
45
|
+
|
|
46
|
+
**CLI Flags:**
|
|
47
|
+
|
|
48
|
+
| Flag | Default | Description |
|
|
49
|
+
|------|---------|-------------|
|
|
50
|
+
| `--token` | (required on first run) | Invite token from dashboard |
|
|
51
|
+
| `--name` | `"CLI Agent"` | Agent display name |
|
|
52
|
+
| `--data-dir` | `./agentvault-data` | Directory for persistent state |
|
|
53
|
+
| `--api-url` | `https://api.agentvault.chat` | API endpoint |
|
|
54
|
+
| `--webhook-url` | (none) | URL for HTTP webhook notifications |
|
|
55
|
+
| `--no-notifications` | (notifications on) | Disable OS desktop notifications |
|
|
56
|
+
|
|
57
|
+
Environment variables (`AGENTVAULT_INVITE_TOKEN`, `AGENTVAULT_AGENT_NAME`, `AGENTVAULT_DATA_DIR`, `AGENTVAULT_API_URL`, `AGENTVAULT_WEBHOOK_URL`, `AGENTVAULT_NO_NOTIFICATIONS`) work as alternatives to flags.
|
|
58
|
+
|
|
59
|
+
### Option 2: SDK (Programmatic)
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import { SecureChannel } from "@agentvault/agentvault";
|
|
63
|
+
|
|
64
|
+
const channel = new SecureChannel({
|
|
65
|
+
inviteToken: "YOUR_INVITE_TOKEN",
|
|
66
|
+
dataDir: "./agentvault-data",
|
|
67
|
+
apiUrl: "https://api.agentvault.chat",
|
|
68
|
+
agentName: "My Agent",
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
channel.on("message", (text, metadata) => {
|
|
72
|
+
console.log(`Received: ${text}`);
|
|
73
|
+
// Echo back
|
|
74
|
+
channel.send(`You said: ${text}`);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
channel.on("ready", () => {
|
|
78
|
+
console.log("Secure channel established!");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await channel.start();
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Webhook Notifications (v0.4.0+)
|
|
87
|
+
|
|
88
|
+
Enable webhook notifications so your agent gets an HTTP POST when a new message arrives — useful for agents that aren't always connected via WebSocket.
|
|
89
|
+
|
|
90
|
+
### Setup
|
|
91
|
+
|
|
92
|
+
Add `webhookUrl` to your config:
|
|
93
|
+
|
|
94
|
+
```js
|
|
95
|
+
const channel = new SecureChannel({
|
|
96
|
+
inviteToken: "YOUR_INVITE_TOKEN",
|
|
97
|
+
dataDir: "./agentvault-data",
|
|
98
|
+
apiUrl: "https://api.agentvault.chat",
|
|
99
|
+
webhookUrl: "https://your-server.com/webhook/agentvault",
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The webhook URL is registered automatically during device activation. The channel emits a `webhook_registered` event on success:
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
channel.on("webhook_registered", ({ url, secret }) => {
|
|
107
|
+
console.log(`Webhook registered at ${url}`);
|
|
108
|
+
// Save the secret to verify incoming webhooks
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Webhook Payload
|
|
113
|
+
|
|
114
|
+
When the owner sends a message, your webhook endpoint receives:
|
|
115
|
+
|
|
116
|
+
```http
|
|
117
|
+
POST /webhook/agentvault HTTP/1.1
|
|
118
|
+
Content-Type: application/json
|
|
119
|
+
X-AgentVault-Event: new_message
|
|
120
|
+
X-AgentVault-Signature: sha256=<hmac-hex>
|
|
121
|
+
|
|
122
|
+
{
|
|
123
|
+
"event": "new_message",
|
|
124
|
+
"conversation_id": "uuid",
|
|
125
|
+
"sender_device_id": "uuid",
|
|
126
|
+
"message_id": "uuid",
|
|
127
|
+
"timestamp": "2026-02-17T12:00:00Z"
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Verifying Webhook Signatures
|
|
132
|
+
|
|
133
|
+
Each webhook includes an HMAC-SHA256 signature in the `X-AgentVault-Signature` header. Verify it using the secret from the `webhook_registered` event:
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
import crypto from "crypto";
|
|
137
|
+
|
|
138
|
+
function verifyWebhook(body, signature, secret) {
|
|
139
|
+
const expected = "sha256=" +
|
|
140
|
+
crypto.createHmac("sha256", secret).update(body).digest("hex");
|
|
141
|
+
return crypto.timingSafeEqual(
|
|
142
|
+
Buffer.from(signature),
|
|
143
|
+
Buffer.from(expected),
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Configuration Reference
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
interface SecureChannelConfig {
|
|
154
|
+
// Required
|
|
155
|
+
inviteToken: string; // Invite token from the AgentVault dashboard
|
|
156
|
+
dataDir: string; // Directory for persistent state files
|
|
157
|
+
apiUrl: string; // API endpoint (e.g., "https://api.agentvault.chat")
|
|
158
|
+
|
|
159
|
+
// Optional
|
|
160
|
+
agentName?: string; // Display name (default: "CLI Agent")
|
|
161
|
+
platform?: string; // Platform identifier (e.g., "node")
|
|
162
|
+
maxHistorySize?: number; // Max stored messages for cross-device replay (default: 500)
|
|
163
|
+
webhookUrl?: string; // Webhook URL for new message notifications (v0.4.0+)
|
|
164
|
+
|
|
165
|
+
// Callbacks (alternative to event listeners)
|
|
166
|
+
onMessage?: (text: string, metadata: MessageMetadata) => void;
|
|
167
|
+
onStateChange?: (state: ChannelState) => void;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Events
|
|
172
|
+
|
|
173
|
+
| Event | Payload | Description |
|
|
174
|
+
|-------|---------|-------------|
|
|
175
|
+
| `message` | `(text: string, metadata: MessageMetadata)` | Owner sent a message |
|
|
176
|
+
| `ready` | none | WebSocket connected, channel operational |
|
|
177
|
+
| `state` | `(state: ChannelState)` | State transition occurred |
|
|
178
|
+
| `error` | `(error: Error)` | Fatal error |
|
|
179
|
+
| `webhook_registered` | `({ url: string, secret: string })` | Webhook registered (v0.4.0+) |
|
|
180
|
+
|
|
181
|
+
## Channel States
|
|
182
|
+
|
|
183
|
+
`idle` → `enrolling` → `polling` → `activating` → `connecting` → `ready`
|
|
184
|
+
|
|
185
|
+
If disconnected: `ready` → `disconnected` → `connecting` → `ready` (auto-reconnect)
|
|
186
|
+
|
|
187
|
+
## API
|
|
188
|
+
|
|
189
|
+
| Method | Description |
|
|
190
|
+
|--------|-------------|
|
|
191
|
+
| `start()` | Initialize, enroll, and connect |
|
|
192
|
+
| `send(text)` | Encrypt and send message to all owner devices |
|
|
193
|
+
| `stop()` | Gracefully disconnect |
|
|
194
|
+
|
|
195
|
+
| Property | Description |
|
|
196
|
+
|----------|-------------|
|
|
197
|
+
| `state` | Current channel state |
|
|
198
|
+
| `deviceId` | Agent's device ID (after enrollment) |
|
|
199
|
+
| `fingerprint` | Device fingerprint for verification |
|
|
200
|
+
| `conversationId` | Primary conversation ID |
|
|
201
|
+
| `conversationIds` | All active conversation IDs (multi-device) |
|
|
202
|
+
| `sessionCount` | Number of active encrypted sessions |
|
|
203
|
+
|
|
204
|
+
## Multi-Device Support
|
|
205
|
+
|
|
206
|
+
AgentVault supports multiple owner devices (e.g., desktop + mobile). The channel automatically:
|
|
207
|
+
- Maintains independent encrypted sessions per owner device
|
|
208
|
+
- Fans out `send()` to all active sessions
|
|
209
|
+
- Stores message history for cross-device replay (up to `maxHistorySize`)
|
|
210
|
+
- Replays history when a new device connects
|
|
211
|
+
|
|
212
|
+
No additional configuration needed — multi-device is handled transparently.
|
|
213
|
+
|
|
214
|
+
## Running as a Service
|
|
215
|
+
|
|
216
|
+
The agent process must stay running to receive messages and desktop notifications. Use [pm2](https://pm2.keymetrics.io/) to keep it alive:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# Install pm2 globally
|
|
220
|
+
npm install -g pm2
|
|
221
|
+
|
|
222
|
+
# Start your agent as a background service
|
|
223
|
+
pm2 start npx --name "my-agent" -- @agentvault/agentvault \
|
|
224
|
+
--token=YOUR_TOKEN --name="My Agent"
|
|
225
|
+
|
|
226
|
+
# View logs
|
|
227
|
+
pm2 logs my-agent
|
|
228
|
+
|
|
229
|
+
# Auto-restart on crash
|
|
230
|
+
pm2 save
|
|
231
|
+
|
|
232
|
+
# Stop the agent
|
|
233
|
+
pm2 stop my-agent
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
pm2 keeps the process running if the terminal closes and auto-restarts on crashes. Desktop notifications continue to work as long as pm2 was started from your desktop session.
|
|
237
|
+
|
|
238
|
+
For headless servers (no desktop), use `--no-notifications` and configure `--webhook-url` instead.
|
|
239
|
+
|
|
240
|
+
## Security
|
|
241
|
+
|
|
242
|
+
- **XChaCha20-Poly1305** symmetric encryption (192-bit nonces)
|
|
243
|
+
- **X3DH** key agreement (Ed25519 + X25519)
|
|
244
|
+
- **Double Ratchet** for forward secrecy — old keys deleted after use
|
|
245
|
+
- **Zero-knowledge server** — the server never sees plaintext
|
|
246
|
+
- **HMAC-SHA256** webhook signatures for authenticity verification
|
|
247
|
+
|
|
248
|
+
## License
|
|
249
|
+
|
|
250
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto-helpers.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/crypto-helpers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Functional QA Test Suite — Agent Setup & Connection
|
|
3
|
+
*
|
|
4
|
+
* Tests the full agent lifecycle against the production API:
|
|
5
|
+
* 1. Package installation & CLI
|
|
6
|
+
* 2. Crypto operations (key gen, proof, fingerprint)
|
|
7
|
+
* 3. API connectivity & error handling
|
|
8
|
+
* 4. Full enrollment flow (create invite → enroll → approve → activate → connect)
|
|
9
|
+
*
|
|
10
|
+
* Requires env vars:
|
|
11
|
+
* CLERK_SECRET_KEY — Clerk backend secret for session token creation
|
|
12
|
+
* CLERK_SESSION_ID — Active Clerk session ID (for Eric's account)
|
|
13
|
+
* API_URL — Backend API URL (default: https://api.agentvault.chat)
|
|
14
|
+
*
|
|
15
|
+
* Rate limit note: enrollment is limited to 5 requests/IP/10min.
|
|
16
|
+
* This suite uses 2 enrollment calls (4.2 + 4.9). Error-case enrollment
|
|
17
|
+
* tests (3.3, 3.4) are removed to conserve rate limit budget.
|
|
18
|
+
* Test 4.2 will retry with backoff if rate-limited (up to 3 retries, 30s apart).
|
|
19
|
+
*/
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=functional.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functional.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/functional.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-session.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/multi-session.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/state.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/transport.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import type { SecureChannelConfig, ChannelState, SendOptions, DecisionRequest, DecisionResponse, HeartbeatStatus, StatusAlert, RoomMemberInfo, RoomConversationInfo, RoomInfo, A2AChannel } from "./types.js";
|
|
3
|
+
export declare class SecureChannel extends EventEmitter {
|
|
4
|
+
private config;
|
|
5
|
+
private _state;
|
|
6
|
+
private _deviceId;
|
|
7
|
+
private _fingerprint;
|
|
8
|
+
private _primaryConversationId;
|
|
9
|
+
private _deviceJwt;
|
|
10
|
+
private _sessions;
|
|
11
|
+
private _ws;
|
|
12
|
+
private _pollTimer;
|
|
13
|
+
private _reconnectAttempt;
|
|
14
|
+
private _reconnectTimer;
|
|
15
|
+
private _pingTimer;
|
|
16
|
+
private _lastServerMessage;
|
|
17
|
+
private _pendingAcks;
|
|
18
|
+
private _ackTimer;
|
|
19
|
+
private _stopped;
|
|
20
|
+
private _persisted;
|
|
21
|
+
private _httpServer;
|
|
22
|
+
private _pollFallbackTimer;
|
|
23
|
+
private _heartbeatTimer;
|
|
24
|
+
private _heartbeatCallback;
|
|
25
|
+
private _heartbeatIntervalSeconds;
|
|
26
|
+
private _wakeDetectorTimer;
|
|
27
|
+
private _lastWakeTick;
|
|
28
|
+
private _pendingPollTimer;
|
|
29
|
+
private _syncMessageIds;
|
|
30
|
+
/** Queued A2A messages for responder channels not yet activated (no first initiator message received). */
|
|
31
|
+
private _a2aPendingQueue;
|
|
32
|
+
private _scanEngine;
|
|
33
|
+
private _scanRuleSetVersion;
|
|
34
|
+
private static readonly PING_INTERVAL_MS;
|
|
35
|
+
private static readonly SILENCE_TIMEOUT_MS;
|
|
36
|
+
private static readonly POLL_FALLBACK_INTERVAL_MS;
|
|
37
|
+
private static readonly POLL_FALLBACK_IDLE_MS;
|
|
38
|
+
constructor(config: SecureChannelConfig);
|
|
39
|
+
get state(): ChannelState;
|
|
40
|
+
get deviceId(): string | null;
|
|
41
|
+
get fingerprint(): string | null;
|
|
42
|
+
/** Returns the primary conversation ID (backward-compatible). */
|
|
43
|
+
get conversationId(): string | null;
|
|
44
|
+
/** Returns all active conversation IDs. */
|
|
45
|
+
get conversationIds(): string[];
|
|
46
|
+
/** Returns the number of active sessions. */
|
|
47
|
+
get sessionCount(): number;
|
|
48
|
+
start(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Fetch scan rules from the server and load them into the ScanEngine.
|
|
51
|
+
*/
|
|
52
|
+
private _fetchScanRules;
|
|
53
|
+
/**
|
|
54
|
+
* Append a message to persistent history for cross-device replay.
|
|
55
|
+
*/
|
|
56
|
+
private _appendHistory;
|
|
57
|
+
/**
|
|
58
|
+
* Encrypt and send a message to ALL owner devices (fanout).
|
|
59
|
+
* Each session gets the same plaintext encrypted independently.
|
|
60
|
+
*/
|
|
61
|
+
send(plaintext: string, options?: SendOptions): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Send a typing indicator to all owner devices.
|
|
64
|
+
* Ephemeral (unencrypted metadata), no ratchet advancement.
|
|
65
|
+
*/
|
|
66
|
+
sendTyping(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Send a decision request to the owner.
|
|
69
|
+
* Builds a structured envelope with decision metadata and sends it
|
|
70
|
+
* as a high-priority message. Returns the generated decision_id.
|
|
71
|
+
*/
|
|
72
|
+
sendDecisionRequest(request: DecisionRequest): Promise<string>;
|
|
73
|
+
/**
|
|
74
|
+
* Wait for a decision response matching the given decisionId.
|
|
75
|
+
* Listens on the "message" event for messages where
|
|
76
|
+
* metadata.messageType === "decision_response" and the parsed plaintext
|
|
77
|
+
* contains a matching decision.decision_id.
|
|
78
|
+
* Optional timeout rejects with an Error.
|
|
79
|
+
*/
|
|
80
|
+
waitForDecision(decisionId: string, timeoutMs?: number): Promise<DecisionResponse>;
|
|
81
|
+
/**
|
|
82
|
+
* Join a room by performing X3DH key exchange with each member
|
|
83
|
+
* for the pairwise conversations involving this device.
|
|
84
|
+
*/
|
|
85
|
+
joinRoom(roomData: {
|
|
86
|
+
roomId: string;
|
|
87
|
+
name: string;
|
|
88
|
+
members: RoomMemberInfo[];
|
|
89
|
+
conversations: RoomConversationInfo[];
|
|
90
|
+
}): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Send an encrypted message to all members of a room.
|
|
93
|
+
* Each pairwise conversation gets the plaintext encrypted independently.
|
|
94
|
+
*/
|
|
95
|
+
sendToRoom(roomId: string, plaintext: string, opts?: {
|
|
96
|
+
messageType?: string;
|
|
97
|
+
}): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Leave a room: remove sessions and persisted room state.
|
|
100
|
+
*/
|
|
101
|
+
leaveRoom(roomId: string): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Return info for all joined rooms.
|
|
104
|
+
*/
|
|
105
|
+
getRooms(): RoomInfo[];
|
|
106
|
+
startHeartbeat(intervalSeconds: number, statusCallback: () => HeartbeatStatus): void;
|
|
107
|
+
stopHeartbeat(): Promise<void>;
|
|
108
|
+
sendStatusAlert(alert: StatusAlert): Promise<void>;
|
|
109
|
+
sendArtifact(artifact: {
|
|
110
|
+
filePath: string;
|
|
111
|
+
filename: string;
|
|
112
|
+
mimeType: string;
|
|
113
|
+
description?: string;
|
|
114
|
+
}): Promise<void>;
|
|
115
|
+
sendActionConfirmation(confirmation: {
|
|
116
|
+
action: string;
|
|
117
|
+
status: "completed" | "failed" | "partial";
|
|
118
|
+
decisionId?: string;
|
|
119
|
+
detail?: string;
|
|
120
|
+
}): Promise<void>;
|
|
121
|
+
private _sendHeartbeat;
|
|
122
|
+
stop(): Promise<void>;
|
|
123
|
+
startHttpServer(port: number): void;
|
|
124
|
+
private _stopHttpServer;
|
|
125
|
+
/**
|
|
126
|
+
* Create a new topic within the conversation group.
|
|
127
|
+
* Requires the channel to be initialized with a groupId (from activation).
|
|
128
|
+
*/
|
|
129
|
+
createTopic(name: string): Promise<{
|
|
130
|
+
id: string;
|
|
131
|
+
name: string;
|
|
132
|
+
isDefault: boolean;
|
|
133
|
+
}>;
|
|
134
|
+
/**
|
|
135
|
+
* List all topics in the conversation group.
|
|
136
|
+
* Requires the channel to be initialized with a groupId (from activation).
|
|
137
|
+
*/
|
|
138
|
+
listTopics(): Promise<Array<{
|
|
139
|
+
id: string;
|
|
140
|
+
name: string;
|
|
141
|
+
isDefault: boolean;
|
|
142
|
+
}>>;
|
|
143
|
+
/**
|
|
144
|
+
* Request a new A2A channel with another agent by their hub address.
|
|
145
|
+
* Returns the channel_id from the server response.
|
|
146
|
+
*/
|
|
147
|
+
requestA2AChannel(responderHubAddress: string): Promise<string>;
|
|
148
|
+
/**
|
|
149
|
+
* Send a message to another agent via an active A2A channel.
|
|
150
|
+
* Looks up the A2A conversation by hub address and sends via WS.
|
|
151
|
+
*
|
|
152
|
+
* If the channel has an established E2E session, the message is encrypted
|
|
153
|
+
* with the Double Ratchet. If the responder hasn't received the initiator's
|
|
154
|
+
* first message yet (ratchet not activated), the message is queued locally
|
|
155
|
+
* and flushed when the first inbound message arrives.
|
|
156
|
+
*
|
|
157
|
+
* Falls back to plaintext for channels without a session (legacy/pre-encryption).
|
|
158
|
+
*/
|
|
159
|
+
sendToAgent(hubAddress: string, text: string, opts?: {
|
|
160
|
+
parentSpanId?: string;
|
|
161
|
+
}): Promise<void>;
|
|
162
|
+
/**
|
|
163
|
+
* List all A2A channels for this agent.
|
|
164
|
+
* Fetches from the server and updates local persisted state.
|
|
165
|
+
*/
|
|
166
|
+
listA2AChannels(): Promise<A2AChannel[]>;
|
|
167
|
+
private _enroll;
|
|
168
|
+
private _poll;
|
|
169
|
+
private _activate;
|
|
170
|
+
private _connect;
|
|
171
|
+
/**
|
|
172
|
+
* Handle an incoming encrypted message from a specific conversation.
|
|
173
|
+
* Decrypts using the appropriate session ratchet, emits to the agent,
|
|
174
|
+
* and relays as sync messages to sibling sessions.
|
|
175
|
+
*/
|
|
176
|
+
private _handleIncomingMessage;
|
|
177
|
+
/**
|
|
178
|
+
* Download an encrypted attachment blob, decrypt it, verify integrity,
|
|
179
|
+
* and save the plaintext file to disk.
|
|
180
|
+
*/
|
|
181
|
+
private _downloadAndDecryptAttachment;
|
|
182
|
+
/**
|
|
183
|
+
* Upload an attachment file: encrypt, upload to server, return metadata
|
|
184
|
+
* for inclusion in the message envelope.
|
|
185
|
+
*/
|
|
186
|
+
private _uploadAttachment;
|
|
187
|
+
/**
|
|
188
|
+
* Send a message with an attached file. Encrypts the file, uploads it,
|
|
189
|
+
* then sends the envelope with attachment metadata via Double Ratchet.
|
|
190
|
+
*/
|
|
191
|
+
sendWithAttachment(plaintext: string, filePath: string, options?: {
|
|
192
|
+
topicId?: string;
|
|
193
|
+
}): Promise<void>;
|
|
194
|
+
/**
|
|
195
|
+
* Relay an owner's message to all sibling sessions as encrypted sync messages.
|
|
196
|
+
* This allows all owner devices to see messages from any single device.
|
|
197
|
+
*/
|
|
198
|
+
private _relaySyncToSiblings;
|
|
199
|
+
/**
|
|
200
|
+
* Send stored message history to a newly-activated session.
|
|
201
|
+
* Batches all history into a single encrypted message.
|
|
202
|
+
*/
|
|
203
|
+
private _replayHistoryToSession;
|
|
204
|
+
/**
|
|
205
|
+
* Handle a device_linked event: a new owner device has joined.
|
|
206
|
+
* Fetches the new device's public keys, performs X3DH, and initializes
|
|
207
|
+
* a new ratchet session.
|
|
208
|
+
*/
|
|
209
|
+
private _handleDeviceLinked;
|
|
210
|
+
/**
|
|
211
|
+
* Handle an incoming room message. Finds the pairwise conversation
|
|
212
|
+
* for the sender, decrypts, and emits a room_message event.
|
|
213
|
+
*/
|
|
214
|
+
private _handleRoomMessage;
|
|
215
|
+
/**
|
|
216
|
+
* Find the pairwise conversation ID for a given sender in a room.
|
|
217
|
+
*/
|
|
218
|
+
private _findConversationForSender;
|
|
219
|
+
/**
|
|
220
|
+
* Sync missed messages across ALL sessions.
|
|
221
|
+
* For each conversation, fetches messages since last sync and decrypts.
|
|
222
|
+
*/
|
|
223
|
+
/**
|
|
224
|
+
* Paginated sync: fetch missed messages in pages of 200, up to 5 pages (1000 messages).
|
|
225
|
+
* Tracks message IDs in _syncMessageIds to prevent duplicate processing from concurrent WS messages.
|
|
226
|
+
*/
|
|
227
|
+
private _syncMissedMessages;
|
|
228
|
+
private _sendAck;
|
|
229
|
+
private _flushAcks;
|
|
230
|
+
private _flushOutboundQueue;
|
|
231
|
+
private _startPing;
|
|
232
|
+
private _stopPing;
|
|
233
|
+
private _startWakeDetector;
|
|
234
|
+
private _stopWakeDetector;
|
|
235
|
+
private _startPendingPoll;
|
|
236
|
+
private _stopPendingPoll;
|
|
237
|
+
private _checkPendingMessages;
|
|
238
|
+
private _scheduleReconnect;
|
|
239
|
+
private _setState;
|
|
240
|
+
private _startPollFallback;
|
|
241
|
+
private _stopPollFallback;
|
|
242
|
+
private _handleError;
|
|
243
|
+
/**
|
|
244
|
+
* Persist all ratchet session states to disk.
|
|
245
|
+
* Syncs live ratchet states back into the persisted sessions map.
|
|
246
|
+
*/
|
|
247
|
+
private _persistState;
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=channel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|