@sesamespace/hivemind 0.8.5 → 0.8.7

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,8 +1,5 @@
1
- import {
2
- SesameClient
3
- } from "./chunk-GPI4RU7N.js";
4
-
5
1
  // packages/runtime/src/llm-client.ts
2
+ import { execSync } from "child_process";
6
3
  function convertMessagesForAnthropic(messages) {
7
4
  let system = "";
8
5
  const converted = [];
@@ -75,6 +72,24 @@ function parseAnthropicResponse(data) {
75
72
  } : void 0
76
73
  };
77
74
  }
75
+ function getClaudeCodeOAuthToken() {
76
+ try {
77
+ const raw = execSync(
78
+ 'security find-generic-password -s "Claude Code-credentials" -w',
79
+ { encoding: "utf-8", timeout: 5e3 }
80
+ ).trim();
81
+ const data = JSON.parse(raw);
82
+ const oauth = data?.claudeAiOauth;
83
+ if (!oauth?.accessToken) return null;
84
+ if (oauth.expiresAt && Date.now() > oauth.expiresAt) {
85
+ console.warn("[llm] Claude Code OAuth token expired. Run: claude auth login");
86
+ return null;
87
+ }
88
+ return oauth.accessToken;
89
+ } catch {
90
+ return null;
91
+ }
92
+ }
78
93
  var LLMClient = class {
79
94
  baseUrl;
80
95
  model;
@@ -82,6 +97,7 @@ var LLMClient = class {
82
97
  temperature;
83
98
  apiKey;
84
99
  provider;
100
+ isOAuth;
85
101
  constructor(config) {
86
102
  this.baseUrl = config.base_url;
87
103
  this.model = config.model;
@@ -89,6 +105,22 @@ var LLMClient = class {
89
105
  this.temperature = config.temperature;
90
106
  this.apiKey = config.api_key ?? "";
91
107
  this.provider = config.provider ?? "openai";
108
+ this.isOAuth = false;
109
+ if (this.provider === "anthropic" && !this.apiKey) {
110
+ const token = getClaudeCodeOAuthToken();
111
+ if (token) {
112
+ this.apiKey = token;
113
+ this.isOAuth = true;
114
+ if (!this.baseUrl || this.baseUrl.includes("openrouter")) {
115
+ this.baseUrl = "https://api.anthropic.com";
116
+ }
117
+ console.log("[llm] Auth: Claude Max OAuth (from macOS Keychain)");
118
+ } else {
119
+ console.warn("[llm] Auth: No API key found for Anthropic provider");
120
+ }
121
+ } else if (this.provider === "anthropic") {
122
+ console.log("[llm] Auth: Anthropic API key (from config/env)");
123
+ }
92
124
  }
93
125
  /**
94
126
  * Simple chat completion (no tools). Backwards compatible.
@@ -181,13 +213,19 @@ var LLMClient = class {
181
213
  console.log(`[llm] Retry ${attempt}/${MAX_RETRIES} after ${delayMs}ms...`);
182
214
  await new Promise((r) => setTimeout(r, delayMs));
183
215
  }
216
+ const headers = {
217
+ "Content-Type": "application/json",
218
+ "anthropic-version": "2023-06-01"
219
+ };
220
+ if (this.isOAuth) {
221
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
222
+ headers["anthropic-beta"] = "oauth-2025-04-20";
223
+ } else {
224
+ headers["x-api-key"] = this.apiKey;
225
+ }
184
226
  const resp = await fetch(`${this.baseUrl}/v1/messages`, {
185
227
  method: "POST",
186
- headers: {
187
- "Content-Type": "application/json",
188
- "x-api-key": this.apiKey,
189
- "anthropic-version": "2023-06-01"
190
- },
228
+ headers,
191
229
  body: JSON.stringify(body)
192
230
  });
193
231
  if (!resp.ok) {
@@ -2472,6 +2510,16 @@ function loadConfig(path) {
2472
2510
  parsed.llm.base_url = "https://api.anthropic.com";
2473
2511
  }
2474
2512
  }
2513
+ if (parsed.llm.provider === "anthropic" && !parsed.llm.api_key) {
2514
+ const oauthToken = getClaudeCodeOAuthToken();
2515
+ if (oauthToken) {
2516
+ parsed.llm.api_key = oauthToken;
2517
+ if (!process.env.LLM_BASE_URL && parsed.llm.base_url.includes("openrouter")) {
2518
+ parsed.llm.base_url = "https://api.anthropic.com";
2519
+ }
2520
+ console.log("[config] Auth: Claude Max OAuth (from macOS Keychain)");
2521
+ }
2522
+ }
2475
2523
  if (process.env.LLM_PROVIDER) {
2476
2524
  parsed.llm.provider = process.env.LLM_PROVIDER;
2477
2525
  }
@@ -2519,6 +2567,626 @@ function loadConfig(path) {
2519
2567
  return parsed;
2520
2568
  }
2521
2569
 
2570
+ // node_modules/.pnpm/@sesamespace+sdk@0.1.6/node_modules/@sesamespace/sdk/dist/client.js
2571
+ import WebSocket from "ws";
2572
+
2573
+ // node_modules/.pnpm/@sesamespace+sdk@0.1.6/node_modules/@sesamespace/sdk/dist/auth.js
2574
+ import { sign } from "crypto";
2575
+ function createAuthSignature(handle, privateKeyBase64url) {
2576
+ const timestamp = Date.now();
2577
+ const message = `AUTH:${handle}:${timestamp}`;
2578
+ const privateKeyDer = Buffer.from(privateKeyBase64url, "base64url");
2579
+ const privateKey = {
2580
+ key: privateKeyDer,
2581
+ format: "der",
2582
+ type: "pkcs8"
2583
+ };
2584
+ const sig = sign(null, Buffer.from(message), privateKey);
2585
+ return {
2586
+ signature: sig.toString("base64url"),
2587
+ timestamp
2588
+ };
2589
+ }
2590
+
2591
+ // node_modules/.pnpm/@sesamespace+sdk@0.1.6/node_modules/@sesamespace/sdk/dist/client.js
2592
+ var SesameClient = class {
2593
+ config;
2594
+ ws = null;
2595
+ eventHandlers = /* @__PURE__ */ new Map();
2596
+ reconnectAttempts = 0;
2597
+ reconnectTimer = null;
2598
+ heartbeatTimer = null;
2599
+ cursors = /* @__PURE__ */ new Map();
2600
+ authenticated = false;
2601
+ constructor(config) {
2602
+ this.config = {
2603
+ autoReconnect: true,
2604
+ maxReconnectAttempts: 10,
2605
+ ...config
2606
+ };
2607
+ }
2608
+ // ── HTTP Methods ──
2609
+ async fetch(path, options = {}) {
2610
+ const headers = {
2611
+ "Content-Type": "application/json",
2612
+ ...options.headers ?? {}
2613
+ };
2614
+ if (this.config.apiKey) {
2615
+ headers["Authorization"] = `Bearer ${this.config.apiKey}`;
2616
+ } else if (this.config.token) {
2617
+ headers["Authorization"] = `Bearer ${this.config.token}`;
2618
+ } else if (this.config.agent) {
2619
+ const { signature, timestamp } = createAuthSignature(this.config.agent.handle, this.config.agent.privateKey);
2620
+ headers["Authorization"] = `Signature ${this.config.agent.handle}.${signature}.${timestamp}`;
2621
+ }
2622
+ const response = await globalThis.fetch(`${this.config.apiUrl}${path}`, {
2623
+ ...options,
2624
+ headers
2625
+ });
2626
+ if (!response.ok) {
2627
+ const error = await response.json().catch(() => ({ error: response.statusText }));
2628
+ throw new SesameApiError(response.status, error.error ?? "Request failed");
2629
+ }
2630
+ return response.json();
2631
+ }
2632
+ get(path) {
2633
+ return this.fetch(path);
2634
+ }
2635
+ post(path, body) {
2636
+ return this.fetch(path, {
2637
+ method: "POST",
2638
+ body: body ? JSON.stringify(body) : void 0
2639
+ });
2640
+ }
2641
+ patch(path, body) {
2642
+ return this.fetch(path, {
2643
+ method: "PATCH",
2644
+ body: JSON.stringify(body)
2645
+ });
2646
+ }
2647
+ del(path) {
2648
+ return this.fetch(path, { method: "DELETE" });
2649
+ }
2650
+ // ── Auth ──
2651
+ async login(email, password) {
2652
+ const result = await this.post("/api/v1/auth/login", { email, password });
2653
+ this.config.token = result.accessToken;
2654
+ return result;
2655
+ }
2656
+ // ── Channels ──
2657
+ async listChannels() {
2658
+ const result = await this.get("/api/v1/channels");
2659
+ const channels = result.data ?? result.channels ?? result;
2660
+ return { channels: Array.isArray(channels) ? channels : [] };
2661
+ }
2662
+ async getChannel(id) {
2663
+ const result = await this.get(`/api/v1/channels/${id}`);
2664
+ const channel = result.data ?? result.channel ?? result;
2665
+ return { channel };
2666
+ }
2667
+ async createChannel(data) {
2668
+ const result = await this.post("/api/v1/channels", data);
2669
+ const channel = result.data ?? result.channel ?? result;
2670
+ return { channel };
2671
+ }
2672
+ async getOrCreateDM(principalId) {
2673
+ const result = await this.post("/api/v1/channels/dm", { principalId });
2674
+ const channel = result.data ?? result.channel ?? result;
2675
+ return { channel };
2676
+ }
2677
+ async getUnread() {
2678
+ return this.get("/api/v1/channels/unread");
2679
+ }
2680
+ // ── Messages ──
2681
+ async sendMessage(channelId, options) {
2682
+ const result = await this.post(`/api/v1/channels/${channelId}/messages`, options);
2683
+ const message = this.normalizeMessage(result.data ?? result.message ?? result);
2684
+ if (message.seq) {
2685
+ this.cursors.set(channelId, message.seq);
2686
+ }
2687
+ return { message };
2688
+ }
2689
+ async getMessages(channelId, options) {
2690
+ const params = new URLSearchParams();
2691
+ if (options?.cursor)
2692
+ params.set("cursor", options.cursor.toString());
2693
+ if (options?.limit)
2694
+ params.set("limit", options.limit.toString());
2695
+ if (options?.direction)
2696
+ params.set("direction", options.direction);
2697
+ if (options?.threadRootId)
2698
+ params.set("threadRootId", options.threadRootId);
2699
+ const qs = params.toString();
2700
+ const result = await this.get(`/api/v1/channels/${channelId}/messages${qs ? `?${qs}` : ""}`);
2701
+ const messages = (result.data ?? result.messages ?? []).map((m) => this.normalizeMessage(m));
2702
+ if (messages.length > 0) {
2703
+ const maxSeq = Math.max(...messages.map((m) => m.seq));
2704
+ const current = this.cursors.get(channelId) ?? 0;
2705
+ if (maxSeq > current)
2706
+ this.cursors.set(channelId, maxSeq);
2707
+ }
2708
+ return {
2709
+ messages,
2710
+ cursor: result.pagination?.cursor ? Number(result.pagination.cursor) : 0,
2711
+ hasMore: result.pagination?.hasMore ?? false
2712
+ };
2713
+ }
2714
+ async editMessage(channelId, messageId, content) {
2715
+ const result = await this.patch(`/api/v1/channels/${channelId}/messages/${messageId}`, { content });
2716
+ const message = this.normalizeMessage(result.data ?? result.message ?? result);
2717
+ return { message };
2718
+ }
2719
+ async deleteMessage(channelId, messageId) {
2720
+ await this.del(`/api/v1/channels/${channelId}/messages/${messageId}`);
2721
+ }
2722
+ async markRead(channelId, seq) {
2723
+ await this.post(`/api/v1/channels/${channelId}/messages/read`, { seq });
2724
+ }
2725
+ async addReaction(channelId, messageId, emoji) {
2726
+ await this.post(`/api/v1/channels/${channelId}/messages/${messageId}/reactions`, { emoji });
2727
+ }
2728
+ async removeReaction(channelId, messageId, emoji) {
2729
+ await this.del(`/api/v1/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`);
2730
+ }
2731
+ // ── Vault ──
2732
+ async listVaults() {
2733
+ return this.get("/api/v1/vault/vaults");
2734
+ }
2735
+ async listVaultItems(vaultId) {
2736
+ const qs = vaultId ? `?vaultId=${vaultId}` : "";
2737
+ return this.get(`/api/v1/vault/items${qs}`);
2738
+ }
2739
+ async getVaultItem(id) {
2740
+ return this.get(`/api/v1/vault/items/${id}`);
2741
+ }
2742
+ async createVaultItem(options) {
2743
+ return this.post("/api/v1/vault/items", options);
2744
+ }
2745
+ async revealItem(id, fields) {
2746
+ return this.post(`/api/v1/vault/items/${id}/reveal`, fields ? { fields } : void 0);
2747
+ }
2748
+ async shareItem(itemId, principalId, options) {
2749
+ await this.post(`/api/v1/vault/items/${itemId}/share`, {
2750
+ principalId,
2751
+ ...options
2752
+ });
2753
+ }
2754
+ async revokeShare(itemId, principalId) {
2755
+ await this.del(`/api/v1/vault/items/${itemId}/share/${principalId}`);
2756
+ }
2757
+ async getWallet() {
2758
+ return this.get("/api/v1/vault/wallet");
2759
+ }
2760
+ // ── Leases ──
2761
+ async requestLease(options) {
2762
+ return this.post("/api/v1/vault/leases/request", options);
2763
+ }
2764
+ async approveLease(leaseId, options) {
2765
+ return this.post(`/api/v1/vault/leases/${leaseId}/approve`, options ?? {});
2766
+ }
2767
+ async denyLease(leaseId) {
2768
+ return this.post(`/api/v1/vault/leases/${leaseId}/deny`, {});
2769
+ }
2770
+ async useSecret(leaseId) {
2771
+ return this.post(`/api/v1/vault/leases/${leaseId}/use`, {});
2772
+ }
2773
+ async revokeLease(leaseId) {
2774
+ await this.del(`/api/v1/vault/leases/${leaseId}`);
2775
+ }
2776
+ // ── HTTP helper: PUT ──
2777
+ put(path, body) {
2778
+ return this.fetch(path, {
2779
+ method: "PUT",
2780
+ body: body ? JSON.stringify(body) : void 0
2781
+ });
2782
+ }
2783
+ // ── Agents ──
2784
+ async listAgents() {
2785
+ return this.get("/api/v1/agents");
2786
+ }
2787
+ async provisionAgent(data) {
2788
+ return this.post("/api/v1/agents", data);
2789
+ }
2790
+ async generateApiKey(agentId, label) {
2791
+ const res = await this.post(`/api/v1/agents/${agentId}/api-keys`, { label });
2792
+ return res.data ?? res;
2793
+ }
2794
+ // ── Capabilities ──
2795
+ async registerCapabilities(capabilities) {
2796
+ const agentId = this.getAgentId();
2797
+ const result = await this.put(`/api/v1/agents/${agentId}/capabilities`, { capabilities });
2798
+ return { capabilities: result.data ?? result };
2799
+ }
2800
+ async addCapability(capability) {
2801
+ const agentId = this.getAgentId();
2802
+ const result = await this.post(`/api/v1/agents/${agentId}/capabilities`, capability);
2803
+ return { capability: result.data ?? result };
2804
+ }
2805
+ async getCapabilities(agentId) {
2806
+ const id = agentId ?? this.getAgentId();
2807
+ const result = await this.get(`/api/v1/agents/${id}/capabilities`);
2808
+ return { capabilities: result.data ?? result };
2809
+ }
2810
+ async removeCapability(capabilityId) {
2811
+ const agentId = this.getAgentId();
2812
+ await this.del(`/api/v1/agents/${agentId}/capabilities/${capabilityId}`);
2813
+ }
2814
+ // ── Discovery ──
2815
+ async discoverAgents(query = {}) {
2816
+ const params = new URLSearchParams();
2817
+ if (query.namespace)
2818
+ params.set("namespace", query.namespace);
2819
+ if (query.name)
2820
+ params.set("name", query.name);
2821
+ if (query.capability) {
2822
+ const caps = Array.isArray(query.capability) ? query.capability : [query.capability];
2823
+ for (const cap of caps) {
2824
+ params.append("capability", cap);
2825
+ }
2826
+ }
2827
+ if (query.active !== void 0)
2828
+ params.set("active", String(query.active));
2829
+ const qs = params.toString();
2830
+ const result = await this.get(`/api/v1/agents/discover${qs ? `?${qs}` : ""}`);
2831
+ return { agents: result.data ?? result };
2832
+ }
2833
+ // ── Manifest & Context ──
2834
+ async getManifest() {
2835
+ if (!this._principalId) {
2836
+ const me = await this.get("/api/v1/auth/me");
2837
+ this.setPrincipalId(me.data?.id ?? me.id);
2838
+ }
2839
+ const agentId = this.getAgentId();
2840
+ const result = await this.get(`/api/v1/agents/${agentId}/manifest`);
2841
+ return result.data ?? result;
2842
+ }
2843
+ async getChannelContext(channelId, options) {
2844
+ const agentId = this.getAgentId();
2845
+ const params = new URLSearchParams();
2846
+ if (options?.strategy)
2847
+ params.set("strategy", options.strategy);
2848
+ if (options?.window)
2849
+ params.set("window", String(options.window));
2850
+ const qs = params.toString();
2851
+ const result = await this.get(`/api/v1/agents/${agentId}/channels/${channelId}/context${qs ? `?${qs}` : ""}`);
2852
+ return result.data ?? result;
2853
+ }
2854
+ // ── Channel Config ──
2855
+ async setChannelConfig(channelId, config) {
2856
+ const agentId = this.getAgentId();
2857
+ const result = await this.put(`/api/v1/agents/${agentId}/channels/${channelId}/config`, config);
2858
+ return result.data ?? result;
2859
+ }
2860
+ async getChannelConfig(channelId) {
2861
+ const agentId = this.getAgentId();
2862
+ const result = await this.get(`/api/v1/agents/${agentId}/channels/${channelId}/config`);
2863
+ return result.data ?? result;
2864
+ }
2865
+ async deleteChannelConfig(channelId) {
2866
+ const agentId = this.getAgentId();
2867
+ await this.del(`/api/v1/agents/${agentId}/channels/${channelId}/config`);
2868
+ }
2869
+ // ── Collaboration ──
2870
+ async createCollaborationChannel(options) {
2871
+ const result = await this.createChannel({
2872
+ kind: "topic",
2873
+ name: options.name,
2874
+ description: options.description,
2875
+ memberIds: options.memberIds
2876
+ });
2877
+ const channel = result.data ?? result.channel ?? result;
2878
+ const channelId = channel.id;
2879
+ if (options.context) {
2880
+ await this.put(`/api/v1/channels/${channelId}/context`, { context: options.context });
2881
+ }
2882
+ if (options.visibility) {
2883
+ await this.patch(`/api/v1/channels/${channelId}`, { visibility: options.visibility });
2884
+ }
2885
+ if (options.coordinationMode) {
2886
+ await this.put(`/api/v1/channels/${channelId}/coordination`, {
2887
+ mode: options.coordinationMode
2888
+ });
2889
+ }
2890
+ return { channel };
2891
+ }
2892
+ // ── Tasks ──
2893
+ async createTask(channelId, options) {
2894
+ const result = await this.post(`/api/v1/channels/${channelId}/tasks`, options);
2895
+ return { task: result.data ?? result };
2896
+ }
2897
+ async listTasks(channelId, filters) {
2898
+ const params = new URLSearchParams();
2899
+ if (filters?.status)
2900
+ params.set("status", filters.status);
2901
+ if (filters?.priority)
2902
+ params.set("priority", filters.priority);
2903
+ if (filters?.assigneeId)
2904
+ params.set("assigneeId", filters.assigneeId);
2905
+ const qs = params.toString();
2906
+ const result = await this.get(`/api/v1/channels/${channelId}/tasks${qs ? `?${qs}` : ""}`);
2907
+ return { tasks: result.data ?? result };
2908
+ }
2909
+ async updateTask(channelId, taskId, updates) {
2910
+ const result = await this.patch(`/api/v1/channels/${channelId}/tasks/${taskId}`, updates);
2911
+ return { task: result.data ?? result };
2912
+ }
2913
+ async claimTask(channelId, taskId) {
2914
+ const result = await this.post(`/api/v1/channels/${channelId}/tasks/${taskId}/claim`);
2915
+ return { task: result.data ?? result };
2916
+ }
2917
+ async addTaskAssignee(channelId, taskId, principalId, role) {
2918
+ const result = await this.post(`/api/v1/channels/${channelId}/tasks/${taskId}/assignees`, { principalId, role });
2919
+ return { task: result.data ?? result };
2920
+ }
2921
+ async removeTaskAssignee(channelId, taskId, principalId) {
2922
+ const result = await this.del(`/api/v1/channels/${channelId}/tasks/${taskId}/assignees/${principalId}`);
2923
+ return { task: result.data ?? result };
2924
+ }
2925
+ async createTaskChannel(channelId, taskId, options) {
2926
+ const result = await this.post(`/api/v1/channels/${channelId}/tasks/${taskId}/channel`, options ?? {});
2927
+ return result.data ?? result;
2928
+ }
2929
+ // ── Webhooks ──
2930
+ async createWebhook(options) {
2931
+ const agentId = this.getAgentId();
2932
+ const result = await this.post(`/api/v1/agents/${agentId}/webhooks`, options);
2933
+ return { webhook: result.data ?? result };
2934
+ }
2935
+ async listWebhooks() {
2936
+ const agentId = this.getAgentId();
2937
+ const result = await this.get(`/api/v1/agents/${agentId}/webhooks`);
2938
+ return { webhooks: result.data ?? result };
2939
+ }
2940
+ async updateWebhook(webhookId, updates) {
2941
+ const agentId = this.getAgentId();
2942
+ const result = await this.patch(`/api/v1/agents/${agentId}/webhooks/${webhookId}`, updates);
2943
+ return { webhook: result.data ?? result };
2944
+ }
2945
+ async deleteWebhook(webhookId) {
2946
+ const agentId = this.getAgentId();
2947
+ await this.del(`/api/v1/agents/${agentId}/webhooks/${webhookId}`);
2948
+ }
2949
+ async rotateWebhookSecret(webhookId) {
2950
+ const agentId = this.getAgentId();
2951
+ const result = await this.post(`/api/v1/agents/${agentId}/webhooks/${webhookId}/rotate-secret`);
2952
+ return result.data ?? result;
2953
+ }
2954
+ async listWebhookDeliveries(webhookId, options) {
2955
+ const agentId = this.getAgentId();
2956
+ const params = new URLSearchParams();
2957
+ if (options?.limit)
2958
+ params.set("limit", String(options.limit));
2959
+ if (options?.status)
2960
+ params.set("status", options.status);
2961
+ const qs = params.toString();
2962
+ const result = await this.get(`/api/v1/agents/${agentId}/webhooks/${webhookId}/deliveries${qs ? `?${qs}` : ""}`);
2963
+ return { deliveries: result.data ?? result };
2964
+ }
2965
+ // ── Profile ──
2966
+ async setReadReceiptEmoji(emoji) {
2967
+ const agentId = this.getAgentId();
2968
+ const result = await this.put(`/api/v1/agents/${agentId}/read-receipt-emoji`, { emoji });
2969
+ return { emoji: result.data?.emoji ?? emoji };
2970
+ }
2971
+ async getReadReceiptEmoji() {
2972
+ const agentId = this.getAgentId();
2973
+ const result = await this.get(`/api/v1/agents/${agentId}/read-receipt-emoji`);
2974
+ return { emoji: result.data?.emoji ?? "\u{1F440}" };
2975
+ }
2976
+ // ── Internal helpers ──
2977
+ normalizeMessage(msg) {
2978
+ return {
2979
+ ...msg,
2980
+ content: msg.content ?? msg.plaintext ?? null
2981
+ };
2982
+ }
2983
+ getAgentId() {
2984
+ const principal = this._principalId;
2985
+ if (principal)
2986
+ return principal;
2987
+ throw new SesameApiError(400, "Agent ID not resolved. Call boot() or setPrincipalId(id) first.");
2988
+ }
2989
+ /**
2990
+ * Set the current agent's principal ID (resolved after auth).
2991
+ */
2992
+ setPrincipalId(id) {
2993
+ this._principalId = id;
2994
+ }
2995
+ /**
2996
+ * Bootstrap the agent: resolves identity via /auth/me and loads manifest.
2997
+ */
2998
+ async boot() {
2999
+ const me = await this.get("/api/v1/auth/me");
3000
+ const principal = me.data ?? me;
3001
+ this.setPrincipalId(principal.id);
3002
+ const manifest = await this.getManifest();
3003
+ return manifest;
3004
+ }
3005
+ // ── WebSocket ──
3006
+ /**
3007
+ * Connect to the real-time WebSocket gateway.
3008
+ */
3009
+ connect() {
3010
+ return new Promise((resolve20, reject) => {
3011
+ try {
3012
+ this.ws = new WebSocket(`${this.config.wsUrl}/v1/connect`);
3013
+ this.ws.on("open", () => {
3014
+ this.reconnectAttempts = 0;
3015
+ this.sendAuth();
3016
+ });
3017
+ this.ws.on("message", (data) => {
3018
+ try {
3019
+ const event = JSON.parse(data.toString());
3020
+ if (event.type === "authenticated") {
3021
+ this.authenticated = true;
3022
+ this.startHeartbeat(event.heartbeatIntervalMs ?? 3e4);
3023
+ this.sendReplay();
3024
+ resolve20();
3025
+ return;
3026
+ }
3027
+ if (event.type === "pong")
3028
+ return;
3029
+ if (event.type === "error") {
3030
+ console.error("WS error:", event.message);
3031
+ return;
3032
+ }
3033
+ if (event.type === "message" && event.data) {
3034
+ event.data = this.normalizeMessage(event.data);
3035
+ const seq = event.data.seq;
3036
+ if (seq) {
3037
+ const channelId = event.data.channelId;
3038
+ const current = this.cursors.get(channelId) ?? 0;
3039
+ if (seq > current)
3040
+ this.cursors.set(channelId, seq);
3041
+ }
3042
+ }
3043
+ this.emit(event);
3044
+ } catch {
3045
+ }
3046
+ });
3047
+ this.ws.on("close", () => {
3048
+ this.authenticated = false;
3049
+ this.stopHeartbeat();
3050
+ if (this.config.autoReconnect) {
3051
+ this.scheduleReconnect();
3052
+ }
3053
+ });
3054
+ this.ws.on("error", (err) => {
3055
+ if (!this.authenticated) {
3056
+ reject(err);
3057
+ }
3058
+ });
3059
+ } catch (err) {
3060
+ reject(err);
3061
+ }
3062
+ });
3063
+ }
3064
+ /**
3065
+ * Disconnect from the WebSocket gateway.
3066
+ */
3067
+ disconnect() {
3068
+ this.config.autoReconnect = false;
3069
+ this.stopHeartbeat();
3070
+ if (this.reconnectTimer) {
3071
+ clearTimeout(this.reconnectTimer);
3072
+ this.reconnectTimer = null;
3073
+ }
3074
+ if (this.ws) {
3075
+ this.ws.close();
3076
+ this.ws = null;
3077
+ }
3078
+ }
3079
+ /**
3080
+ * Subscribe to WebSocket events.
3081
+ */
3082
+ on(eventType, handler) {
3083
+ if (!this.eventHandlers.has(eventType)) {
3084
+ this.eventHandlers.set(eventType, /* @__PURE__ */ new Set());
3085
+ }
3086
+ this.eventHandlers.get(eventType).add(handler);
3087
+ return () => {
3088
+ this.eventHandlers.get(eventType)?.delete(handler);
3089
+ };
3090
+ }
3091
+ /**
3092
+ * Subscribe to all events.
3093
+ */
3094
+ onAny(handler) {
3095
+ return this.on("*", handler);
3096
+ }
3097
+ emit(event) {
3098
+ this.eventHandlers.get(event.type)?.forEach((h) => h(event));
3099
+ this.eventHandlers.get("*")?.forEach((h) => h(event));
3100
+ }
3101
+ sendAuth() {
3102
+ if (!this.ws)
3103
+ return;
3104
+ if (this.config.apiKey) {
3105
+ this.ws.send(JSON.stringify({ type: "auth", apiKey: this.config.apiKey }));
3106
+ } else if (this.config.token) {
3107
+ this.ws.send(JSON.stringify({ type: "auth", token: this.config.token }));
3108
+ } else if (this.config.agent) {
3109
+ const { signature, timestamp } = createAuthSignature(this.config.agent.handle, this.config.agent.privateKey);
3110
+ this.ws.send(JSON.stringify({
3111
+ type: "auth",
3112
+ signature: {
3113
+ handle: this.config.agent.handle,
3114
+ sig: signature,
3115
+ timestamp
3116
+ }
3117
+ }));
3118
+ }
3119
+ }
3120
+ sendReplay() {
3121
+ if (!this.ws || this.cursors.size === 0)
3122
+ return;
3123
+ const cursors = {};
3124
+ this.cursors.forEach((seq, channelId) => {
3125
+ cursors[channelId] = seq;
3126
+ });
3127
+ this.ws.send(JSON.stringify({ type: "replay", cursors }));
3128
+ }
3129
+ startHeartbeat(intervalMs) {
3130
+ this.stopHeartbeat();
3131
+ this.heartbeatTimer = setInterval(() => {
3132
+ if (this.ws?.readyState === WebSocket.OPEN) {
3133
+ this.ws.send(JSON.stringify({ type: "ping" }));
3134
+ }
3135
+ }, intervalMs);
3136
+ }
3137
+ stopHeartbeat() {
3138
+ if (this.heartbeatTimer) {
3139
+ clearInterval(this.heartbeatTimer);
3140
+ this.heartbeatTimer = null;
3141
+ }
3142
+ }
3143
+ scheduleReconnect() {
3144
+ if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
3145
+ console.error("Max reconnect attempts reached");
3146
+ return;
3147
+ }
3148
+ const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts), 3e4);
3149
+ this.reconnectAttempts++;
3150
+ this.reconnectTimer = setTimeout(() => {
3151
+ this.connect().catch(() => {
3152
+ this.scheduleReconnect();
3153
+ });
3154
+ }, delay);
3155
+ }
3156
+ /**
3157
+ * Send a typing indicator for a channel.
3158
+ */
3159
+ sendTyping(channelId) {
3160
+ if (this.ws?.readyState === WebSocket.OPEN) {
3161
+ this.ws.send(JSON.stringify({ type: "typing", channelId }));
3162
+ }
3163
+ }
3164
+ /**
3165
+ * Send a message via WebSocket (alternative to HTTP).
3166
+ */
3167
+ sendWsMessage(channelId, content, options) {
3168
+ if (this.ws?.readyState === WebSocket.OPEN) {
3169
+ this.ws.send(JSON.stringify({
3170
+ type: "send",
3171
+ channelId,
3172
+ content,
3173
+ ...options
3174
+ }));
3175
+ }
3176
+ }
3177
+ };
3178
+ var SesameApiError = class extends Error {
3179
+ status;
3180
+ constructor(status, message) {
3181
+ super(message);
3182
+ this.status = status;
3183
+ this.name = "SesameApiError";
3184
+ }
3185
+ };
3186
+
3187
+ // node_modules/.pnpm/@sesamespace+sdk@0.1.6/node_modules/@sesamespace/sdk/dist/verify-webhook.js
3188
+ import { createHmac, timingSafeEqual } from "crypto";
3189
+
2522
3190
  // packages/runtime/src/sesame.ts
