@knowsuchagency/fulcrum 2.16.2 → 2.17.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/bin/fulcrum.js CHANGED
@@ -46247,7 +46247,7 @@ async function runMcpServer(urlOverride, portOverride) {
46247
46247
  const client = new FulcrumClient(urlOverride, portOverride);
46248
46248
  const server = new McpServer({
46249
46249
  name: "fulcrum",
46250
- version: "2.16.2"
46250
+ version: "2.17.1"
46251
46251
  });
46252
46252
  registerTools(server, client);
46253
46253
  const transport = new StdioServerTransport;
@@ -48596,7 +48596,7 @@ var marketplace_default = `{
48596
48596
  "name": "fulcrum",
48597
48597
  "source": "./",
48598
48598
  "description": "Task orchestration for Claude Code",
48599
- "version": "2.16.2",
48599
+ "version": "2.17.1",
48600
48600
  "skills": [
48601
48601
  "./skills/fulcrum"
48602
48602
  ],
@@ -49784,7 +49784,7 @@ function compareVersions(v1, v2) {
49784
49784
  var package_default = {
49785
49785
  name: "@knowsuchagency/fulcrum",
49786
49786
  private: true,
49787
- version: "2.16.2",
49787
+ version: "2.17.1",
49788
49788
  description: "Harness Attention. Orchestrate Agents. Ship.",
49789
49789
  license: "PolyForm-Perimeter-1.0.0",
49790
49790
  type: "module",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knowsuchagency/fulcrum",
3
- "version": "2.16.2",
3
+ "version": "2.17.1",
4
4
  "description": "Harness Attention. Orchestrate Agents. Ship.",
5
5
  "license": "PolyForm-Perimeter-1.0.0",
6
6
  "repository": {
package/server/index.js CHANGED
@@ -72115,7 +72115,8 @@ User message: ${userMessage}`;
72115
72115
  tools: isObserver ? [] : { type: "preset", preset: "claude_code" },
72116
72116
  systemPrompt,
72117
72117
  permissionMode: "bypassPermissions",
72118
- allowDangerouslySkipPermissions: true
72118
+ allowDangerouslySkipPermissions: true,
72119
+ settingSources: ["user"]
72119
72120
  }
72120
72121
  });
72121
72122
  let currentText = "";
@@ -361552,289 +361553,359 @@ var require_dist20 = __commonJS((exports) => {
361552
361553
  });
361553
361554
 
361554
361555
  // server/services/channels/slack-channel.ts
