@herdctl/slack 0.0.1 → 0.2.0
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/LICENSE +21 -0
- package/dist/__tests__/command-handler.test.d.ts +2 -0
- package/dist/__tests__/command-handler.test.d.ts.map +1 -0
- package/dist/__tests__/command-handler.test.js +141 -0
- package/dist/__tests__/command-handler.test.js.map +1 -0
- package/dist/__tests__/error-handler.test.d.ts +2 -0
- package/dist/__tests__/error-handler.test.d.ts.map +1 -0
- package/dist/__tests__/error-handler.test.js +168 -0
- package/dist/__tests__/error-handler.test.js.map +1 -0
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +133 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/formatting.test.d.ts +2 -0
- package/dist/__tests__/formatting.test.d.ts.map +1 -0
- package/dist/__tests__/formatting.test.js +216 -0
- package/dist/__tests__/formatting.test.js.map +1 -0
- package/dist/__tests__/logger.test.d.ts +2 -0
- package/dist/__tests__/logger.test.d.ts.map +1 -0
- package/dist/__tests__/logger.test.js +97 -0
- package/dist/__tests__/logger.test.js.map +1 -0
- package/dist/__tests__/message-handler.test.d.ts +2 -0
- package/dist/__tests__/message-handler.test.d.ts.map +1 -0
- package/dist/__tests__/message-handler.test.js +78 -0
- package/dist/__tests__/message-handler.test.js.map +1 -0
- package/dist/__tests__/session-manager.test.d.ts +2 -0
- package/dist/__tests__/session-manager.test.d.ts.map +1 -0
- package/dist/__tests__/session-manager.test.js +214 -0
- package/dist/__tests__/session-manager.test.js.map +1 -0
- package/dist/__tests__/slack-connector.test.d.ts +2 -0
- package/dist/__tests__/slack-connector.test.d.ts.map +1 -0
- package/dist/__tests__/slack-connector.test.js +376 -0
- package/dist/__tests__/slack-connector.test.js.map +1 -0
- package/dist/commands/command-handler.d.ts +72 -0
- package/dist/commands/command-handler.d.ts.map +1 -0
- package/dist/commands/command-handler.js +85 -0
- package/dist/commands/command-handler.js.map +1 -0
- package/dist/commands/help.d.ts +6 -0
- package/dist/commands/help.d.ts.map +1 -0
- package/dist/commands/help.js +22 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/index.d.ts +11 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +10 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/reset.d.ts +6 -0
- package/dist/commands/reset.d.ts.map +1 -0
- package/dist/commands/reset.js +18 -0
- package/dist/commands/reset.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +94 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/error-handler.d.ts +50 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +123 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/errors.d.ts +59 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +73 -0
- package/dist/errors.js.map +1 -0
- package/dist/formatting.d.ts +83 -0
- package/dist/formatting.d.ts.map +1 -0
- package/dist/formatting.js +155 -0
- package/dist/formatting.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +28 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +40 -0
- package/dist/logger.js.map +1 -0
- package/dist/message-handler.d.ts +62 -0
- package/dist/message-handler.d.ts.map +1 -0
- package/dist/message-handler.js +85 -0
- package/dist/message-handler.js.map +1 -0
- package/dist/session-manager/errors.d.ts +58 -0
- package/dist/session-manager/errors.d.ts.map +1 -0
- package/dist/session-manager/errors.js +70 -0
- package/dist/session-manager/errors.js.map +1 -0
- package/dist/session-manager/index.d.ts +9 -0
- package/dist/session-manager/index.d.ts.map +1 -0
- package/dist/session-manager/index.js +13 -0
- package/dist/session-manager/index.js.map +1 -0
- package/dist/session-manager/session-manager.d.ts +62 -0
- package/dist/session-manager/session-manager.d.ts.map +1 -0
- package/dist/session-manager/session-manager.js +325 -0
- package/dist/session-manager/session-manager.js.map +1 -0
- package/dist/session-manager/types.d.ts +154 -0
- package/dist/session-manager/types.d.ts.map +1 -0
- package/dist/session-manager/types.js +57 -0
- package/dist/session-manager/types.js.map +1 -0
- package/dist/slack-connector.d.ts +53 -0
- package/dist/slack-connector.d.ts.map +1 -0
- package/dist/slack-connector.js +447 -0
- package/dist/slack-connector.js.map +1 -0
- package/dist/types.d.ts +211 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -4
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command handler for Slack message prefix commands
|
|
3
|
+
*
|
|
4
|
+
* Handles !command style messages for MVP simplicity
|
|
5
|
+
* (vs Slack slash commands which require URL verification).
|
|
6
|
+
*/
|
|
7
|
+
import type { SlackConnectorLogger, ISlackSessionManager } from "../types.js";
|
|
8
|
+
import type { SlackConnectorState } from "../types.js";
|
|
9
|
+
/**
|
|
10
|
+
* Context passed to command handlers
|
|
11
|
+
*/
|
|
12
|
+
export interface CommandContext {
|
|
13
|
+
/** Name of the agent handling this command */
|
|
14
|
+
agentName: string;
|
|
15
|
+
/** Channel ID */
|
|
16
|
+
channelId: string;
|
|
17
|
+
/** User who sent the command */
|
|
18
|
+
userId: string;
|
|
19
|
+
/** Function to reply in the channel */
|
|
20
|
+
reply: (content: string) => Promise<void>;
|
|
21
|
+
/** Session manager for the agent */
|
|
22
|
+
sessionManager: ISlackSessionManager;
|
|
23
|
+
/** Current connector state */
|
|
24
|
+
connectorState: SlackConnectorState;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A prefix command definition
|
|
28
|
+
*/
|
|
29
|
+
export interface PrefixCommand {
|
|
30
|
+
/** Command name (without ! prefix) */
|
|
31
|
+
name: string;
|
|
32
|
+
/** Description of the command */
|
|
33
|
+
description: string;
|
|
34
|
+
/** Execute the command */
|
|
35
|
+
execute(context: CommandContext): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Options for CommandHandler
|
|
39
|
+
*/
|
|
40
|
+
export interface CommandHandlerOptions {
|
|
41
|
+
/** Logger instance */
|
|
42
|
+
logger?: SlackConnectorLogger;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* CommandHandler manages message prefix commands for Slack
|
|
46
|
+
*
|
|
47
|
+
* Commands are triggered by messages starting with `!` (e.g., `!reset`, `!status`)
|
|
48
|
+
*/
|
|
49
|
+
export declare class CommandHandler {
|
|
50
|
+
private commands;
|
|
51
|
+
private readonly logger;
|
|
52
|
+
constructor(options?: CommandHandlerOptions);
|
|
53
|
+
/**
|
|
54
|
+
* Register a command
|
|
55
|
+
*/
|
|
56
|
+
registerCommand(command: PrefixCommand): void;
|
|
57
|
+
/**
|
|
58
|
+
* Check if a message is a command
|
|
59
|
+
*/
|
|
60
|
+
isCommand(text: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Execute a command from message text
|
|
63
|
+
*
|
|
64
|
+
* @returns true if a command was executed, false otherwise
|
|
65
|
+
*/
|
|
66
|
+
executeCommand(text: string, context: CommandContext): Promise<boolean>;
|
|
67
|
+
/**
|
|
68
|
+
* Get all registered commands
|
|
69
|
+
*/
|
|
70
|
+
getCommands(): PrefixCommand[];
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=command-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-handler.d.ts","sourceRoot":"","sources":["../../src/commands/command-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAMvD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAElB,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAElB,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IAEf,uCAAuC;IACvC,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C,oCAAoC;IACpC,cAAc,EAAE,oBAAoB,CAAC;IAErC,8BAA8B;IAC9B,cAAc,EAAE,mBAAmB,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IAEb,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IAEpB,0BAA0B;IAC1B,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,sBAAsB;IACtB,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAMD;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,OAAO,GAAE,qBAA0B;IAS/C;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAI7C;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAUhC;;;;OAIG;IACG,cAAc,CAClB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,OAAO,CAAC;IAsCnB;;OAEG;IACH,WAAW,IAAI,aAAa,EAAE;CAG/B"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command handler for Slack message prefix commands
|
|
3
|
+
*
|
|
4
|
+
* Handles !command style messages for MVP simplicity
|
|
5
|
+
* (vs Slack slash commands which require URL verification).
|
|
6
|
+
*/
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Command Handler
|
|
9
|
+
// =============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* CommandHandler manages message prefix commands for Slack
|
|
12
|
+
*
|
|
13
|
+
* Commands are triggered by messages starting with `!` (e.g., `!reset`, `!status`)
|
|
14
|
+
*/
|
|
15
|
+
export class CommandHandler {
|
|
16
|
+
commands = new Map();
|
|
17
|
+
logger;
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
this.logger = options.logger ?? {
|
|
20
|
+
debug: () => { },
|
|
21
|
+
info: () => { },
|
|
22
|
+
warn: () => { },
|
|
23
|
+
error: () => { },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Register a command
|
|
28
|
+
*/
|
|
29
|
+
registerCommand(command) {
|
|
30
|
+
this.commands.set(command.name.toLowerCase(), command);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if a message is a command
|
|
34
|
+
*/
|
|
35
|
+
isCommand(text) {
|
|
36
|
+
const trimmed = text.trim();
|
|
37
|
+
if (!trimmed.startsWith("!")) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const commandName = trimmed.slice(1).split(/\s+/)[0].toLowerCase();
|
|
41
|
+
return this.commands.has(commandName);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Execute a command from message text
|
|
45
|
+
*
|
|
46
|
+
* @returns true if a command was executed, false otherwise
|
|
47
|
+
*/
|
|
48
|
+
async executeCommand(text, context) {
|
|
49
|
+
const trimmed = text.trim();
|
|
50
|
+
if (!trimmed.startsWith("!")) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const commandName = trimmed.slice(1).split(/\s+/)[0].toLowerCase();
|
|
54
|
+
const command = this.commands.get(commandName);
|
|
55
|
+
if (!command) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
this.logger.info(`Executing command: !${commandName}`, {
|
|
59
|
+
agentName: context.agentName,
|
|
60
|
+
channelId: context.channelId,
|
|
61
|
+
});
|
|
62
|
+
try {
|
|
63
|
+
await command.execute(context);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
68
|
+
this.logger.error(`Command !${commandName} failed: ${errorMessage}`);
|
|
69
|
+
try {
|
|
70
|
+
await context.reply(`An error occurred while executing \`!${commandName}\`. Please try again.`);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Ignore reply error
|
|
74
|
+
}
|
|
75
|
+
return true; // Command was attempted, even if it failed
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get all registered commands
|
|
80
|
+
*/
|
|
81
|
+
getCommands() {
|
|
82
|
+
return Array.from(this.commands.values());
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=command-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-handler.js","sourceRoot":"","sources":["../../src/commands/command-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsDH,gFAAgF;AAChF,kBAAkB;AAClB,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,OAAO,cAAc;IACjB,QAAQ,GAA+B,IAAI,GAAG,EAAE,CAAC;IACxC,MAAM,CAAuB;IAE9C,YAAY,UAAiC,EAAE;QAC7C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI;YAC9B,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;YACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;SAChB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,OAAsB;QACpC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAAY;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACnE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAClB,IAAY,EACZ,OAAuB;QAEvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACnE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAE/C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,WAAW,EAAE,EAAE;YACrD,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,WAAW,YAAY,YAAY,EAAE,CAAC,CAAC;YAErE,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,KAAK,CACjB,wCAAwC,WAAW,uBAAuB,CAC3E,CAAC;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;YAED,OAAO,IAAI,CAAC,CAAC,2CAA2C;QAC1D,CAAC;IACH,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,sBAAsB,CAAC;AAE1E,eAAO,MAAM,WAAW,EAAE,aAoBzB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* !help command — Show available commands
|
|
3
|
+
*/
|
|
4
|
+
export const helpCommand = {
|
|
5
|
+
name: "help",
|
|
6
|
+
description: "Show available commands",
|
|
7
|
+
async execute(context) {
|
|
8
|
+
const { agentName, reply } = context;
|
|
9
|
+
const helpMessage = `*${agentName} Bot Commands*
|
|
10
|
+
|
|
11
|
+
\`!help\` — Show this help message
|
|
12
|
+
\`!status\` — Show agent status and session info
|
|
13
|
+
\`!reset\` — Clear conversation context (start fresh session)
|
|
14
|
+
|
|
15
|
+
*Interacting with the bot:*
|
|
16
|
+
\u2022 Mention the bot in a configured channel to start a conversation
|
|
17
|
+
\u2022 The bot remembers context within each channel
|
|
18
|
+
\u2022 Use \`!reset\` to clear the conversation and start fresh`;
|
|
19
|
+
await reply(helpMessage);
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,WAAW,GAAkB;IACxC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,yBAAyB;IAEtC,KAAK,CAAC,OAAO,CAAC,OAAuB;QACnC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;QAErC,MAAM,WAAW,GAAG,IAAI,SAAS;;;;;;;;;gEAS2B,CAAC;QAE7D,MAAM,KAAK,CAAC,WAAW,CAAC,CAAC;IAC3B,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commands module for Slack
|
|
3
|
+
*
|
|
4
|
+
* Provides message prefix command handling.
|
|
5
|
+
*/
|
|
6
|
+
export { CommandHandler } from "./command-handler.js";
|
|
7
|
+
export type { CommandContext, PrefixCommand, CommandHandlerOptions, } from "./command-handler.js";
|
|
8
|
+
export { helpCommand } from "./help.js";
|
|
9
|
+
export { resetCommand } from "./reset.js";
|
|
10
|
+
export { statusCommand } from "./status.js";
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,YAAY,EACV,cAAc,EACd,aAAa,EACb,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Commands module for Slack
|
|
3
|
+
*
|
|
4
|
+
* Provides message prefix command handling.
|
|
5
|
+
*/
|
|
6
|
+
export { CommandHandler } from "./command-handler.js";
|
|
7
|
+
export { helpCommand } from "./help.js";
|
|
8
|
+
export { resetCommand } from "./reset.js";
|
|
9
|
+
export { statusCommand } from "./status.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQtD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../src/commands/reset.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,sBAAsB,CAAC;AAE1E,eAAO,MAAM,YAAY,EAAE,aAiB1B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* !reset command — Clear session for current channel
|
|
3
|
+
*/
|
|
4
|
+
export const resetCommand = {
|
|
5
|
+
name: "reset",
|
|
6
|
+
description: "Clear conversation context (start fresh session)",
|
|
7
|
+
async execute(context) {
|
|
8
|
+
const { channelId, sessionManager, reply } = context;
|
|
9
|
+
const cleared = await sessionManager.clearSession(channelId);
|
|
10
|
+
if (cleared) {
|
|
11
|
+
await reply("Session cleared. The next message will start a fresh conversation.");
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
await reply("No active session in this channel.");
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=reset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset.js","sourceRoot":"","sources":["../../src/commands/reset.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,CAAC,MAAM,YAAY,GAAkB;IACzC,IAAI,EAAE,OAAO;IACb,WAAW,EAAE,kDAAkD;IAE/D,KAAK,CAAC,OAAO,CAAC,OAAuB;QACnC,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;QAErD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;QAE7D,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,KAAK,CACT,oEAAoE,CACrE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,sBAAsB,CAAC;AA6D1E,eAAO,MAAM,aAAa,EAAE,aA4C3B,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* !status command — Show agent status and connection info
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format a timestamp for display
|
|
6
|
+
*/
|
|
7
|
+
function formatTimestamp(isoString) {
|
|
8
|
+
if (!isoString) {
|
|
9
|
+
return "N/A";
|
|
10
|
+
}
|
|
11
|
+
const date = new Date(isoString);
|
|
12
|
+
return date.toLocaleString();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Format duration since a timestamp
|
|
16
|
+
*/
|
|
17
|
+
function formatDuration(isoString) {
|
|
18
|
+
if (!isoString) {
|
|
19
|
+
return "N/A";
|
|
20
|
+
}
|
|
21
|
+
const startTime = new Date(isoString).getTime();
|
|
22
|
+
const now = Date.now();
|
|
23
|
+
const durationMs = now - startTime;
|
|
24
|
+
const seconds = Math.floor(durationMs / 1000);
|
|
25
|
+
const minutes = Math.floor(seconds / 60);
|
|
26
|
+
const hours = Math.floor(minutes / 60);
|
|
27
|
+
const days = Math.floor(hours / 24);
|
|
28
|
+
if (days > 0) {
|
|
29
|
+
return `${days}d ${hours % 24}h`;
|
|
30
|
+
}
|
|
31
|
+
if (hours > 0) {
|
|
32
|
+
return `${hours}h ${minutes % 60}m`;
|
|
33
|
+
}
|
|
34
|
+
if (minutes > 0) {
|
|
35
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
36
|
+
}
|
|
37
|
+
return `${seconds}s`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get status emoji based on connection status
|
|
41
|
+
*/
|
|
42
|
+
function getStatusEmoji(status) {
|
|
43
|
+
switch (status) {
|
|
44
|
+
case "connected":
|
|
45
|
+
return "\u{1F7E2}"; // Green circle
|
|
46
|
+
case "connecting":
|
|
47
|
+
case "reconnecting":
|
|
48
|
+
return "\u{1F7E1}"; // Yellow circle
|
|
49
|
+
case "disconnected":
|
|
50
|
+
case "disconnecting":
|
|
51
|
+
return "\u26AA"; // White circle
|
|
52
|
+
case "error":
|
|
53
|
+
return "\u{1F534}"; // Red circle
|
|
54
|
+
default:
|
|
55
|
+
return "\u2753"; // Question mark
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export const statusCommand = {
|
|
59
|
+
name: "status",
|
|
60
|
+
description: "Show agent status and connection info",
|
|
61
|
+
async execute(context) {
|
|
62
|
+
const { agentName, channelId, connectorState, sessionManager, reply } = context;
|
|
63
|
+
// Get session info for this channel
|
|
64
|
+
const session = await sessionManager.getSession(channelId);
|
|
65
|
+
// Build status message using Slack mrkdwn
|
|
66
|
+
const statusEmoji = getStatusEmoji(connectorState.status);
|
|
67
|
+
const botUsername = connectorState.botUser?.username ?? "Unknown";
|
|
68
|
+
let statusMessage = `*${agentName} Status*\n\n`;
|
|
69
|
+
statusMessage += `${statusEmoji} *Connection:* ${connectorState.status}\n`;
|
|
70
|
+
statusMessage += `*Bot:* ${botUsername}`;
|
|
71
|
+
if (connectorState.connectedAt) {
|
|
72
|
+
statusMessage += `\n*Connected:* ${formatTimestamp(connectorState.connectedAt)}`;
|
|
73
|
+
statusMessage += `\n*Uptime:* ${formatDuration(connectorState.connectedAt)}`;
|
|
74
|
+
}
|
|
75
|
+
if (connectorState.reconnectAttempts > 0) {
|
|
76
|
+
statusMessage += `\n*Reconnect Attempts:* ${connectorState.reconnectAttempts}`;
|
|
77
|
+
}
|
|
78
|
+
if (connectorState.lastError) {
|
|
79
|
+
statusMessage += `\n*Last Error:* ${connectorState.lastError}`;
|
|
80
|
+
}
|
|
81
|
+
// Session info
|
|
82
|
+
statusMessage += `\n\n*Session Info*`;
|
|
83
|
+
if (session) {
|
|
84
|
+
statusMessage += `\n*Session ID:* \`${session.sessionId.substring(0, 20)}...\``;
|
|
85
|
+
statusMessage += `\n*Last Activity:* ${formatTimestamp(session.lastMessageAt)}`;
|
|
86
|
+
statusMessage += `\n*Session Age:* ${formatDuration(session.lastMessageAt)}`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
statusMessage += `\nNo active session in this channel.`;
|
|
90
|
+
}
|
|
91
|
+
await reply(statusMessage);
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities for the Slack connector
|
|
3
|
+
*
|
|
4
|
+
* Provides error classification, user-friendly messages,
|
|
5
|
+
* and retry logic for Slack API operations.
|
|
6
|
+
*/
|
|
7
|
+
import type { SlackConnectorLogger } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Error categories for classification
|
|
10
|
+
*/
|
|
11
|
+
export declare enum ErrorCategory {
|
|
12
|
+
/** Authentication/authorization errors */
|
|
13
|
+
AUTH = "auth",
|
|
14
|
+
/** Rate limiting errors */
|
|
15
|
+
RATE_LIMIT = "rate_limit",
|
|
16
|
+
/** Network errors */
|
|
17
|
+
NETWORK = "network",
|
|
18
|
+
/** Slack API errors */
|
|
19
|
+
API = "api",
|
|
20
|
+
/** Internal errors */
|
|
21
|
+
INTERNAL = "internal",
|
|
22
|
+
/** Unknown errors */
|
|
23
|
+
UNKNOWN = "unknown"
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Classified error with category and user-facing message
|
|
27
|
+
*/
|
|
28
|
+
export interface ClassifiedError {
|
|
29
|
+
category: ErrorCategory;
|
|
30
|
+
userMessage: string;
|
|
31
|
+
isRetryable: boolean;
|
|
32
|
+
originalError: Error;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* User-friendly error messages
|
|
36
|
+
*/
|
|
37
|
+
export declare const USER_ERROR_MESSAGES: Record<string, string>;
|
|
38
|
+
/**
|
|
39
|
+
* Classify an error for appropriate handling
|
|
40
|
+
*/
|
|
41
|
+
export declare function classifyError(error: Error): ClassifiedError;
|
|
42
|
+
/**
|
|
43
|
+
* Execute a function safely, catching and logging errors
|
|
44
|
+
*/
|
|
45
|
+
export declare function safeExecute<T>(fn: () => Promise<T>, logger: SlackConnectorLogger, context: string): Promise<T | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* Execute a function safely and reply with error message on failure
|
|
48
|
+
*/
|
|
49
|
+
export declare function safeExecuteWithReply(fn: () => Promise<void>, reply: (content: string) => Promise<void>, logger: SlackConnectorLogger, context: string): Promise<void>;
|
|
50
|
+
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../src/error-handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAMvD;;GAEG;AACH,oBAAY,aAAa;IACvB,0CAA0C;IAC1C,IAAI,SAAS;IACb,2BAA2B;IAC3B,UAAU,eAAe;IACzB,qBAAqB;IACrB,OAAO,YAAY;IACnB,uBAAuB;IACvB,GAAG,QAAQ;IACX,sBAAsB;IACtB,QAAQ,aAAa;IACrB,qBAAqB;IACrB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,aAAa,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,KAAK,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAOtD,CAAC;AAEF;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,eAAe,CAsD3D;AAMD;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CASxB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACvB,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EACzC,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling utilities for the Slack connector
|
|
3
|
+
*
|
|
4
|
+
* Provides error classification, user-friendly messages,
|
|
5
|
+
* and retry logic for Slack API operations.
|
|
6
|
+
*/
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Error Classification
|
|
9
|
+
// =============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Error categories for classification
|
|
12
|
+
*/
|
|
13
|
+
export var ErrorCategory;
|
|
14
|
+
(function (ErrorCategory) {
|
|
15
|
+
/** Authentication/authorization errors */
|
|
16
|
+
ErrorCategory["AUTH"] = "auth";
|
|
17
|
+
/** Rate limiting errors */
|
|
18
|
+
ErrorCategory["RATE_LIMIT"] = "rate_limit";
|
|
19
|
+
/** Network errors */
|
|
20
|
+
ErrorCategory["NETWORK"] = "network";
|
|
21
|
+
/** Slack API errors */
|
|
22
|
+
ErrorCategory["API"] = "api";
|
|
23
|
+
/** Internal errors */
|
|
24
|
+
ErrorCategory["INTERNAL"] = "internal";
|
|
25
|
+
/** Unknown errors */
|
|
26
|
+
ErrorCategory["UNKNOWN"] = "unknown";
|
|
27
|
+
})(ErrorCategory || (ErrorCategory = {}));
|
|
28
|
+
/**
|
|
29
|
+
* User-friendly error messages
|
|
30
|
+
*/
|
|
31
|
+
export const USER_ERROR_MESSAGES = {
|
|
32
|
+
auth: "I'm having trouble authenticating with Slack. Please check the bot configuration.",
|
|
33
|
+
rate_limit: "I'm being rate limited by Slack. Please try again in a moment.",
|
|
34
|
+
network: "I'm having trouble connecting to Slack. Please try again later.",
|
|
35
|
+
api: "Something went wrong with the Slack API. Please try again.",
|
|
36
|
+
internal: "An internal error occurred. Please try again or use `!reset` to start a new session.",
|
|
37
|
+
unknown: "An unexpected error occurred. Please try again.",
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Classify an error for appropriate handling
|
|
41
|
+
*/
|
|
42
|
+
export function classifyError(error) {
|
|
43
|
+
const message = error.message.toLowerCase();
|
|
44
|
+
if (message.includes("invalid_auth") ||
|
|
45
|
+
message.includes("token_revoked") ||
|
|
46
|
+
message.includes("token_expired") ||
|
|
47
|
+
message.includes("not_authed")) {
|
|
48
|
+
return {
|
|
49
|
+
category: ErrorCategory.AUTH,
|
|
50
|
+
userMessage: USER_ERROR_MESSAGES.auth,
|
|
51
|
+
isRetryable: false,
|
|
52
|
+
originalError: error,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (message.includes("rate_limit") || message.includes("ratelimited")) {
|
|
56
|
+
return {
|
|
57
|
+
category: ErrorCategory.RATE_LIMIT,
|
|
58
|
+
userMessage: USER_ERROR_MESSAGES.rate_limit,
|
|
59
|
+
isRetryable: true,
|
|
60
|
+
originalError: error,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (message.includes("econnrefused") ||
|
|
64
|
+
message.includes("enotfound") ||
|
|
65
|
+
message.includes("timeout")) {
|
|
66
|
+
return {
|
|
67
|
+
category: ErrorCategory.NETWORK,
|
|
68
|
+
userMessage: USER_ERROR_MESSAGES.network,
|
|
69
|
+
isRetryable: true,
|
|
70
|
+
originalError: error,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (message.includes("slack") || message.includes("api")) {
|
|
74
|
+
return {
|
|
75
|
+
category: ErrorCategory.API,
|
|
76
|
+
userMessage: USER_ERROR_MESSAGES.api,
|
|
77
|
+
isRetryable: true,
|
|
78
|
+
originalError: error,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
category: ErrorCategory.UNKNOWN,
|
|
83
|
+
userMessage: USER_ERROR_MESSAGES.unknown,
|
|
84
|
+
isRetryable: false,
|
|
85
|
+
originalError: error,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// =============================================================================
|
|
89
|
+
// Safe Execution
|
|
90
|
+
// =============================================================================
|
|
91
|
+
/**
|
|
92
|
+
* Execute a function safely, catching and logging errors
|
|
93
|
+
*/
|
|
94
|
+
export async function safeExecute(fn, logger, context) {
|
|
95
|
+
try {
|
|
96
|
+
return await fn();
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
100
|
+
logger.error(`Error in ${context}: ${errorMessage}`);
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Execute a function safely and reply with error message on failure
|
|
106
|
+
*/
|
|
107
|
+
export async function safeExecuteWithReply(fn, reply, logger, context) {
|
|
108
|
+
try {
|
|
109
|
+
await fn();
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
113
|
+
const classified = classifyError(err);
|
|
114
|
+
logger.error(`Error in ${context}: ${err.message}`);
|
|
115
|
+
try {
|
|
116
|
+
await reply(classified.userMessage);
|
|
117
|
+
}
|
|
118
|
+
catch (replyError) {
|
|
119
|
+
logger.error(`Failed to send error reply: ${replyError.message}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../src/error-handler.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classes for the Slack connector
|
|
3
|
+
*
|
|
4
|
+
* Provides typed errors for Slack connection and message handling failures.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Error codes for Slack connector operations
|
|
8
|
+
*/
|
|
9
|
+
export declare enum SlackErrorCode {
|
|
10
|
+
CONNECTION_FAILED = "SLACK_CONNECTION_FAILED",
|
|
11
|
+
ALREADY_CONNECTED = "SLACK_ALREADY_CONNECTED",
|
|
12
|
+
MISSING_TOKEN = "SLACK_MISSING_TOKEN",
|
|
13
|
+
INVALID_TOKEN = "SLACK_INVALID_TOKEN",
|
|
14
|
+
MESSAGE_SEND_FAILED = "SLACK_MESSAGE_SEND_FAILED",
|
|
15
|
+
SOCKET_MODE_ERROR = "SLACK_SOCKET_MODE_ERROR"
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Base error class for Slack connector operations
|
|
19
|
+
*/
|
|
20
|
+
export declare class SlackConnectorError extends Error {
|
|
21
|
+
readonly code: SlackErrorCode;
|
|
22
|
+
constructor(message: string, code: SlackErrorCode, options?: {
|
|
23
|
+
cause?: Error;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Error thrown when connection to Slack fails
|
|
28
|
+
*/
|
|
29
|
+
export declare class SlackConnectionError extends SlackConnectorError {
|
|
30
|
+
constructor(message: string, options?: {
|
|
31
|
+
cause?: Error;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error thrown when attempting to connect while already connected
|
|
36
|
+
*/
|
|
37
|
+
export declare class AlreadyConnectedError extends SlackConnectorError {
|
|
38
|
+
constructor();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Error thrown when bot or app token is missing
|
|
42
|
+
*/
|
|
43
|
+
export declare class MissingTokenError extends SlackConnectorError {
|
|
44
|
+
readonly tokenType: "bot" | "app";
|
|
45
|
+
constructor(tokenType: "bot" | "app", envVar: string);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Error thrown when a token is invalid
|
|
49
|
+
*/
|
|
50
|
+
export declare class InvalidTokenError extends SlackConnectorError {
|
|
51
|
+
constructor(message: string, options?: {
|
|
52
|
+
cause?: Error;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Type guard to check if an error is a SlackConnectorError
|
|
57
|
+
*/
|
|
58
|
+
export declare function isSlackConnectorError(error: unknown): error is SlackConnectorError;
|
|
59
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,oBAAY,cAAc;IACxB,iBAAiB,4BAA4B;IAC7C,iBAAiB,4BAA4B;IAC7C,aAAa,wBAAwB;IACrC,aAAa,wBAAwB;IACrC,mBAAmB,8BAA8B;IACjD,iBAAiB,4BAA4B;CAC9C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,SAAgB,IAAI,EAAE,cAAc,CAAC;gBAGnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,EACpB,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAM9B;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,mBAAmB;gBAC/C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAIzD;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,mBAAmB;;CAQ7D;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,mBAAmB;IACxD,SAAgB,SAAS,EAAE,KAAK,GAAG,KAAK,CAAC;gBAE7B,SAAS,EAAE,KAAK,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM;CAQrD;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,mBAAmB;gBAC5C,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE;CAIzD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,mBAAmB,CAE9B"}
|