clawmatrix 0.2.11 → 0.3.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/src/types.ts CHANGED
@@ -420,10 +420,20 @@ export interface ModelInfo {
420
420
  compat?: ModelCompatInfo;
421
421
  }
422
422
 
423
+ export interface ToolCatalogEntry {
424
+ name: string;
425
+ description: string;
426
+ usage?: string;
427
+ /** JSON Schema for the tool's input parameters (for LLM callers to construct invocations). */
428
+ inputSchema?: Record<string, unknown>;
429
+ }
430
+
423
431
  export interface ToolProxyInfo {
424
432
  enabled: boolean;
425
433
  allow: string[];
426
434
  deny: string[];
435
+ /** Optional tool catalog with descriptions and usage hints for remote callers. */
436
+ catalog?: ToolCatalogEntry[];
427
437
  }
428
438
 
429
439
  export interface AcpAgentInfo {
@@ -559,9 +569,10 @@ export interface AcpStreamChunk extends ClusterFrame {
559
569
  id: string;
560
570
  payload: {
561
571
  delta: string;
562
- event?: string; // "agent_message_chunk" | "tool_call" | etc.
572
+ event?: string; // "agent_message_chunk" | "tool_call" | "plan" | "available_commands" | "config_options" | "usage" | "session_info" | etc.
563
573
  done: boolean;
564
574
  sessionId?: string; // included for session watchers (multi-device sync)
575
+ data?: unknown; // structured data for rich events (plan entries, slash commands, config options, usage stats)
565
576
  };
566
577
  }
567
578
 
@@ -577,6 +588,10 @@ export interface AcpTaskResponse extends ClusterFrame {
577
588
  acpSessionId?: string; // ACP-level session ID for future resume
578
589
  stopReason?: string; // ACP stop reason
579
590
  error?: string;
591
+ configOptions?: AcpConfigOption[]; // initial config options (model, thinking level, etc.)
592
+ slashCommands?: AcpSlashCommand[]; // available slash commands
593
+ availableModes?: AcpModeInfo[]; // available session modes
594
+ currentModeId?: string; // current mode
580
595
  };
581
596
  }
582
597
 
@@ -605,6 +620,7 @@ export interface AcpSessionInfo {
605
620
  description?: string; // first user message (for display in session list)
606
621
  updatedAt?: string;
607
622
  agent?: string; // which ACP agent (claude, codex, etc.)
623
+ status?: "active" | "idle"; // active = in-memory session with daemon, idle = persisted on disk
608
624
  }
609
625
 
610
626
  export interface AcpListRequest extends ClusterFrame {
@@ -706,6 +722,86 @@ export interface AcpGetModesResponse extends ClusterFrame {
706
722
  };
707
723
  }
708
724
 
725
+ // ── ACP config options ───────────────────────────────────────────
726
+
727
+ export interface AcpConfigOption {
728
+ id: string;
729
+ name: string;
730
+ type: "select" | "boolean";
731
+ currentValue: string | boolean;
732
+ options?: Array<{ id: string; name: string; description?: string }>;
733
+ description?: string;
734
+ category?: string; // "mode" | "model" | "thought_level" | custom
735
+ }
736
+
737
+ export interface AcpSetConfigRequest extends ClusterFrame {
738
+ type: "acp_set_config";
739
+ id: string;
740
+ payload: {
741
+ sessionId: string;
742
+ configId: string;
743
+ value: string | boolean;
744
+ };
745
+ }
746
+
747
+ export interface AcpSetConfigResponse extends ClusterFrame {
748
+ type: "acp_set_config_res";
749
+ id: string;
750
+ payload: {
751
+ success: boolean;
752
+ configOptions?: AcpConfigOption[];
753
+ error?: string;
754
+ };
755
+ }
756
+
757
+ // ── ACP subscribe / observe ──────────────────────────────────────
758
+
759
+ export interface AcpSubscribeRequest extends ClusterFrame {
760
+ type: "acp_subscribe";
761
+ id: string;
762
+ payload: {
763
+ sessionId: string; // ClawMatrix session ID to observe
764
+ };
765
+ }
766
+
767
+ export interface AcpSubscribeResponse extends ClusterFrame {
768
+ type: "acp_subscribe_res";
769
+ id: string;
770
+ payload: {
771
+ success: boolean;
772
+ history?: ChatHistoryMessage[]; // snapshot at subscribe time
773
+ error?: string;
774
+ };
775
+ }
776
+
777
+ export interface AcpUnsubscribeRequest extends ClusterFrame {
778
+ type: "acp_unsubscribe";
779
+ payload: {
780
+ sessionId: string;
781
+ };
782
+ }
783
+
784
+ /** Pushed to all peers when a session is created, its title changes, or it completes. */
785
+ export interface AcpSessionNotify extends ClusterFrame {
786
+ type: "acp_session_notify";
787
+ payload: {
788
+ sessionId: string;
789
+ nodeId: string;
790
+ event: "created" | "updated" | "completed";
791
+ title?: string;
792
+ updatedAt?: string;
793
+ agent?: string;
794
+ };
795
+ }
796
+
797
+ // ── ACP slash commands ──────────────────────────────────────────
798
+
799
+ export interface AcpSlashCommand {
800
+ name: string;
801
+ description: string;
802
+ input?: { hint?: string };
803
+ }
804
+
709
805
  // ── Chat history ──────────────────────────────────────────────────