361555
- class SlackChannel {
361556
- type = "slack";
361557
- connectionId;
361558
- app = null;
361559
- events = null;
361560
- status = "disconnected";
361561
- reconnectTimer = null;
361562
- isShuttingDown = false;
361563
- botToken = null;
361564
- appToken = null;
361565
- constructor(connectionId) {
361566
- this.connectionId = connectionId;
361567
- }
361568
- async initialize(events) {
361569
- this.events = events;
361570
- this.isShuttingDown = false;
361571
- const settings = getSettings();
361572
- const slackConfig = settings.channels.slack;
361573
- if (!slackConfig.botToken || !slackConfig.appToken) {
361574
- log2.messaging.warn("Slack channel missing credentials", {
361575
- connectionId: this.connectionId
361576
- });
361577
- this.updateStatus("disconnected");
361578
- return;
361556
+ var import_bolt, SlackChannel;
361557
+ var init_slack_channel = __esm(() => {
361558
+ init_drizzle_orm();
361559
+ init_db2();
361560
+ init_logger3();
361561
+ init_settings();
361562
+ import_bolt = __toESM(require_dist20(), 1);
361563
+ SlackChannel = class SlackChannel {
361564
+ type = "slack";
361565
+ connectionId;
361566
+ app = null;
361567
+ events = null;
361568
+ status = "disconnected";
361569
+ reconnectTimer = null;
361570
+ healthCheckTimer = null;
361571
+ isShuttingDown = false;
361572
+ botToken = null;
361573
+ appToken = null;
361574
+ static HEALTH_CHECK_INTERVAL = 5 * 60 * 1000;
361575
+ constructor(connectionId) {
361576
+ this.connectionId = connectionId;
361577
+ }
361578
+ async initialize(events) {
361579
+ this.events = events;
361580
+ this.isShuttingDown = false;
361581
+ const settings = getSettings();
361582
+ const slackConfig = settings.channels.slack;
361583
+ if (!slackConfig.botToken || !slackConfig.appToken) {
361584
+ log2.messaging.warn("Slack channel missing credentials", {
361585
+ connectionId: this.connectionId
361586
+ });
361587
+ this.updateStatus("disconnected");
361588
+ return;
361589
+ }
361590
+ this.botToken = slackConfig.botToken;
361591
+ this.appToken = slackConfig.appToken;
361592
+ await this.connect();
361579
361593
  }
361580
- this.botToken = slackConfig.botToken;
361581
- this.appToken = slackConfig.appToken;
361582
- await this.connect();
361583
- }
361584
- async connect() {
361585
- if (this.isShuttingDown || !this.botToken || !this.appToken)
361586
- return;
361587
- try {
361588
- this.updateStatus("connecting");
361589
- this.app = new import_bolt.App({
361590
- token: this.botToken,
361591
- appToken: this.appToken,
361592
- socketMode: true,
361593
- logLevel: import_bolt.LogLevel.WARN
361594
- });
361595
- this.app.command(/.*/, async ({ ack, command, respond }) => {
361596
- await ack();
361597
- await this.handleSlashCommand(command, respond);
361594
+ async connect() {
361595
+ if (this.isShuttingDown || !this.botToken || !this.appToken)
361596
+ return;
361597
+ try {
361598
+ this.updateStatus("connecting");
361599
+ this.app = new import_bolt.App({
361600
+ token: this.botToken,
361601
+ appToken: this.appToken,
361602
+ socketMode: true,
361603
+ logLevel: import_bolt.LogLevel.WARN
361604
+ });
361605
+ this.app.command(/.*/, async ({ ack, command, respond }) => {
361606
+ await ack();
361607
+ await this.handleSlashCommand(command, respond);
361608
+ });
361609
+ this.app.message(async ({ message }) => {
361610
+ if (message.channel_type === "im") {
361611
+ await this.handleMessage(message);
361612
+ }
361613
+ });
361614
+ await this.app.start();
361615
+ this.setupSocketModeListeners();
361616
+ const authTest = await this.app.client.auth.test();
361617
+ log2.messaging.info("Slack bot connected", {
361618
+ connectionId: this.connectionId,
361619
+ botId: authTest.bot_id,
361620
+ userId: authTest.user_id
361621
+ });
361622
+ this.updateStatus("connected");
361623
+ this.startHealthCheck();
361624
+ const displayName = authTest.user || "Slack Bot";
361625
+ db2.update(messagingConnections).set({
361626
+ displayName,
361627
+ updatedAt: new Date().toISOString()
361628
+ }).where(eq(messagingConnections.id, this.connectionId)).run();
361629
+ this.events?.onDisplayNameChange?.(displayName);
361630
+ } catch (err) {
361631
+ log2.messaging.error("Slack connect error", {
361632
+ connectionId: this.connectionId,
361633
+ error: String(err)
361634
+ });
361635
+ this.updateStatus("disconnected");
361636
+ this.scheduleReconnect();
361637
+ }
361638
+ }
361639
+ setupSocketModeListeners() {
361640
+ const receiver2 = this.app?.receiver;
361641
+ const socketClient = receiver2?.client;
361642
+ if (!socketClient) {
361643
+ log2.messaging.warn("Could not access Socket Mode client for health monitoring", {
361644
+ connectionId: this.connectionId
361645
+ });
361646
+ return;
361647
+ }
361648
+ socketClient.on("disconnected", () => {
361649
+ if (this.isShuttingDown)
361650
+ return;
361651
+ log2.messaging.warn("Slack Socket Mode disconnected", {
361652
+ connectionId: this.connectionId
361653
+ });
361654
+ this.updateStatus("disconnected");
361598
361655
  });
361599
- this.app.message(async ({ message }) => {
361600
- if (message.channel_type === "im") {
361601
- await this.handleMessage(message);
361602
- }
361656
+ socketClient.on("reconnecting", () => {
361657
+ if (this.isShuttingDown)
361658
+ return;
361659
+ log2.messaging.info("Slack Socket Mode reconnecting", {
361660
+ connectionId: this.connectionId
361661
+ });
361662
+ this.updateStatus("connecting");
361603
361663
  });
361604
- await this.app.start();
361605
- const authTest = await this.app.client.auth.test();
361606
- log2.messaging.info("Slack bot connected", {
361607
- connectionId: this.connectionId,
361608
- botId: authTest.bot_id,
361609
- userId: authTest.user_id
361664
+ socketClient.on("connected", () => {
361665
+ if (this.isShuttingDown)
361666
+ return;
361667
+ log2.messaging.info("Slack Socket Mode reconnected", {
361668
+ connectionId: this.connectionId
361669
+ });
361670
+ this.updateStatus("connected");
361610
361671
  });
361611
- this.updateStatus("connected");
361612
- const displayName = authTest.user || "Slack Bot";
361613
- db2.update(messagingConnections).set({
361614
- displayName,
361615
- updatedAt: new Date().toISOString()
361616
- }).where(eq(messagingConnections.id, this.connectionId)).run();
361617
- this.events?.onDisplayNameChange?.(displayName);
361618
- } catch (err) {
361619
- log2.messaging.error("Slack connect error", {
361620
- connectionId: this.connectionId,
361621
- error: String(err)
361672
+ log2.messaging.debug("Socket Mode event listeners attached", {
361673
+ connectionId: this.connectionId
361622
361674
  });
361623
- this.updateStatus("disconnected");
361624
- this.scheduleReconnect();
361625
361675
  }
361626
- }
361627
- async handleMessage(message) {
361628
- if (message.bot_id || message.subtype === "bot_message")
361629
- return;
361630
- const content = message.text;
361631
- if (!content)
361632
- return;
361633
- const userId = message.user;
361634
- if (!userId)
361635
- return;
361636
- let senderName;
361637
- try {
361638
- if (this.app) {
361639
- const userInfo = await this.app.client.users.info({ user: userId });
361640
- senderName = userInfo.user?.real_name || userInfo.user?.name;
361676
+ startHealthCheck() {
361677
+ this.stopHealthCheck();
361678
+ this.healthCheckTimer = setInterval(async () => {
361679
+ if (this.isShuttingDown || !this.app || this.status !== "connected")
361680
+ return;
361681
+ try {
361682
+ await this.app.client.auth.test();
361683
+ } catch (err) {
361684
+ log2.messaging.warn("Slack health check failed, triggering reconnect", {
361685
+ connectionId: this.connectionId,
361686
+ error: String(err)
361687
+ });
361688
+ this.updateStatus("disconnected");
361689
+ try {
361690
+ await this.app?.stop();
361691
+ } catch {}
361692
+ this.app = null;
361693
+ this.scheduleReconnect();
361694
+ }
361695
+ }, SlackChannel.HEALTH_CHECK_INTERVAL);
361696
+ }
361697
+ stopHealthCheck() {
361698
+ if (this.healthCheckTimer) {
361699
+ clearInterval(this.healthCheckTimer);
361700
+ this.healthCheckTimer = null;
361641
361701
  }
361642
- } catch {}
361643
- const incomingMessage = {
361644
- channelType: "slack",
361645
- connectionId: this.connectionId,
361646
- senderId: userId,
361647
- senderName,
361648
- content,
361649
- timestamp: new Date(parseFloat(message.ts) * 1000)
361650
- };
361651
- log2.messaging.info("Slack message received", {
361652
- connectionId: this.connectionId,
361653
- from: userId,
361654
- contentLength: content.length
361655
- });
361656
- try {
361657
- await this.events?.onMessage(incomingMessage);
361658
- } catch (err) {
361659
- log2.messaging.error("Error processing Slack message", {
361702
+ }
361703
+ async handleMessage(message) {
361704
+ if (message.bot_id || message.subtype === "bot_message")
361705
+ return;
361706
+ const content = message.text;
361707
+ if (!content)
361708
+ return;
361709
+ const userId = message.user;
361710
+ if (!userId)
361711
+ return;
361712
+ let senderName;
361713
+ try {
361714
+ if (this.app) {
361715
+ const userInfo = await this.app.client.users.info({ user: userId });
361716
+ senderName = userInfo.user?.real_name || userInfo.user?.name;
361717
+ }
361718
+ } catch {}
361719
+ const incomingMessage = {
361720
+ channelType: "slack",
361660
361721
  connectionId: this.connectionId,
361661
- error: String(err)
361722
+ senderId: userId,
361723
+ senderName,
361724
+ content,
361725
+ timestamp: new Date(parseFloat(message.ts) * 1000)
361726
+ };
361727
+ log2.messaging.info("Slack message received", {
361728
+ connectionId: this.connectionId,
361729
+ from: userId,
361730
+ contentLength: content.length
361662
361731
  });
361663
- }
361664
- }
361665
- async handleSlashCommand(command, respond) {
361666
- log2.messaging.info("Slack slash command received", {
361667
- connectionId: this.connectionId,
361668
- command: command.command,
361669
- userId: command.user_id,
361670
- userName: command.user_name
361671
- });
361672
- const incomingMessage = {
361673
- channelType: "slack",
361674
- connectionId: this.connectionId,
361675
- senderId: command.user_id,
361676
- senderName: command.user_name,
361677
- content: command.command,
361678
- timestamp: new Date,
361679
- metadata: {
361680
- isSlashCommand: true
361732
+ try {
361733
+ await this.events?.onMessage(incomingMessage);
361734
+ } catch (err) {
361735
+ log2.messaging.error("Error processing Slack message", {
361736
+ connectionId: this.connectionId,
361737
+ error: String(err)
361738
+ });
361681
361739
  }
361682
- };
361683
- try {
361684
- await this.events?.onMessage(incomingMessage);
361685
- await respond({ text: "\u2713 Command received", response_type: "ephemeral" });
361686
- } catch (err) {
361687
- log2.messaging.error("Error processing Slack slash command", {
361740
+ }
361741
+ async handleSlashCommand(command, respond) {
361742
+ log2.messaging.info("Slack slash command received", {
361688
361743
  connectionId: this.connectionId,
361689
361744
  command: command.command,
361690
- error: String(err)
361691
- });
361692
- await respond({
361693
- text: "Sorry, something went wrong processing your command.",
361694
- response_type: "ephemeral"
361745
+ userId: command.user_id,
361746
+ userName: command.user_name
361695
361747
  });
361696
- }
361697
- }
361698
- async shutdown() {
361699
- this.isShuttingDown = true;
361700
- if (this.reconnectTimer) {
361701
- clearTimeout(this.reconnectTimer);
361702
- this.reconnectTimer = null;
361703
- }
361704
- if (this.app) {
361705
- await this.app.stop();
361706
- this.app = null;
361707
- }
361708
- this.updateStatus("disconnected");
361709
- log2.messaging.info("Slack channel shutdown", {
361710
- connectionId: this.connectionId
361711
- });
361712
- }
361713
- async sendMessage(recipientId, content, metadata) {
361714
- if (!this.app || this.status !== "connected") {
361715
- log2.messaging.warn("Cannot send Slack message - not connected", {
361748
+ const incomingMessage = {
361749
+ channelType: "slack",
361716
361750
  connectionId: this.connectionId,
361717
- status: this.status
361718
- });
361719
- return false;
361751
+ senderId: command.user_id,
361752
+ senderName: command.user_name,
361753
+ content: command.command,
361754
+ timestamp: new Date,
361755
+ metadata: {
361756
+ isSlashCommand: true
361757
+ }
361758
+ };
361759
+ try {
361760
+ await this.events?.onMessage(incomingMessage);
361761
+ await respond({ text: "\u2713 Command received", response_type: "ephemeral" });
361762
+ } catch (err) {
361763
+ log2.messaging.error("Error processing Slack slash command", {
361764
+ connectionId: this.connectionId,
361765
+ command: command.command,
361766
+ error: String(err)
361767
+ });
361768
+ await respond({
361769
+ text: "Sorry, something went wrong processing your command.",
361770
+ response_type: "ephemeral"
361771
+ });
361772
+ }
361720
361773
  }
361721
- try {
361722
- const conversation = await this.app.client.conversations.open({
361723
- users: recipientId
361774
+ async shutdown() {
361775
+ this.isShuttingDown = true;
361776
+ this.stopHealthCheck();
361777
+ if (this.reconnectTimer) {
361778
+ clearTimeout(this.reconnectTimer);
361779
+ this.reconnectTimer = null;
361780
+ }
361781
+ if (this.app) {
361782
+ await this.app.stop();
361783
+ this.app = null;
361784
+ }
361785
+ this.updateStatus("disconnected");
361786
+ log2.messaging.info("Slack channel shutdown", {
361787
+ connectionId: this.connectionId
361724
361788
  });
361725
- const channelId = conversation.channel?.id;
361726
- if (!channelId) {
361727
- throw new Error("Failed to open DM channel");
361789
+ }
361790
+ async sendMessage(recipientId, content, metadata) {
361791
+ if (!this.app || this.status !== "connected") {
361792
+ log2.messaging.warn("Cannot send Slack message - not connected", {
361793
+ connectionId: this.connectionId,
361794
+ status: this.status
361795
+ });
361796
+ return false;
361728
361797
  }
361729
- if (content.length <= 4000) {
361730
- const messageOptions = {
361731
- channel: channelId,
361732
- text: content
361733
- };
361734
- if (metadata?.blocks) {
361735
- messageOptions.blocks = metadata.blocks;
361736
- } else {
361737
- messageOptions.mrkdwn = true;
361798
+ try {
361799
+ const conversation = await this.app.client.conversations.open({
361800
+ users: recipientId
361801
+ });
361802
+ const channelId = conversation.channel?.id;
361803
+ if (!channelId) {
361804
+ throw new Error("Failed to open DM channel");
361738
361805
  }
361739
- await this.app.client.chat.postMessage(messageOptions);
361740
- } else {
361741
- const parts = this.splitMessage(content, 4000);
361742
- for (const part of parts) {
361743
- await this.app.client.chat.postMessage({
361806
+ if (content.length <= 4000) {
361807
+ const messageOptions = {
361744
361808
  channel: channelId,
361745
- text: part,
361746
- mrkdwn: true
361747
- });
361748
- await new Promise((resolve6) => setTimeout(resolve6, 100));
361809
+ text: content
361810
+ };
361811
+ if (metadata?.blocks) {
361812
+ messageOptions.blocks = metadata.blocks;
361813
+ } else {
361814
+ messageOptions.mrkdwn = true;
361815
+ }
361816
+ await this.app.client.chat.postMessage(messageOptions);
361817
+ } else {
361818
+ const parts = this.splitMessage(content, 4000);
361819
+ for (const part of parts) {
361820
+ await this.app.client.chat.postMessage({
361821
+ channel: channelId,
361822
+ text: part,
361823
+ mrkdwn: true
361824
+ });
361825
+ await new Promise((resolve6) => setTimeout(resolve6, 100));
361826
+ }
361749
361827
  }
361828
+ log2.messaging.info("Slack message sent", {
361829
+ connectionId: this.connectionId,
361830
+ to: recipientId,
361831
+ contentLength: content.length,
361832
+ hasBlocks: !!metadata?.blocks
361833
+ });
361834
+ return true;
361835
+ } catch (err) {
361836
+ log2.messaging.error("Failed to send Slack message", {
361837
+ connectionId: this.connectionId,
361838
+ to: recipientId,
361839
+ error: String(err)
361840
+ });
361841
+ return false;
361750
361842
  }
361751
- log2.messaging.info("Slack message sent", {
361752
- connectionId: this.connectionId,
361753
- to: recipientId,
361754
- contentLength: content.length,
361755
- hasBlocks: !!metadata?.blocks
361756
- });
361757
- return true;
361758
- } catch (err) {
361759
- log2.messaging.error("Failed to send Slack message", {
361760
- connectionId: this.connectionId,
361761
- to: recipientId,
361762
- error: String(err)
361763
- });
361764
- return false;
361765
361843
  }
361766
- }
361767
- splitMessage(content, maxLength) {
361768
- const parts = [];
361769
- let remaining = content;
361770
- while (remaining.length > 0) {
361771
- if (remaining.length <= maxLength) {
361772
- parts.push(remaining);
361773
- break;
361774
- }
361775
- let breakPoint = remaining.lastIndexOf(`
361844
+ splitMessage(content, maxLength) {
361845
+ const parts = [];
361846
+ let remaining = content;
361847
+ while (remaining.length > 0) {
361848
+ if (remaining.length <= maxLength) {
361849
+ parts.push(remaining);
361850
+ break;
361851
+ }
361852
+ let breakPoint = remaining.lastIndexOf(`
361776
361853
 
361777
361854
  `, maxLength);
361778
- if (breakPoint === -1 || breakPoint < maxLength / 2) {
361779
- breakPoint = remaining.lastIndexOf(`
361855
+ if (breakPoint === -1 || breakPoint < maxLength / 2) {
361856
+ breakPoint = remaining.lastIndexOf(`
361780
361857
  `, maxLength);
361858
+ }
361859
+ if (breakPoint === -1 || breakPoint < maxLength / 2) {
361860
+ breakPoint = remaining.lastIndexOf(" ", maxLength);
361861
+ }
361862
+ if (breakPoint === -1 || breakPoint < maxLength / 2) {
361863
+ breakPoint = maxLength;
361864
+ }
361865
+ parts.push(remaining.slice(0, breakPoint));
361866
+ remaining = remaining.slice(breakPoint).trimStart();
361781
361867
  }
361782
- if (breakPoint === -1 || breakPoint < maxLength / 2) {
361783
- breakPoint = remaining.lastIndexOf(" ", maxLength);
361784
- }
361785
- if (breakPoint === -1 || breakPoint < maxLength / 2) {
361786
- breakPoint = maxLength;
361868
+ return parts;
361869
+ }
361870
+ getStatus() {
361871
+ return this.status;
361872
+ }
361873
+ async logout() {
361874
+ this.stopHealthCheck();
361875
+ if (this.app) {
361876
+ await this.app.stop();
361877
+ this.app = null;
361787
361878
  }
361788
- parts.push(remaining.slice(0, breakPoint));
361789
- remaining = remaining.slice(breakPoint).trimStart();
361879
+ this.botToken = null;
361880
+ this.appToken = null;
361881
+ db2.update(messagingConnections).set({
361882
+ displayName: null,
361883
+ status: "disconnected",
361884
+ updatedAt: new Date().toISOString()
361885
+ }).where(eq(messagingConnections.id, this.connectionId)).run();
361886
+ this.updateStatus("disconnected");
361790
361887
  }
361791
- return parts;
361792
- }
361793
- getStatus() {
361794
- return this.status;
361795
- }
361796
- async logout() {
361797
- if (this.app) {
361798
- await this.app.stop();
361799
- this.app = null;
361888
+ updateStatus(status) {
361889
+ this.status = status;
361890
+ db2.update(messagingConnections).set({
361891
+ status,
361892
+ updatedAt: new Date().toISOString()
361893
+ }).where(eq(messagingConnections.id, this.connectionId)).run();
361894
+ this.events?.onConnectionChange(status);
361800
361895
  }
361801
- this.botToken = null;
361802
- this.appToken = null;
361803
- db2.update(messagingConnections).set({
361804
- displayName: null,
361805
- status: "disconnected",
361806
- updatedAt: new Date().toISOString()
361807
- }).where(eq(messagingConnections.id, this.connectionId)).run();
361808
- this.updateStatus("disconnected");
361809
- }
361810
- updateStatus(status) {
361811
- this.status = status;
361812
- db2.update(messagingConnections).set({
361813
- status,
361814
- updatedAt: new Date().toISOString()
361815
- }).where(eq(messagingConnections.id, this.connectionId)).run();
361816
- this.events?.onConnectionChange(status);
361817
- }
361818
- scheduleReconnect() {
361819
- if (this.reconnectTimer || this.isShuttingDown)
361820
- return;
361821
- log2.messaging.debug("Scheduling Slack reconnect", {
361822
- connectionId: this.connectionId,
361823
- delayMs: 5000
361824
- });
361825
- this.reconnectTimer = setTimeout(() => {
361826
- this.reconnectTimer = null;
361827
- this.connect();
361828
- }, 5000);
361829
- }
361830
- }
361831
- var import_bolt;
361832
- var init_slack_channel = __esm(() => {
361833
- init_drizzle_orm();
361834
- init_db2();
361835
- init_logger3();
361836
- init_settings();
361837
- import_bolt = __toESM(require_dist20(), 1);
361896
+ scheduleReconnect() {
361897
+ if (this.reconnectTimer || this.isShuttingDown)
361898
+ return;
361899
+ log2.messaging.debug("Scheduling Slack reconnect", {
361900
+ connectionId: this.connectionId,
361901
+ delayMs: 5000
361902
+ });
361903
+ this.reconnectTimer = setTimeout(() => {
361904
+ this.reconnectTimer = null;
361905
+ this.connect();
361906
+ }, 5000);
361907
+ }
361908
+ };
361838
361909
  });
361839
361910
 
361840
361911
  // node_modules/imapflow/node_modules/pino/lib/caller.js
@@ -1260547,7 +1260618,7 @@ mcpRoutes.all("/", async (c) => {
1260547
1260618
  });
1260548
1260619
  const server = new McpServer({
1260549
1260620
  name: "fulcrum",
1260550
- version: "2.16.2"
1260621
+ version: "2.17.1"
1260551
1260622
  });
1260552
1260623
  const client = new FulcrumClient(`http://localhost:${port}`);
1260553
1260624
  registerTools(server, client);