2523
3191
  import { readFileSync as readFileSync5 } from "fs";
2524
3192
  import { resolve as resolve4, dirname as dirname3 } from "path";
@@ -2688,7 +3356,7 @@ var SesameClient2 = class {
2688
3356
  };
2689
3357
 
2690
3358
  // packages/runtime/src/skills.ts
2691
- import { execSync } from "child_process";
3359
+ import { execSync as execSync2 } from "child_process";
2692
3360
  import { existsSync as existsSync5, readFileSync as readFileSync6, readdirSync as readdirSync3, watch as watch2, mkdirSync as mkdirSync3 } from "fs";
2693
3361
  import { resolve as resolve5 } from "path";
2694
3362
  function shellEscape(value) {
@@ -2757,7 +3425,7 @@ var SkillsEngine = class {
2757
3425
  const setupPath = resolve5(skillDir, "setup.sh");
2758
3426
  if (existsSync5(setupPath)) {
2759
3427
  try {
2760
- execSync("bash setup.sh", { cwd: skillDir, timeout: 3e4, stdio: "pipe" });
3428
+ execSync2("bash setup.sh", { cwd: skillDir, timeout: 3e4, stdio: "pipe" });
2761
3429
  console.log(`[skills] Ran setup.sh for "${name}"`);
2762
3430
  } catch (err) {
2763
3431
  console.warn(`[skills] setup.sh failed for "${name}":`, err.message);
@@ -2782,7 +3450,7 @@ var SkillsEngine = class {
2782
3450
  async (params) => {
2783
3451
  const cmd = renderCommand(commandTemplate, params, skillDir, this.workspaceDir);
2784
3452
  try {
2785
- const output = execSync(cmd, {
3453
+ const output = execSync2(cmd, {
2786
3454
  cwd: skillDir,
2787
3455
  timeout: 6e4,
2788
3456
  encoding: "utf-8",
@@ -2821,7 +3489,7 @@ var SkillsEngine = class {
2821
3489
  const teardownPath = resolve5(skill.path, "teardown.sh");
2822
3490
  if (existsSync5(teardownPath)) {
2823
3491
  try {
2824
- execSync("bash teardown.sh", { cwd: skill.path, timeout: 3e4, stdio: "pipe" });
3492
+ execSync2("bash teardown.sh", { cwd: skill.path, timeout: 3e4, stdio: "pipe" });
2825
3493
  console.log(`[skills] Ran teardown.sh for "${skill.name}"`);
2826
3494
  } catch (err) {
2827
3495
  console.warn(`[skills] teardown.sh failed for "${skill.name}":`, err.message);
@@ -3217,7 +3885,7 @@ var ToolRegistry = class {
3217
3885
  };
3218
3886
 
3219
3887
  // packages/runtime/src/tools/shell.ts
3220
- import { execSync as execSync2 } from "child_process";
3888
+ import { execSync as execSync3 } from "child_process";
3221
3889
  import { resolve as resolve7 } from "path";
3222
3890
  var MAX_OUTPUT = 5e4;
3223
3891
  function registerShellTool(registry, workspaceDir) {
@@ -3247,7 +3915,7 @@ function registerShellTool(registry, workspaceDir) {
3247
3915
  const timeout = (params.timeout || 30) * 1e3;
3248
3916
  const cwd = params.workdir ? resolve7(workspaceDir, params.workdir) : workspaceDir;
3249
3917
  try {
3250
- const output = execSync2(command, {
3918
+ const output = execSync3(command, {
3251
3919
  cwd,
3252
3920
  timeout,
3253
3921
  encoding: "utf-8",
@@ -4120,7 +4788,7 @@ function registerVisionTools(registry) {
4120
4788
  }
4121
4789
 
4122
4790
  // packages/runtime/src/tools/git.ts
4123
- import { execSync as execSync3 } from "child_process";
4791
+ import { execSync as execSync4 } from "child_process";
4124
4792
  import { resolve as resolve10, normalize } from "path";
4125
4793
  function resolveRepoPath(workspaceDir, repoPath) {
4126
4794
  if (!repoPath) return workspaceDir;
@@ -4133,7 +4801,7 @@ function resolveRepoPath(workspaceDir, repoPath) {
4133
4801
  return resolved;
4134
4802
  }
4135
4803
  function runGit(args, cwd) {
4136
- const output = execSync3(`git ${args}`, {
4804
+ const output = execSync4(`git ${args}`, {
4137
4805
  cwd,
4138
4806
  timeout: 3e4,
4139
4807
  encoding: "utf-8",
@@ -4540,7 +5208,7 @@ function registerBrowserTools(registry, workspaceDir) {
4540
5208
  }
4541
5209
 
4542
5210
  // packages/runtime/src/tools/system.ts
4543
- import { execSync as execSync4 } from "child_process";
5211
+ import { execSync as execSync5 } from "child_process";
4544
5212
  import * as os from "os";
4545
5213
  var MAX_OUTPUT3 = 5e4;
4546
5214
  function truncate(output) {
@@ -4551,7 +5219,7 @@ function truncate(output) {
4551
5219
  return output;
4552
5220
  }
4553
5221
  function exec(cmd, timeoutS = 10) {
4554
- return execSync4(cmd, {
5222
+ return execSync5(cmd, {
4555
5223
  encoding: "utf-8",
4556
5224
  timeout: timeoutS * 1e3,
4557
5225
  maxBuffer: 10 * 1024 * 1024,
@@ -5142,13 +5810,13 @@ ${lines.join("\n")}`;
5142
5810
  }
5143
5811
 
5144
5812
  // packages/runtime/src/tools/macos.ts
5145
- import { execSync as execSync5 } from "child_process";
5813
+ import { execSync as execSync6 } from "child_process";
5146
5814
  import { resolve as resolve14, normalize as normalize2 } from "path";
5147
5815
  import { mkdirSync as mkdirSync10, existsSync as existsSync13 } from "fs";
5148
5816
  import { randomUUID as randomUUID7 } from "crypto";
5149
5817
  var MAX_OUTPUT4 = 5e4;
5150
5818
  function shellExec(command, timeoutMs) {
5151
- return execSync5(command, {
5819
+ return execSync6(command, {
5152
5820
  timeout: timeoutMs,
5153
5821
  encoding: "utf-8",
5154
5822
  maxBuffer: 10 * 1024 * 1024,
@@ -5259,7 +5927,7 @@ ${output || err.message}`;
5259
5927
  async (params) => {
5260
5928
  const content = params.content;
5261
5929
  try {
5262
- execSync5("pbcopy", {
5930
+ execSync6("pbcopy", {
5263
5931
  input: content,
5264
5932
  timeout: 5e3,
5265
5933
  encoding: "utf-8",
@@ -5359,12 +6027,12 @@ function escapeAppleString(s) {
5359
6027
  }
5360
6028
 
5361
6029
  // packages/runtime/src/tools/data.ts
5362
- import { execSync as execSync6 } from "child_process";
6030
+ import { execSync as execSync7 } from "child_process";
5363
6031
  import { resolve as resolve15, normalize as normalize3, extname as extname2 } from "path";
5364
6032
  import { mkdirSync as mkdirSync11, existsSync as existsSync14 } from "fs";
5365
6033
  var MAX_OUTPUT5 = 5e4;
5366
6034
  function shellExec2(command, cwd, timeoutMs) {
5367
- return execSync6(command, {
6035
+ return execSync7(command, {
5368
6036
  cwd,
5369
6037
  timeout: timeoutMs,
5370
6038
  encoding: "utf-8",
@@ -5605,7 +6273,7 @@ function truncate2(text) {
5605
6273
  }
5606
6274
 
5607
6275
  // packages/runtime/src/tools/coding-agent.ts
5608
- import { execSync as execSync7 } from "child_process";
6276
+ import { execSync as execSync8 } from "child_process";
5609
6277
  import { resolve as resolve16 } from "path";
5610
6278
  var MAX_OUTPUT6 = 5e4;
5611
6279
  function registerCodingAgentTools(registry, workspaceDir) {
@@ -5635,14 +6303,14 @@ function registerCodingAgentTools(registry, workspaceDir) {
5635
6303
  const timeoutSeconds = params.timeout || 300;
5636
6304
  const cwd = params.workdir ? resolve16(workspaceDir, params.workdir) : workspaceDir;
5637
6305
  try {
5638
- execSync7("which claude", { stdio: "ignore" });
6306
+ execSync8("which claude", { stdio: "ignore" });
5639
6307
  } catch {
5640
6308
  return "Error: 'claude' CLI not found. Install Claude Code first: https://docs.anthropic.com/en/docs/claude-code";
5641
6309
  }
5642
6310
  const escapedTask = task.replace(/'/g, "'\\''");
5643
6311
  const command = `claude --dangerously-skip-permissions -p '${escapedTask}'`;
5644
6312
  try {
5645
- const output = execSync7(command, {
6313
+ const output = execSync8(command, {
5646
6314
  cwd,
5647
6315
  timeout: timeoutSeconds * 1e3,
5648
6316
  encoding: "utf-8",
@@ -6656,6 +7324,7 @@ async function startWorker(config) {
6656
7324
  }
6657
7325
 
6658
7326
  export {
7327
+ getClaudeCodeOAuthToken,
6659
7328
  LLMClient,
6660
7329
  MemoryClient,
6661
7330
  ContextManager,
@@ -6671,7 +7340,8 @@ export {
6671
7340
  EventsWatcher,
6672
7341
  defaultSentinelConfig,
6673
7342
  loadConfig,
6674
- SesameClient2 as SesameClient,
7343
+ SesameClient,
7344
+ SesameClient2,
6675
7345
  HEALTH_PATH,
6676
7346
  SkillsEngine,
6677
7347
  startPipeline,
@@ -6723,4 +7393,4 @@ smol-toml/dist/index.js:
6723
7393
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6724
7394
  *)
6725
7395
  */
6726
- //# sourceMappingURL=chunk-Q5ZO5WXM.js.map
7396
+ //# sourceMappingURL=chunk-KYNTNQXV.js.map