@mcp-fe/mcp-worker 0.0.17 → 0.1.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.
@@ -27614,185 +27614,241 @@ var Server = class extends Protocol {
27614
27614
  }
27615
27615
  };
27616
27616
 
27617
- // libs/mcp-worker/src/lib/mcp-server.ts
27618
- var mcpServer = new Server(
27617
+ // libs/mcp-worker/src/lib/tool-registry.ts
27618
+ var ToolRegistry = class {
27619
+ tools = /* @__PURE__ */ new Map();
27620
+ handlers = /* @__PURE__ */ new Map();
27621
+ register(definition, handler) {
27622
+ this.tools.set(definition.name, definition);
27623
+ this.handlers.set(definition.name, handler);
27624
+ }
27625
+ unregister(name) {
27626
+ const deleted = this.tools.delete(name);
27627
+ this.handlers.delete(name);
27628
+ return deleted;
27629
+ }
27630
+ getTools() {
27631
+ return Array.from(this.tools.values());
27632
+ }
27633
+ getHandler(name) {
27634
+ return this.handlers.get(name);
27635
+ }
27636
+ clear() {
27637
+ this.tools.clear();
27638
+ this.handlers.clear();
27639
+ }
27640
+ };
27641
+ var toolRegistry = new ToolRegistry();
27642
+
27643
+ // libs/mcp-worker/src/lib/built-in-tools.ts
27644
+ var builtInTools = [
27645
+ // get_user_events tool
27619
27646
  {
27620
- name: "mcp-worker-server",
27621
- version: "1.0.0"
27647
+ definition: {
27648
+ name: "get_user_events",
27649
+ description: "Get user activity events (navigation, clicks, etc.)",
27650
+ inputSchema: {
27651
+ type: "object",
27652
+ properties: {
27653
+ type: {
27654
+ type: "string",
27655
+ enum: ["navigation", "click", "input", "custom"],
27656
+ description: "Filter by event type"
27657
+ },
27658
+ startTime: {
27659
+ type: "number",
27660
+ description: "Start timestamp (Unix timestamp in milliseconds)"
27661
+ },
27662
+ endTime: {
27663
+ type: "number",
27664
+ description: "End timestamp (Unix timestamp in milliseconds)"
27665
+ },
27666
+ path: {
27667
+ type: "string",
27668
+ description: "Filter by path/URL"
27669
+ },
27670
+ limit: {
27671
+ type: "number",
27672
+ description: "Maximum number of events to return",
27673
+ default: 100
27674
+ }
27675
+ }
27676
+ }
27677
+ },
27678
+ handler: async (args) => {
27679
+ const schema = external_exports3.object({
27680
+ type: external_exports3.enum(["navigation", "click", "input", "custom"]).optional(),
27681
+ startTime: external_exports3.number().optional(),
27682
+ endTime: external_exports3.number().optional(),
27683
+ path: external_exports3.string().optional(),
27684
+ limit: external_exports3.number().optional().default(100)
27685
+ });
27686
+ const validatedArgs = schema.parse(args || {});
27687
+ const events = await queryEvents(validatedArgs);
27688
+ return {
27689
+ content: [
27690
+ {
27691
+ type: "text",
27692
+ text: JSON.stringify({ events }, null, 2)
27693
+ }
27694
+ ]
27695
+ };
27696
+ }
27622
27697
  },
27698
+ // get_navigation_history tool
27623
27699
  {
27624
- capabilities: {
27625
- tools: {}
27626
- }
27627
- }
27628
- );
27629
- mcpServer.setRequestHandler(ListToolsRequestSchema, async () => {
27630
- return {
27631
- tools: [
27632
- {
27633
- name: "get_user_events",
27634
- description: "Get user activity events (navigation, clicks, etc.)",
27635
- inputSchema: {
27636
- type: "object",
27637
- properties: {
27638
- type: {
27639
- type: "string",
27640
- enum: ["navigation", "click", "input", "custom"],
27641
- description: "Filter by event type"
27642
- },
27643
- startTime: {
27644
- type: "number",
27645
- description: "Start timestamp (Unix timestamp in milliseconds)"
27646
- },
27647
- endTime: {
27648
- type: "number",
27649
- description: "End timestamp (Unix timestamp in milliseconds)"
27650
- },
27651
- path: {
27652
- type: "string",
27653
- description: "Filter by path/URL"
27654
- },
27655
- limit: {
27656
- type: "number",
27657
- description: "Maximum number of events to return",
27658
- default: 100
27659
- }
27700
+ definition: {
27701
+ name: "get_navigation_history",
27702
+ description: "Get user navigation history",
27703
+ inputSchema: {
27704
+ type: "object",
27705
+ properties: {
27706
+ limit: {
27707
+ type: "number",
27708
+ description: "Maximum number of navigation events to return",
27709
+ default: 50
27660
27710
  }
27661
27711
  }
27662
- },
27663
- {
27664
- name: "get_navigation_history",
27665
- description: "Get user navigation history",
27666
- inputSchema: {
27667
- type: "object",
27668
- properties: {
27669
- limit: {
27670
- type: "number",
27671
- description: "Maximum number of navigation events to return",
27672
- default: 50
27673
- }
27712
+ }
27713
+ },
27714
+ handler: async (args) => {
27715
+ const schema = external_exports3.object({
27716
+ limit: external_exports3.number().optional().default(50)
27717
+ });
27718
+ const validatedArgs = schema.parse(args || {});
27719
+ const events = await queryEvents({
27720
+ type: "navigation",
27721
+ limit: validatedArgs.limit
27722
+ });
27723
+ return {
27724
+ content: [
27725
+ {
27726
+ type: "text",
27727
+ text: JSON.stringify(
27728
+ {
27729
+ navigationHistory: events.map((e) => ({
27730
+ from: e.from,
27731
+ to: e.to,
27732
+ path: e.path,
27733
+ timestamp: e.timestamp
27734
+ }))
27735
+ },
27736
+ null,
27737
+ 2
27738
+ )
27674
27739
  }
27675
- }
27676
- },
27677
- {
27678
- name: "get_click_events",
27679
- description: "Get user click events",
27680
- inputSchema: {
27681
- type: "object",
27682
- properties: {
27683
- element: {
27684
- type: "string",
27685
- description: "Filter by element selector or text"
27686
- },
27687
- limit: {
27688
- type: "number",
27689
- description: "Maximum number of click events to return",
27690
- default: 100
27691
- }
27740
+ ]
27741
+ };
27742
+ }
27743
+ },
27744
+ // get_click_events tool
27745
+ {
27746
+ definition: {
27747
+ name: "get_click_events",
27748
+ description: "Get user click events",
27749
+ inputSchema: {
27750
+ type: "object",
27751
+ properties: {
27752
+ element: {
27753
+ type: "string",
27754
+ description: "Filter by element selector or text"
27755
+ },
27756
+ limit: {
27757
+ type: "number",
27758
+ description: "Maximum number of click events to return",
27759
+ default: 100
27692
27760
  }
27693
27761
  }
27694
27762
  }
27695
- ]
27696
- };
27697
- });
27698
- mcpServer.setRequestHandler(
27699
- CallToolRequestSchema,
27700
- async (request) => {
27701
- const { name, arguments: args } = request.params;
27702
- switch (name) {
27703
- case "get_user_events": {
27704
- const schema = external_exports3.object({
27705
- type: external_exports3.enum(["navigation", "click", "input", "custom"]).optional(),
27706
- startTime: external_exports3.number().optional(),
27707
- endTime: external_exports3.number().optional(),
27708
- path: external_exports3.string().optional(),
27709
- limit: external_exports3.number().optional().default(100)
27710
- });
27711
- const validatedArgs = schema.parse(args || {});
27712
- const events = await queryEvents(validatedArgs);
27713
- return {
27714
- content: [
27715
- {
27716
- type: "text",
27717
- text: JSON.stringify({ events }, null, 2)
27718
- }
27719
- ]
27720
- };
27763
+ },
27764
+ handler: async (args) => {
27765
+ const schema = external_exports3.object({
27766
+ element: external_exports3.string().optional(),
27767
+ limit: external_exports3.number().optional().default(100)
27768
+ });
27769
+ const validatedArgs = schema.parse(args || {});
27770
+ const events = await queryEvents({
27771
+ type: "click",
27772
+ limit: validatedArgs.limit
27773
+ });
27774
+ let filteredEvents = events;
27775
+ if (validatedArgs.element) {
27776
+ const elementFilter = validatedArgs.element.toLowerCase();
27777
+ filteredEvents = events.filter(
27778
+ (e) => e.element?.toLowerCase().includes(elementFilter) || e.elementText?.toLowerCase().includes(elementFilter) || e.elementId?.toLowerCase().includes(elementFilter) || e.elementClass?.toLowerCase().includes(elementFilter)
27779
+ );
27721
27780
  }
27722
- case "get_navigation_history": {
27723
- const schema = external_exports3.object({
27724
- limit: external_exports3.number().optional().default(50)
27725
- });
27726
- const validatedArgs = schema.parse(args || {});
27727
- const events = await queryEvents({
27728
- type: "navigation",
27729
- limit: validatedArgs.limit
27730
- });
27731
- return {
27732
- content: [
27733
- {
27734
- type: "text",
27735
- text: JSON.stringify(
27736
- {
27737
- navigationHistory: events.map((e) => ({
27738
- from: e.from,
27739
- to: e.to,
27740
- path: e.path,
27741
- timestamp: e.timestamp
27742
- }))
27743
- },
27744
- null,
27745
- 2
27746
- )
27747
- }
27748
- ]
27749
- };
27781
+ return {
27782
+ content: [
27783
+ {
27784
+ type: "text",
27785
+ text: JSON.stringify(
27786
+ {
27787
+ clickEvents: filteredEvents.map((e) => ({
27788
+ element: e.element,
27789
+ elementId: e.elementId,
27790
+ elementClass: e.elementClass,
27791
+ elementText: e.elementText,
27792
+ path: e.path,
27793
+ timestamp: e.timestamp,
27794
+ metadata: e.metadata
27795
+ }))
27796
+ },
27797
+ null,
27798
+ 2
27799
+ )
27800
+ }
27801
+ ]
27802
+ };
27803
+ }
27804
+ }
27805
+ ];
27806
+ function registerBuiltInTools() {
27807
+ builtInTools.forEach(({ definition, handler }) => {
27808
+ toolRegistry.register(definition, handler);
27809
+ });
27810
+ }
27811
+
27812
+ // libs/mcp-worker/src/lib/mcp-server.ts
27813
+ function createMCPServer(options = {}) {
27814
+ const {
27815
+ name = "mcp-worker-server",
27816
+ version: version2 = "1.0.0",
27817
+ autoRegisterBuiltInTools = true
27818
+ } = options;
27819
+ if (autoRegisterBuiltInTools) {
27820
+ registerBuiltInTools();
27821
+ }
27822
+ const server = new Server(
27823
+ {
27824
+ name,
27825
+ version: version2
27826
+ },
27827
+ {
27828
+ capabilities: {
27829
+ tools: {}
27750
27830
  }
27751
- case "get_click_events": {
27752
- const schema = external_exports3.object({
27753
- element: external_exports3.string().optional(),
27754
- limit: external_exports3.number().optional().default(100)
27755
- });
27756
- const validatedArgs = schema.parse(args || {});
27757
- const events = await queryEvents({
27758
- type: "click",
27759
- limit: validatedArgs.limit
27760
- });
27761
- let filteredEvents = events;
27762
- if (validatedArgs.element) {
27763
- const elementFilter = validatedArgs.element.toLowerCase();
27764
- filteredEvents = events.filter(
27765
- (e) => e.element?.toLowerCase().includes(elementFilter) || e.elementText?.toLowerCase().includes(elementFilter) || e.elementId?.toLowerCase().includes(elementFilter) || e.elementClass?.toLowerCase().includes(elementFilter)
27766
- );
27767
- }
27768
- return {
27769
- content: [
27770
- {
27771
- type: "text",
27772
- text: JSON.stringify(
27773
- {
27774
- clickEvents: filteredEvents.map((e) => ({
27775
- element: e.element,
27776
- elementId: e.elementId,
27777
- elementClass: e.elementClass,
27778
- elementText: e.elementText,
27779
- path: e.path,
27780
- timestamp: e.timestamp,
27781
- metadata: e.metadata
27782
- }))
27783
- },
27784
- null,
27785
- 2
27786
- )
27787
- }
27788
- ]
27789
- };
27831
+ }
27832
+ );
27833
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
27834
+ return {
27835
+ tools: toolRegistry.getTools()
27836
+ };
27837
+ });
27838
+ server.setRequestHandler(
27839
+ CallToolRequestSchema,
27840
+ async (request) => {
27841
+ const { name: name2, arguments: args } = request.params;
27842
+ const handler = toolRegistry.getHandler(name2);
27843
+ if (!handler) {
27844
+ throw new Error(`Unknown tool: ${name2}`);
27790
27845
  }
27791
- default:
27792
- throw new Error(`Unknown tool: ${name}`);
27846
+ return await handler(args);
27793
27847
  }
27794
- }
27795
- );
27848
+ );
27849
+ return server;
27850
+ }
27851
+ var mcpServer = createMCPServer();
27796
27852
 
27797
27853
  // libs/mcp-worker/src/lib/websocket-transport.ts
27798
27854
  var WebSocketTransport = class {
@@ -27872,6 +27928,9 @@ var MCPController = class _MCPController {
27872
27928
  keepAliveInterval = null;
27873
27929
  requireAuth;
27874
27930
  isReconnectingForToken = false;
27931
+ // Queue for tool registrations that arrive before MCP server is ready
27932
+ pendingToolRegistrations = [];
27933
+ isMCPServerReady = false;
27875
27934
  startKeepAlive() {
27876
27935
  if (this.keepAliveInterval) {
27877
27936
  clearInterval(this.keepAliveInterval);
@@ -27938,6 +27997,8 @@ var MCPController = class _MCPController {
27938
27997
  logger.log(
27939
27998
  "[MCPController] MCP Server connected to WebSocket transport"
27940
27999
  );
28000
+ this.isMCPServerReady = true;
28001
+ this.processPendingToolRegistrations();
27941
28002
  this.startKeepAlive();
27942
28003
  this.broadcastFn({ type: "CONNECTION_STATUS", connected: true });
27943
28004
  resolve();
@@ -28016,6 +28077,129 @@ var MCPController = class _MCPController {
28016
28077
  async handleGetEvents() {
28017
28078
  return queryEvents({ limit: 50 });
28018
28079
  }
28080
+ /**
28081
+ * Process pending tool registrations after MCP server is ready
28082
+ * @private
28083
+ */
28084
+ processPendingToolRegistrations() {
28085
+ if (this.pendingToolRegistrations.length === 0)
28086
+ return;
28087
+ logger.log(
28088
+ `[MCPController] Processing ${this.pendingToolRegistrations.length} pending tool registrations`
28089
+ );
28090
+ const pending = [...this.pendingToolRegistrations];
28091
+ this.pendingToolRegistrations = [];
28092
+ pending.forEach(async ({ toolData, resolve, reject }) => {
28093
+ try {
28094
+ await this.handleRegisterToolInternal(toolData);
28095
+ resolve();
28096
+ } catch (error48) {
28097
+ reject(error48 instanceof Error ? error48 : new Error(String(error48)));
28098
+ }
28099
+ });
28100
+ }
28101
+ async handleRegisterTool(toolData) {
28102
+ if (!this.isMCPServerReady) {
28103
+ logger.log(
28104
+ `[MCPController] Queueing tool registration '${toolData["name"]}' (MCP server not ready yet)`
28105
+ );
28106
+ return new Promise((resolve, reject) => {
28107
+ this.pendingToolRegistrations.push({
28108
+ toolData,
28109
+ resolve,
28110
+ reject
28111
+ });
28112
+ });
28113
+ }
28114
+ return this.handleRegisterToolInternal(toolData);
28115
+ }
28116
+ /**
28117
+ * Internal method to register tool (assumes MCP server is ready)
28118
+ * @private
28119
+ */
28120
+ async handleRegisterToolInternal(toolData) {
28121
+ const name = toolData["name"];
28122
+ const description = toolData["description"];
28123
+ const inputSchema = toolData["inputSchema"];
28124
+ const handlerType = toolData["handlerType"];
28125
+ if (!name || !description || !inputSchema) {
28126
+ throw new Error(
28127
+ "Missing required tool fields: name, description, inputSchema"
28128
+ );
28129
+ }
28130
+ if (handlerType !== "proxy") {
28131
+ throw new Error(
28132
+ `Unsupported handler type: ${handlerType}. Only 'proxy' handlers are supported.`
28133
+ );
28134
+ }
28135
+ const handler = async (args) => {
28136
+ const callId = `call_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
28137
+ logger.log(`[MCPController] Proxying tool call to main thread: ${name}`, {
28138
+ callId,
28139
+ args
28140
+ });
28141
+ return new Promise((resolve, reject) => {
28142
+ const pendingCall = {
28143
+ resolve,
28144
+ reject,
28145
+ timeout: setTimeout(() => {
28146
+ reject(new Error(`Tool call timeout: ${name}`));
28147
+ }, 3e4)
28148
+ // 30 second timeout
28149
+ };
28150
+ if (!this.pendingToolCalls) {
28151
+ this.pendingToolCalls = /* @__PURE__ */ new Map();
28152
+ }
28153
+ this.pendingToolCalls.set(callId, pendingCall);
28154
+ this.broadcastFn({
28155
+ type: "CALL_TOOL",
28156
+ toolName: name,
28157
+ args,
28158
+ callId
28159
+ });
28160
+ });
28161
+ };
28162
+ toolRegistry.register(
28163
+ {
28164
+ name,
28165
+ description,
28166
+ inputSchema
28167
+ },
28168
+ handler
28169
+ );
28170
+ logger.log(
28171
+ `[MCPController] Registered proxy tool: ${name} (forwards to main thread)`
28172
+ );
28173
+ }
28174
+ pendingToolCalls;
28175
+ handleToolCallResult(callId, result) {
28176
+ if (!this.pendingToolCalls)
28177
+ return;
28178
+ const pendingCall = this.pendingToolCalls.get(callId);
28179
+ if (!pendingCall) {
28180
+ logger.warn(
28181
+ `[MCPController] Received result for unknown call: ${callId}`
28182
+ );
28183
+ return;
28184
+ }
28185
+ clearTimeout(pendingCall.timeout);
28186
+ this.pendingToolCalls.delete(callId);
28187
+ const resultData = result;
28188
+ if (resultData.success && resultData.result) {
28189
+ pendingCall.resolve(resultData.result);
28190
+ } else {
28191
+ pendingCall.reject(new Error(resultData.error || "Tool call failed"));
28192
+ }
28193
+ }
28194
+ async handleUnregisterTool(toolName) {
28195
+ const success2 = toolRegistry.unregister(toolName);
28196
+ if (success2) {
28197
+ logger.log(`[MCPController] Unregistered tool: ${toolName}`);
28198
+ } else {
28199
+ logger.log(`[MCPController] Tool not found: ${toolName}`);
28200
+ }
28201
+ return success2;
28202
+ }
28019
28203
  getConnectionStatus() {
28020
28204
  return this.socket?.readyState === WebSocket.OPEN;
28021
28205
  }
@@ -28056,11 +28240,17 @@ var setBackendUrl = (url2) => {
28056
28240
  try {
28057
28241
  client.postMessage(message);
28058
28242
  } catch (e) {
28059
- logger.error("[ServiceWorker] Failed to post message to client:", e);
28243
+ logger.error(
28244
+ "[ServiceWorker] Failed to post message to client:",
28245
+ e
28246
+ );
28060
28247
  }
28061
28248
  });
28062
28249
  }).catch((err) => {
28063
- logger.error("[ServiceWorker] Failed to match clients for broadcast:", err);
28250
+ logger.error(
28251
+ "[ServiceWorker] Failed to match clients for broadcast:",
28252
+ err
28253
+ );
28064
28254
  });
28065
28255
  });
28066
28256
  return controller;
@@ -28105,64 +28295,175 @@ self.addEventListener("message", async (event) => {
28105
28295
  return;
28106
28296
  }
28107
28297
  if (msg["type"] === "STORE_EVENT") {
28108
- event.waitUntil((async () => {
28109
- try {
28110
- if (!backendUrl || !controller) {
28298
+ event.waitUntil(
28299
+ (async () => {
28300
+ try {
28301
+ if (!backendUrl || !controller) {
28302
+ if (event.ports && event.ports[0]) {
28303
+ event.ports[0].postMessage({
28304
+ success: false,
28305
+ error: "Worker not initialized"
28306
+ });
28307
+ } else {
28308
+ logger.warn("[ServiceWorker] STORE_EVENT before INIT, ignoring");
28309
+ }
28310
+ return;
28311
+ }
28312
+ const userEvent = event.data.event;
28313
+ await getController().handleStoreEvent(userEvent);
28111
28314
  if (event.ports && event.ports[0]) {
28112
- event.ports[0].postMessage({ success: false, error: "Worker not initialized" });
28315
+ event.ports[0].postMessage({ success: true });
28316
+ }
28317
+ } catch (error48) {
28318
+ logger.error("[ServiceWorker] Failed to store event:", error48);
28319
+ if (event.ports && event.ports[0]) {
28320
+ event.ports[0].postMessage({
28321
+ success: false,
28322
+ error: error48 instanceof Error ? error48.message : "Failed to store event"
28323
+ });
28113
28324
  }
28114
- return;
28115
- }
28116
- const userEvent = event.data.event;
28117
- await getController().handleStoreEvent(userEvent);
28118
- if (event.ports && event.ports[0]) {
28119
- event.ports[0].postMessage({ success: true });
28120
- }
28121
- } catch (error48) {
28122
- if (event.ports && event.ports[0]) {
28123
- event.ports[0].postMessage({ success: false, error: error48 instanceof Error ? error48.message : "Worker not initialized" });
28124
28325
  }
28125
- }
28126
- })());
28326
+ })()
28327
+ );
28127
28328
  return;
28128
28329
  }
28129
28330
  if (msg["type"] === "GET_EVENTS") {
28130
- event.waitUntil((async () => {
28131
- try {
28132
- if (!backendUrl || !controller) {
28331
+ event.waitUntil(
28332
+ (async () => {
28333
+ try {
28334
+ if (!backendUrl || !controller) {
28335
+ if (event.ports && event.ports[0]) {
28336
+ event.ports[0].postMessage({
28337
+ success: false,
28338
+ error: "Worker not initialized"
28339
+ });
28340
+ }
28341
+ return;
28342
+ }
28343
+ const events = await getController().handleGetEvents();
28133
28344
  if (event.ports && event.ports[0]) {
28134
- event.ports[0].postMessage({ success: false, error: "Worker not initialized" });
28345
+ event.ports[0].postMessage({ success: true, events });
28346
+ }
28347
+ } catch (error48) {
28348
+ if (event.ports && event.ports[0]) {
28349
+ event.ports[0].postMessage({
28350
+ success: false,
28351
+ error: error48 instanceof Error ? error48.message : "Worker not initialized"
28352
+ });
28135
28353
  }
28136
- return;
28137
- }
28138
- const events = await getController().handleGetEvents();
28139
- if (event.ports && event.ports[0]) {
28140
- event.ports[0].postMessage({ success: true, events });
28141
- }
28142
- } catch (error48) {
28143
- if (event.ports && event.ports[0]) {
28144
- event.ports[0].postMessage({ success: false, error: error48 instanceof Error ? error48.message : "Worker not initialized" });
28145
28354
  }
28146
- }
28147
- })());
28355
+ })()
28356
+ );
28148
28357
  return;
28149
28358
  }
28150
28359
  if (msg["type"] === "GET_CONNECTION_STATUS") {
28151
28360
  if (event.ports && event.ports[0]) {
28152
28361
  if (!backendUrl || !controller) {
28153
- event.ports[0].postMessage({ success: false, error: "Worker not initialized" });
28362
+ event.ports[0].postMessage({
28363
+ success: false,
28364
+ error: "Worker not initialized"
28365
+ });
28154
28366
  } else {
28155
- event.ports[0].postMessage({ success: true, connected: getController().getConnectionStatus() });
28367
+ event.ports[0].postMessage({
28368
+ success: true,
28369
+ connected: getController().getConnectionStatus()
28370
+ });
28156
28371
  }
28157
28372
  }
28158
28373
  return;
28159
28374
  }
28375
+ if (msg["type"] === "REGISTER_TOOL") {
28376
+ event.waitUntil(
28377
+ (async () => {
28378
+ try {
28379
+ if (!backendUrl || !controller) {
28380
+ if (event.ports && event.ports[0]) {
28381
+ event.ports[0].postMessage({
28382
+ success: false,
28383
+ error: "Worker not initialized"
28384
+ });
28385
+ }
28386
+ return;
28387
+ }
28388
+ const toolData = msg;
28389
+ await getController().handleRegisterTool(toolData);
28390
+ if (event.ports && event.ports[0]) {
28391
+ event.ports[0].postMessage({ success: true });
28392
+ }
28393
+ } catch (error48) {
28394
+ if (event.ports && event.ports[0]) {
28395
+ event.ports[0].postMessage({
28396
+ success: false,
28397
+ error: error48 instanceof Error ? error48.message : "Failed to register tool"
28398
+ });
28399
+ }
28400
+ }
28401
+ })()
28402
+ );
28403
+ return;
28404
+ }
28405
+ if (msg["type"] === "UNREGISTER_TOOL") {
28406
+ event.waitUntil(
28407
+ (async () => {
28408
+ try {
28409
+ if (!backendUrl || !controller) {
28410
+ if (event.ports && event.ports[0]) {
28411
+ event.ports[0].postMessage({
28412
+ success: false,
28413
+ error: "Worker not initialized"
28414
+ });
28415
+ }
28416
+ return;
28417
+ }
28418
+ const toolName = msg["name"];
28419
+ if (!toolName) {
28420
+ if (event.ports && event.ports[0]) {
28421
+ event.ports[0].postMessage({
28422
+ success: false,
28423
+ error: "Tool name is required"
28424
+ });
28425
+ }
28426
+ return;
28427
+ }
28428
+ const success2 = await getController().handleUnregisterTool(toolName);
28429
+ if (event.ports && event.ports[0]) {
28430
+ event.ports[0].postMessage({ success: success2 });
28431
+ }
28432
+ } catch (error48) {
28433
+ if (event.ports && event.ports[0]) {
28434
+ event.ports[0].postMessage({
28435
+ success: false,
28436
+ error: error48 instanceof Error ? error48.message : "Failed to unregister tool"
28437
+ });
28438
+ }
28439
+ }
28440
+ })()
28441
+ );
28442
+ return;
28443
+ }
28444
+ if (msg["type"] === "TOOL_CALL_RESULT") {
28445
+ try {
28446
+ if (!controller) {
28447
+ logger.warn(
28448
+ "[ServiceWorker] Received TOOL_CALL_RESULT but no controller"
28449
+ );
28450
+ return;
28451
+ }
28452
+ const callId = msg["callId"];
28453
+ if (!callId) {
28454
+ logger.warn("[ServiceWorker] TOOL_CALL_RESULT missing callId");
28455
+ return;
28456
+ }
28457
+ getController().handleToolCallResult(callId, msg);
28458
+ } catch (error48) {
28459
+ logger.error("[ServiceWorker] Failed to handle TOOL_CALL_RESULT:", error48);
28460
+ }
28461
+ return;
28462
+ }
28160
28463
  });
28161
28464
  self.addEventListener("install", (event) => {
28162
28465
  event.waitUntil(self.skipWaiting());
28163
28466
  });
28164
28467
  self.addEventListener("activate", (event) => {
28165
- event.waitUntil(
28166
- Promise.resolve(self.clients.claim())
28167
- );
28468
+ event.waitUntil(Promise.resolve(self.clients.claim()));
28168
28469
  });