mcp-lab-agent 2.1.2 → 2.1.3
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/README.md +6 -0
- package/package.json +1 -1
- package/slack-bot/src/config.js +62 -12
- package/slack-bot/src/index.js +4 -11
package/README.md
CHANGED
package/package.json
CHANGED
package/slack-bot/src/config.js
CHANGED
|
@@ -9,37 +9,80 @@ const SLACK_BOT_DIR = path.dirname(__dirname);
|
|
|
9
9
|
|
|
10
10
|
config({ path: path.join(SLACK_BOT_DIR, ".env") });
|
|
11
11
|
|
|
12
|
-
function
|
|
13
|
-
const
|
|
14
|
-
if (!
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
function getMcpJsonPath() {
|
|
13
|
+
const home = process.env.HOME || process.env.USERPROFILE;
|
|
14
|
+
if (!home) return null;
|
|
15
|
+
return path.join(home, ".cursor", "mcp.json");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function loadMcpConfig() {
|
|
19
|
+
const mcpPath = process.env.QA_LAB_MCP_CONFIG || getMcpJsonPath();
|
|
20
|
+
if (!mcpPath || !existsSync(mcpPath)) return null;
|
|
17
21
|
try {
|
|
18
|
-
|
|
19
|
-
return data.slack || data;
|
|
22
|
+
return JSON.parse(readFileSync(mcpPath, "utf8"));
|
|
20
23
|
} catch {
|
|
21
24
|
return null;
|
|
22
25
|
}
|
|
23
26
|
}
|
|
24
27
|
|
|
28
|
+
function getSlackConfigFromMcp() {
|
|
29
|
+
const mcp = loadMcpConfig();
|
|
30
|
+
const qa = mcp?.["qa-lab-agent"];
|
|
31
|
+
const slack = qa?.slack;
|
|
32
|
+
if (!slack) return null;
|
|
33
|
+
return {
|
|
34
|
+
id: slack.id || slack.channelId,
|
|
35
|
+
botToken: slack.botToken || slack.SLACK_BOT_TOKEN,
|
|
36
|
+
signingSecret: slack.signingSecret || slack.SLACK_SIGNING_SECRET,
|
|
37
|
+
repo: slack.repo || slack.REPO_URL,
|
|
38
|
+
branch: slack.branch || slack.REPO_BRANCH || "main",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function loadSlackConfig() {
|
|
43
|
+
const configPath = process.env.QA_LAB_CONFIG || path.join(ROOT, "qa-lab-agent.config.json");
|
|
44
|
+
if (existsSync(configPath)) {
|
|
45
|
+
try {
|
|
46
|
+
const data = JSON.parse(readFileSync(configPath, "utf8"));
|
|
47
|
+
return data.slack || data;
|
|
48
|
+
} catch {}
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getSlackTokens() {
|
|
54
|
+
const fromMcp = getSlackConfigFromMcp();
|
|
55
|
+
if (fromMcp?.botToken && fromMcp?.signingSecret) {
|
|
56
|
+
return { token: fromMcp.botToken, signingSecret: fromMcp.signingSecret };
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
token: process.env.SLACK_BOT_TOKEN,
|
|
60
|
+
signingSecret: process.env.SLACK_SIGNING_SECRET,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
25
64
|
function getRepoForChannel() {
|
|
65
|
+
const fromMcp = getSlackConfigFromMcp();
|
|
66
|
+
if (fromMcp?.repo) {
|
|
67
|
+
return { url: fromMcp.repo, branch: fromMcp.branch || "main" };
|
|
68
|
+
}
|
|
26
69
|
const repoUrl = process.env.REPO_URL;
|
|
27
|
-
const repoBranch = process.env.REPO_BRANCH || "main";
|
|
28
70
|
if (repoUrl) {
|
|
29
|
-
return { url: repoUrl, branch:
|
|
71
|
+
return { url: repoUrl, branch: process.env.REPO_BRANCH || "main" };
|
|
30
72
|
}
|
|
31
73
|
const cfg = loadSlackConfig();
|
|
32
74
|
const repo = cfg?.repo || cfg?.defaultRepo?.url;
|
|
33
75
|
const branch = cfg?.branch || cfg?.defaultRepo?.branch || "main";
|
|
34
76
|
if (!repo) {
|
|
35
|
-
throw new Error("Configure
|
|
77
|
+
throw new Error("Configure 'slack.repo' no ~/.cursor/mcp.json ou em qa-lab-agent.config.json");
|
|
36
78
|
}
|
|
37
79
|
return { url: repo, branch };
|
|
38
80
|
}
|
|
39
81
|
|
|
40
82
|
function getMcpLabAgentCmd() {
|
|
83
|
+
const fromMcp = loadMcpConfig()?.["qa-lab-agent"]?.mcpLabAgent;
|
|
41
84
|
const cfg = loadSlackConfig();
|
|
42
|
-
const mcp = cfg?.mcpLabAgent || { command: "npx", args: ["-y", "mcp-lab-agent@latest"] };
|
|
85
|
+
const mcp = fromMcp || cfg?.mcpLabAgent || { command: "npx", args: ["-y", "mcp-lab-agent@latest"] };
|
|
43
86
|
return { command: mcp.command, args: mcp.args || [] };
|
|
44
87
|
}
|
|
45
88
|
|
|
@@ -47,4 +90,11 @@ function getCloneBaseDir() {
|
|
|
47
90
|
return process.env.CLONE_BASE_DIR || path.join(process.cwd(), ".qa-lab-clones");
|
|
48
91
|
}
|
|
49
92
|
|
|
50
|
-
export {
|
|
93
|
+
export {
|
|
94
|
+
loadSlackConfig,
|
|
95
|
+
getRepoForChannel,
|
|
96
|
+
getMcpLabAgentCmd,
|
|
97
|
+
getCloneBaseDir,
|
|
98
|
+
getSlackConfigFromMcp,
|
|
99
|
+
getSlackTokens,
|
|
100
|
+
};
|
package/slack-bot/src/index.js
CHANGED
|
@@ -3,23 +3,16 @@
|
|
|
3
3
|
* QA Lab Slack Bot
|
|
4
4
|
* Recebe @mentions no Slack, executa mcp-lab-agent e posta relatório.
|
|
5
5
|
*
|
|
6
|
-
* Config: qa-lab-agent.
|
|
7
|
-
* Secrets: .env (SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET)
|
|
6
|
+
* Config: ~/.cursor/mcp.json (qa-lab-agent.slack) ou .env
|
|
8
7
|
*/
|
|
9
8
|
import { App } from "@slack/bolt";
|
|
10
|
-
import {
|
|
11
|
-
import path from "node:path";
|
|
12
|
-
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { getSlackTokens } from "./config.js";
|
|
13
10
|
import { registerAppMention } from "./handlers/app-mention.js";
|
|
14
11
|
|
|
15
|
-
const
|
|
16
|
-
config({ path: path.join(__dirname, "..", ".env") });
|
|
17
|
-
|
|
18
|
-
const token = process.env.SLACK_BOT_TOKEN;
|
|
19
|
-
const signingSecret = process.env.SLACK_SIGNING_SECRET;
|
|
12
|
+
const { token, signingSecret } = getSlackTokens();
|
|
20
13
|
|
|
21
14
|
if (!token || !signingSecret) {
|
|
22
|
-
console.error("Configure
|
|
15
|
+
console.error("Configure no ~/.cursor/mcp.json:\n \"qa-lab-agent\": { \"slack\": { \"botToken\": \"xoxb-...\", \"signingSecret\": \"...\" } }\n\nOu use .env (SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET)");
|
|
23
16
|
process.exit(1);
|
|
24
17
|
}
|
|
25
18
|
|