710
806
 
711
807
  export interface ChatHistoryMessage {
@@ -908,6 +1004,12 @@ export type AnyClusterFrame =
908
1004
  | AcpSetModeResponse
909
1005
  | AcpGetModesRequest
910
1006
  | AcpGetModesResponse
1007
+ | AcpSetConfigRequest
1008
+ | AcpSetConfigResponse
1009
+ | AcpSubscribeRequest
1010
+ | AcpSubscribeResponse
1011
+ | AcpUnsubscribeRequest
1012
+ | AcpSessionNotify
911
1013
  | ChatHistoryRequest
912
1014
  | ChatHistoryResponse
913
1015
  | PeerApprovalNotify
package/src/web.ts CHANGED
@@ -5,7 +5,6 @@ import type { ClawMatrixConfig } from "./config.ts";
5
5
  import type { SatelliteContext, IngestedEvent } from "./types.ts";
6
6
  import type { HealthTracker } from "./health-tracker.ts";
7
7
  import { timingSafeEqual } from "./auth.ts";
8
- import { renderDashboard } from "./web-ui.ts";
9
8
  import { readBody } from "./http-utils.ts";
10
9
 
11
10
  const COOKIE_NAME = "clawmatrix_token";
@@ -135,13 +134,6 @@ export class WebHandler {
135
134
  return true;
136
135
  }
137
136
 
138
- // Serve dashboard HTML (auth checked client-side via API)
139
- if (path === "/" && req.method === "GET") {
140
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
141
- res.end(renderDashboard(this.config.nodeId));
142
- return true;
143
- }
144
-
145
137
  // All /api/* routes require auth (async)
146
138
  if (path.startsWith("/api/")) {
147
139
  this.handleAuthenticatedRoute(req, res, path);
@@ -224,7 +216,7 @@ export class WebHandler {
224
216
  private async checkAuth(req: IncomingMessage): Promise<boolean> {
225
217
  // Check Authorization header
226
218
  const authHeader = req.headers.authorization;
227
- if (authHeader?.startsWith("Bearer ") && await timingSafeEqual(authHeader.slice(7), this.token)) {
219
+ if (authHeader?.startsWith("Bearer ") && timingSafeEqual(authHeader.slice(7), this.token)) {
228
220
  return true;
229
221
  }
230
222
 
@@ -658,7 +650,7 @@ export class WebHandler {
658
650
  ssid: ctx.ssid || undefined,
659
651
  ip: ctx.ip || undefined,
660
652
  router: ctx.router || undefined,
661
- cellular: !ctx.ssid,
653
+ cellular: typeof ctx.cellular === "boolean" ? ctx.cellular : !ctx.ssid,
662
654
  country: ctx.country || undefined,
663
655
  tools: Array.isArray(ctx.tools) ? ctx.tools : undefined,
664
656
  ts: Date.now(),