clawmatrix 0.1.23 → 0.2.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 +4 -1
- package/package.json +4 -2
- package/src/acp-proxy.ts +2183 -0
- package/src/audit.ts +42 -0
- package/src/auth.ts +2 -3
- package/src/cli.ts +76 -2
- package/src/cluster-service.ts +243 -3
- package/src/compat.ts +84 -3
- package/src/config.ts +117 -4
- package/src/connection.ts +288 -85
- package/src/crypto.ts +179 -0
- package/src/debug.ts +15 -2
- package/src/e2e/helpers.ts +318 -0
- package/src/handoff.ts +171 -92
- package/src/identity.ts +95 -0
- package/src/index.ts +433 -58
- package/src/knowledge-sync.ts +776 -207
- package/src/model-proxy.ts +144 -39
- package/src/peer-approval.ts +628 -0
- package/src/peer-manager.ts +261 -32
- package/src/rate-limiter.ts +88 -0
- package/src/router.ts +32 -10
- package/src/sentinel-manager.ts +142 -0
- package/src/sentinel.ts +618 -0
- package/src/task-activity.ts +74 -0
- package/src/terminal.ts +566 -0
- package/src/tool-proxy.ts +127 -3
- package/src/tools/cluster-acp.ts +237 -0
- package/src/tools/cluster-batch.ts +76 -0
- package/src/tools/cluster-diagnostic.ts +174 -0
- package/src/tools/cluster-edit.ts +70 -0
- package/src/tools/cluster-peers.ts +59 -14
- package/src/tools/cluster-terminal.ts +232 -0
- package/src/tools/cluster-tool.ts +26 -11
- package/src/types.ts +477 -3
- package/src/web.ts +2 -2
package/src/types.ts
CHANGED
|
@@ -12,11 +12,33 @@ export interface ClusterFrame {
|
|
|
12
12
|
// ── Auth messages ──────────────────────────────────────────────────
|
|
13
13
|
export interface AuthChallenge extends ClusterFrame {
|
|
14
14
|
type: "auth_challenge";
|
|
15
|
-
payload: { nonce: string };
|
|
15
|
+
payload: { nonce: string; publicKey?: string };
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/** Legacy plaintext auth (used when E2EE is disabled). */
|
|
18
19
|
export interface AuthRequest extends ClusterFrame {
|
|
19
20
|
type: "auth";
|
|
21
|
+
payload: {
|
|
22
|
+
nodeId: string;
|
|
23
|
+
sig: string;
|
|
24
|
+
publicKey?: string;
|
|
25
|
+
agents?: AgentInfo[];
|
|
26
|
+
models?: ModelInfo[];
|
|
27
|
+
tags?: string[];
|
|
28
|
+
deviceInfo?: DeviceInfo;
|
|
29
|
+
toolProxy?: ToolProxyInfo;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Phase 2 of E2EE handshake: client sends its public key (plaintext). */
|
|
34
|
+
export interface AuthKeyExchange extends ClusterFrame {
|
|
35
|
+
type: "auth_key_exchange";
|
|
36
|
+
payload: { publicKey: string };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Phase 3 of E2EE handshake: client sends encrypted HMAC + capabilities. */
|
|
40
|
+
export interface AuthVerify extends ClusterFrame {
|
|
41
|
+
type: "auth_verify";
|
|
20
42
|
payload: {
|
|
21
43
|
nodeId: string;
|
|
22
44
|
sig: string;
|
|
@@ -115,6 +137,8 @@ export interface ModelResponse extends ClusterFrame {
|
|
|
115
137
|
payload: {
|
|
116
138
|
success: boolean;
|
|
117
139
|
content?: string;
|
|
140
|
+
/** Reasoning/thinking content from models like DeepSeek. */
|
|
141
|
+
reasoning?: string;
|
|
118
142
|
/** Full message object from upstream (choices[0].message or responses output).
|
|
119
143
|
* Carries tool_calls, refusal, etc. that `content` alone cannot represent. */
|
|
120
144
|
message?: unknown;
|
|
@@ -128,6 +152,8 @@ export interface ModelStreamChunk extends ClusterFrame {
|
|
|
128
152
|
id: string;
|
|
129
153
|
payload: {
|
|
130
154
|
delta: string;
|
|
155
|
+
/** Reasoning/thinking delta from models like DeepSeek (reasoning_content). */
|
|
156
|
+
reasoningDelta?: string;
|
|
131
157
|
/** Full delta object from upstream (choices[0].delta).
|
|
132
158
|
* Carries tool_calls chunks that `delta` string cannot represent. */
|
|
133
159
|
deltaObj?: unknown;
|
|
@@ -136,6 +162,14 @@ export interface ModelStreamChunk extends ClusterFrame {
|
|
|
136
162
|
};
|
|
137
163
|
}
|
|
138
164
|
|
|
165
|
+
// ── Image content ─────────────────────────────────────────────────
|
|
166
|
+
export interface ImageContent {
|
|
167
|
+
/** Base64-encoded image data (without data URI prefix) */
|
|
168
|
+
data: string;
|
|
169
|
+
/** MIME type, e.g. "image/png", "image/jpeg" */
|
|
170
|
+
mediaType: string;
|
|
171
|
+
}
|
|
172
|
+
|
|
139
173
|
// ── Handoff ────────────────────────────────────────────────────────
|
|
140
174
|
export type HandoffStatus = "working" | "input_required" | "completed" | "failed" | "canceled";
|
|
141
175
|
|
|
@@ -152,6 +186,8 @@ export interface HandoffRequest extends ClusterFrame {
|
|
|
152
186
|
target: string;
|
|
153
187
|
task: string;
|
|
154
188
|
context?: string;
|
|
189
|
+
sessionId?: string; // Reuse session for multi-turn conversation
|
|
190
|
+
images?: ImageContent[];
|
|
155
191
|
};
|
|
156
192
|
}
|
|
157
193
|
|
|
@@ -162,6 +198,7 @@ export interface HandoffStreamChunk extends ClusterFrame {
|
|
|
162
198
|
delta: string;
|
|
163
199
|
done: boolean;
|
|
164
200
|
artifacts?: Artifact[];
|
|
201
|
+
sessionId?: string; // included for session watchers (multi-device sync)
|
|
165
202
|
};
|
|
166
203
|
}
|
|
167
204
|
|
|
@@ -177,6 +214,7 @@ export interface HandoffResponse extends ClusterFrame {
|
|
|
177
214
|
artifacts?: Artifact[];
|
|
178
215
|
inputRequired?: boolean;
|
|
179
216
|
handoffId?: string;
|
|
217
|
+
sessionId?: string; // For multi-turn conversation reuse
|
|
180
218
|
};
|
|
181
219
|
}
|
|
182
220
|
|
|
@@ -216,6 +254,7 @@ export interface HandoffInput extends ClusterFrame {
|
|
|
216
254
|
id: string;
|
|
217
255
|
payload: {
|
|
218
256
|
message: string;
|
|
257
|
+
images?: ImageContent[];
|
|
219
258
|
};
|
|
220
259
|
}
|
|
221
260
|
|
|
@@ -248,6 +287,36 @@ export interface ToolProxyResponse extends ClusterFrame {
|
|
|
248
287
|
};
|
|
249
288
|
}
|
|
250
289
|
|
|
290
|
+
// ── Tool batch proxy ──────────────────────────────────────────────
|
|
291
|
+
export interface ToolBatchItem {
|
|
292
|
+
tool: string;
|
|
293
|
+
params: Record<string, unknown>;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export interface ToolBatchResultItem {
|
|
297
|
+
tool: string;
|
|
298
|
+
success: boolean;
|
|
299
|
+
result?: Record<string, unknown>;
|
|
300
|
+
error?: string;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export interface ToolBatchRequest extends ClusterFrame {
|
|
304
|
+
type: "tool_batch_req";
|
|
305
|
+
id: string;
|
|
306
|
+
payload: {
|
|
307
|
+
items: ToolBatchItem[];
|
|
308
|
+
stopOnError?: boolean; // default true
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export interface ToolBatchResponse extends ClusterFrame {
|
|
313
|
+
type: "tool_batch_res";
|
|
314
|
+
id: string;
|
|
315
|
+
payload: {
|
|
316
|
+
results: ToolBatchResultItem[];
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
251
320
|
// ── Device info ───────────────────────────────────────────────────
|
|
252
321
|
export interface DeviceInfo {
|
|
253
322
|
os: string; // e.g. "Darwin 24.6.0", "Linux 6.1.0"
|
|
@@ -285,6 +354,7 @@ export interface ModelInfo {
|
|
|
285
354
|
id: string;
|
|
286
355
|
provider: string;
|
|
287
356
|
description?: string;
|
|
357
|
+
input?: ("text" | "image")[];
|
|
288
358
|
compat?: ModelCompatInfo;
|
|
289
359
|
}
|
|
290
360
|
|
|
@@ -294,6 +364,11 @@ export interface ToolProxyInfo {
|
|
|
294
364
|
deny: string[];
|
|
295
365
|
}
|
|
296
366
|
|
|
367
|
+
export interface AcpAgentInfo {
|
|
368
|
+
id: string;
|
|
369
|
+
description: string;
|
|
370
|
+
}
|
|
371
|
+
|
|
297
372
|
export interface PeerInfo {
|
|
298
373
|
nodeId: string;
|
|
299
374
|
agents: AgentInfo[];
|
|
@@ -303,6 +378,8 @@ export interface PeerInfo {
|
|
|
303
378
|
directPeers?: string[]; // nodeIds this node has direct connections to
|
|
304
379
|
deviceInfo?: DeviceInfo; // system/hardware info
|
|
305
380
|
toolProxy?: ToolProxyInfo;
|
|
381
|
+
acpAgents?: AcpAgentInfo[]; // ACP agents available on this node
|
|
382
|
+
latencyMs?: number; // heartbeat RTT (direct) or estimated round-trip (relay)
|
|
306
383
|
}
|
|
307
384
|
|
|
308
385
|
export interface NodeCapabilities {
|
|
@@ -312,6 +389,7 @@ export interface NodeCapabilities {
|
|
|
312
389
|
tags: string[];
|
|
313
390
|
deviceInfo?: DeviceInfo;
|
|
314
391
|
toolProxy?: ToolProxyInfo;
|
|
392
|
+
acpAgents?: AcpAgentInfo[];
|
|
315
393
|
}
|
|
316
394
|
|
|
317
395
|
// ── Ingested events (from Shortcuts automations, etc.) ────────────
|
|
@@ -328,7 +406,368 @@ export interface IngestedEvent {
|
|
|
328
406
|
export interface KnowledgeSyncFrame extends ClusterFrame {
|
|
329
407
|
type: "knowledge_sync";
|
|
330
408
|
payload: {
|
|
331
|
-
|
|
409
|
+
docId: string; // "" = registry, otherwise file relPath
|
|
410
|
+
data: string; // base64-encoded Automerge sync message
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// ── Diagnostic (sentinel) ────────────────────────────────────────
|
|
415
|
+
export interface DiagnosticExec extends ClusterFrame {
|
|
416
|
+
type: "diagnostic_exec";
|
|
417
|
+
id: string;
|
|
418
|
+
payload: {
|
|
419
|
+
command: string;
|
|
420
|
+
timeout?: number; // seconds, default 30
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export interface DiagnosticExecResponse extends ClusterFrame {
|
|
425
|
+
type: "diagnostic_exec_res";
|
|
426
|
+
id: string;
|
|
427
|
+
payload: {
|
|
428
|
+
success: boolean;
|
|
429
|
+
exitCode?: number;
|
|
430
|
+
stdout?: string;
|
|
431
|
+
stderr?: string;
|
|
432
|
+
error?: string;
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
export interface DiagnosticStatus extends ClusterFrame {
|
|
437
|
+
type: "diagnostic_status";
|
|
438
|
+
id: string;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
export interface DiagnosticStatusResponse extends ClusterFrame {
|
|
442
|
+
type: "diagnostic_status_res";
|
|
443
|
+
id: string;
|
|
444
|
+
payload: {
|
|
445
|
+
gatewayAlive: boolean;
|
|
446
|
+
uptimeMs: number;
|
|
447
|
+
pid: number;
|
|
448
|
+
gatewayPid?: number;
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// ── ACP proxy ─────────────────────────────────────────────────────
|
|
453
|
+
export type AcpSessionMode = "oneshot" | "persistent";
|
|
454
|
+
|
|
455
|
+
export interface AcpTaskRequest extends ClusterFrame {
|
|
456
|
+
type: "acp_req";
|
|
457
|
+
id: string;
|
|
458
|
+
payload: {
|
|
459
|
+
agent: string; // ACP harness: "claude", "codex", "gemini", etc.
|
|
460
|
+
task?: string; // prompt to execute (omit to create session without prompting)
|
|
461
|
+
sessionId?: string; // existing session ID for follow-up (persistent mode)
|
|
462
|
+
acpSessionId?: string; // ACP-level session ID for resume when sessionId is stale
|
|
463
|
+
mode?: AcpSessionMode; // default: "oneshot"
|
|
464
|
+
cwd?: string; // working directory on remote node
|
|
465
|
+
images?: ImageContent[];
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
export interface AcpStreamChunk extends ClusterFrame {
|
|
470
|
+
type: "acp_stream";
|
|
471
|
+
id: string;
|
|
472
|
+
payload: {
|
|
473
|
+
delta: string;
|
|
474
|
+
event?: string; // "agent_message_chunk" | "tool_call" | etc.
|
|
475
|
+
done: boolean;
|
|
476
|
+
sessionId?: string; // included for session watchers (multi-device sync)
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
export interface AcpTaskResponse extends ClusterFrame {
|
|
481
|
+
type: "acp_res";
|
|
482
|
+
id: string;
|
|
483
|
+
payload: {
|
|
484
|
+
success: boolean;
|
|
485
|
+
nodeId?: string;
|
|
486
|
+
agent?: string;
|
|
487
|
+
result?: string;
|
|
488
|
+
sessionId?: string; // returned for persistent sessions
|
|
489
|
+
acpSessionId?: string; // ACP-level session ID for future resume
|
|
490
|
+
stopReason?: string; // ACP stop reason
|
|
491
|
+
error?: string;
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
export interface AcpCloseRequest extends ClusterFrame {
|
|
496
|
+
type: "acp_close";
|
|
497
|
+
id: string;
|
|
498
|
+
payload: {
|
|
499
|
+
sessionId: string;
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
export interface AcpCloseResponse extends ClusterFrame {
|
|
504
|
+
type: "acp_close_res";
|
|
505
|
+
id: string;
|
|
506
|
+
payload: {
|
|
507
|
+
success: boolean;
|
|
508
|
+
error?: string;
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// ── ACP session management ──────────────────────────────────────
|
|
513
|
+
export interface AcpSessionInfo {
|
|
514
|
+
sessionId: string;
|
|
515
|
+
cwd: string;
|
|
516
|
+
title?: string;
|
|
517
|
+
description?: string; // first user message (for display in session list)
|
|
518
|
+
updatedAt?: string;
|
|
519
|
+
agent?: string; // which ACP agent (claude, codex, etc.)
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export interface AcpListRequest extends ClusterFrame {
|
|
523
|
+
type: "acp_list_req";
|
|
524
|
+
id: string;
|
|
525
|
+
payload: {
|
|
526
|
+
agent?: string; // filter by agent type
|
|
527
|
+
cwd?: string; // filter by working directory
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
export interface AcpListResponse extends ClusterFrame {
|
|
532
|
+
type: "acp_list_res";
|
|
533
|
+
id: string;
|
|
534
|
+
payload: {
|
|
535
|
+
success: boolean;
|
|
536
|
+
sessions?: AcpSessionInfo[];
|
|
537
|
+
error?: string;
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
export interface AcpResumeRequest extends ClusterFrame {
|
|
542
|
+
type: "acp_resume_req";
|
|
543
|
+
id: string;
|
|
544
|
+
payload: {
|
|
545
|
+
agent: string;
|
|
546
|
+
acpSessionId: string; // the ACP protocol session ID to resume
|
|
547
|
+
cwd: string;
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export interface AcpResumeResponse extends ClusterFrame {
|
|
552
|
+
type: "acp_resume_res";
|
|
553
|
+
id: string;
|
|
554
|
+
payload: {
|
|
555
|
+
success: boolean;
|
|
556
|
+
sessionId?: string; // ClawMatrix session ID for follow-up prompts
|
|
557
|
+
error?: string;
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export interface AcpCancelRequest extends ClusterFrame {
|
|
562
|
+
type: "acp_cancel";
|
|
563
|
+
id: string;
|
|
564
|
+
payload: {
|
|
565
|
+
sessionId: string; // ClawMatrix session ID
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
export interface AcpCancelResponse extends ClusterFrame {
|
|
570
|
+
type: "acp_cancel_res";
|
|
571
|
+
id: string;
|
|
572
|
+
payload: {
|
|
573
|
+
success: boolean;
|
|
574
|
+
error?: string;
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export interface AcpModeInfo {
|
|
579
|
+
id: string;
|
|
580
|
+
name: string;
|
|
581
|
+
description?: string;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
export interface AcpSetModeRequest extends ClusterFrame {
|
|
585
|
+
type: "acp_set_mode";
|
|
586
|
+
id: string;
|
|
587
|
+
payload: {
|
|
588
|
+
sessionId: string; // ClawMatrix session ID
|
|
589
|
+
modeId: string; // e.g. "code", "architect", "ask"
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
export interface AcpSetModeResponse extends ClusterFrame {
|
|
594
|
+
type: "acp_set_mode_res";
|
|
595
|
+
id: string;
|
|
596
|
+
payload: {
|
|
597
|
+
success: boolean;
|
|
598
|
+
error?: string;
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export interface AcpGetModesRequest extends ClusterFrame {
|
|
603
|
+
type: "acp_get_modes";
|
|
604
|
+
id: string;
|
|
605
|
+
payload: {
|
|
606
|
+
sessionId: string;
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
export interface AcpGetModesResponse extends ClusterFrame {
|
|
611
|
+
type: "acp_get_modes_res";
|
|
612
|
+
id: string;
|
|
613
|
+
payload: {
|
|
614
|
+
success: boolean;
|
|
615
|
+
modes?: AcpModeInfo[];
|
|
616
|
+
currentModeId?: string;
|
|
617
|
+
error?: string;
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
// ── Chat history ──────────────────────────────────────────────────
|
|
622
|
+
|
|
623
|
+
export interface ChatHistoryMessage {
|
|
624
|
+
role: "user" | "assistant" | "system" | "tool";
|
|
625
|
+
text: string;
|
|
626
|
+
thinking?: string;
|
|
627
|
+
toolName?: string;
|
|
628
|
+
toolArgs?: string;
|
|
629
|
+
toolResult?: string;
|
|
630
|
+
images?: Array<{ data: string; mediaType: string }>;
|
|
631
|
+
timestamp?: number;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
export interface ChatHistoryRequest extends ClusterFrame {
|
|
635
|
+
type: "chat_history_req";
|
|
636
|
+
id: string;
|
|
637
|
+
payload: {
|
|
638
|
+
sessionId: string;
|
|
639
|
+
limit?: number;
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
export interface ChatHistoryResponse extends ClusterFrame {
|
|
644
|
+
type: "chat_history_res";
|
|
645
|
+
id: string;
|
|
646
|
+
payload: {
|
|
647
|
+
success: boolean;
|
|
648
|
+
messages?: ChatHistoryMessage[];
|
|
649
|
+
error?: string;
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// ── Task activity (Live Activity push to mobile nodes) ───────────
|
|
654
|
+
|
|
655
|
+
export type TaskActivityStatus = "started" | "progress" | "completed" | "failed";
|
|
656
|
+
|
|
657
|
+
export interface TaskActivityFrame extends ClusterFrame {
|
|
658
|
+
type: "task_activity";
|
|
659
|
+
payload: {
|
|
660
|
+
taskId: string;
|
|
661
|
+
taskType: "acp" | "handoff";
|
|
662
|
+
status: TaskActivityStatus;
|
|
663
|
+
agent: string;
|
|
664
|
+
nodeId: string; // node where task is running
|
|
665
|
+
title: string;
|
|
666
|
+
detail?: string;
|
|
667
|
+
progress?: number; // 0.0 - 1.0
|
|
668
|
+
startedAt: number;
|
|
669
|
+
elapsedMs?: number;
|
|
670
|
+
tool?: string; // current tool being executed
|
|
671
|
+
toolDone?: boolean;
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
// ── Peer approval ────────────────────────────────────────────────
|
|
676
|
+
export interface PeerApprovalNotify extends ClusterFrame {
|
|
677
|
+
type: "peer_approval_notify";
|
|
678
|
+
payload: {
|
|
679
|
+
approvalId: string;
|
|
680
|
+
nodeId: string;
|
|
681
|
+
deviceInfo?: DeviceInfo;
|
|
682
|
+
mode: "notify" | "required";
|
|
683
|
+
ip?: string;
|
|
684
|
+
/** Present when this is a resolution notification (approved/denied). */
|
|
685
|
+
resolution?: {
|
|
686
|
+
decision: "approve" | "deny";
|
|
687
|
+
resolvedBy: string;
|
|
688
|
+
};
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
export interface PeerApprovalRequest extends ClusterFrame {
|
|
693
|
+
type: "peer_approval_req";
|
|
694
|
+
id: string;
|
|
695
|
+
payload: {
|
|
696
|
+
approvalId: string;
|
|
697
|
+
nodeId: string;
|
|
698
|
+
deviceInfo?: DeviceInfo;
|
|
699
|
+
ip?: string;
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
export interface PeerApprovalResponse extends ClusterFrame {
|
|
704
|
+
type: "peer_approval_res";
|
|
705
|
+
id: string;
|
|
706
|
+
payload: {
|
|
707
|
+
approvalId: string;
|
|
708
|
+
decision: "approve" | "deny";
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// ── Terminal (interactive PTY over WebSocket) ─────────────────────
|
|
713
|
+
|
|
714
|
+
export interface TerminalOpenRequest extends ClusterFrame {
|
|
715
|
+
type: "terminal_open";
|
|
716
|
+
id: string;
|
|
717
|
+
payload: {
|
|
718
|
+
shell?: string;
|
|
719
|
+
cols?: number;
|
|
720
|
+
rows?: number;
|
|
721
|
+
cwd?: string;
|
|
722
|
+
env?: Record<string, string>;
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
export interface TerminalOpenResponse extends ClusterFrame {
|
|
727
|
+
type: "terminal_open_res";
|
|
728
|
+
id: string;
|
|
729
|
+
payload: {
|
|
730
|
+
success: boolean;
|
|
731
|
+
sessionId?: string;
|
|
732
|
+
error?: string;
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
export interface TerminalData extends ClusterFrame {
|
|
737
|
+
type: "terminal_data";
|
|
738
|
+
id: string;
|
|
739
|
+
payload: {
|
|
740
|
+
sessionId: string;
|
|
741
|
+
data: string; // base64-encoded
|
|
742
|
+
direction: "input" | "output";
|
|
743
|
+
};
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
export interface TerminalResize extends ClusterFrame {
|
|
747
|
+
type: "terminal_resize";
|
|
748
|
+
id: string;
|
|
749
|
+
payload: {
|
|
750
|
+
sessionId: string;
|
|
751
|
+
cols: number;
|
|
752
|
+
rows: number;
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
export interface TerminalCloseRequest extends ClusterFrame {
|
|
757
|
+
type: "terminal_close";
|
|
758
|
+
id: string;
|
|
759
|
+
payload: {
|
|
760
|
+
sessionId: string;
|
|
761
|
+
exitCode?: number;
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
export interface TerminalCloseResponse extends ClusterFrame {
|
|
766
|
+
type: "terminal_close_res";
|
|
767
|
+
id: string;
|
|
768
|
+
payload: {
|
|
769
|
+
success: boolean;
|
|
770
|
+
error?: string;
|
|
332
771
|
};
|
|
333
772
|
}
|
|
334
773
|
|
|
@@ -336,6 +775,8 @@ export interface KnowledgeSyncFrame extends ClusterFrame {
|
|
|
336
775
|
export type AnyClusterFrame =
|
|
337
776
|
| AuthChallenge
|
|
338
777
|
| AuthRequest
|
|
778
|
+
| AuthKeyExchange
|
|
779
|
+
| AuthVerify
|
|
339
780
|
| AuthOk
|
|
340
781
|
| AuthFail
|
|
341
782
|
| PeerSync
|
|
@@ -357,4 +798,37 @@ export type AnyClusterFrame =
|
|
|
357
798
|
| HandoffInput
|
|
358
799
|
| ToolProxyRequest
|
|
359
800
|
| ToolProxyResponse
|
|
360
|
-
|
|
|
801
|
+
| ToolBatchRequest
|
|
802
|
+
| ToolBatchResponse
|
|
803
|
+
| DiagnosticExec
|
|
804
|
+
| DiagnosticExecResponse
|
|
805
|
+
| DiagnosticStatus
|
|
806
|
+
| DiagnosticStatusResponse
|
|
807
|
+
| KnowledgeSyncFrame
|
|
808
|
+
| AcpTaskRequest
|
|
809
|
+
| AcpStreamChunk
|
|
810
|
+
| AcpTaskResponse
|
|
811
|
+
| AcpCloseRequest
|
|
812
|
+
| AcpCloseResponse
|
|
813
|
+
| AcpListRequest
|
|
814
|
+
| AcpListResponse
|
|
815
|
+
| AcpResumeRequest
|
|
816
|
+
| AcpResumeResponse
|
|
817
|
+
| AcpCancelRequest
|
|
818
|
+
| AcpCancelResponse
|
|
819
|
+
| AcpSetModeRequest
|
|
820
|
+
| AcpSetModeResponse
|
|
821
|
+
| AcpGetModesRequest
|
|
822
|
+
| AcpGetModesResponse
|
|
823
|
+
| ChatHistoryRequest
|
|
824
|
+
| ChatHistoryResponse
|
|
825
|
+
| PeerApprovalNotify
|
|
826
|
+
| PeerApprovalRequest
|
|
827
|
+
| PeerApprovalResponse
|
|
828
|
+
| TaskActivityFrame
|
|
829
|
+
| TerminalOpenRequest
|
|
830
|
+
| TerminalOpenResponse
|
|
831
|
+
| TerminalData
|
|
832
|
+
| TerminalResize
|
|
833
|
+
| TerminalCloseRequest
|
|
834
|
+
| TerminalCloseResponse;
|
package/src/web.ts
CHANGED
|
@@ -288,14 +288,14 @@ export class WebHandler {
|
|
|
288
288
|
} : undefined,
|
|
289
289
|
clusterTools: [
|
|
290
290
|
"cluster_handoff", "cluster_send", "cluster_peers",
|
|
291
|
-
"cluster_exec", "cluster_read", "cluster_write", "
|
|
291
|
+
"cluster_exec", "cluster_read", "cluster_write", "cluster_edit",
|
|
292
292
|
],
|
|
293
293
|
};
|
|
294
294
|
|
|
295
295
|
// All mesh peers share these cluster tools (they all run the ClawMatrix plugin)
|
|
296
296
|
const CLUSTER_TOOLS = [
|
|
297
297
|
"cluster_handoff", "cluster_send", "cluster_peers",
|
|
298
|
-
"cluster_exec", "cluster_read", "cluster_write", "
|
|
298
|
+
"cluster_exec", "cluster_read", "cluster_write", "cluster_edit",
|
|
299
299
|
];
|
|
300
300
|
|
|
301
301
|
const peerNodes: Record<string, unknown>[] = peers.map((p) => ({
|