phinix 0.2.7 → 0.2.9
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/dist/analytics/index.d.ts +1 -1
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +1 -1
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/tracker.d.ts +4 -0
- package/dist/analytics/tracker.d.ts.map +1 -1
- package/dist/analytics/tracker.js +1 -1
- package/dist/analytics/tracker.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +15 -11
- package/dist/config.js.map +1 -1
- package/dist/tools/triggerFeedback.d.ts +60 -0
- package/dist/tools/triggerFeedback.d.ts.map +1 -1
- package/dist/tools/triggerFeedback.js +196 -27
- package/dist/tools/triggerFeedback.js.map +1 -1
- package/package.json +1 -1
- package/src/config.js +17 -12
- package/src/tools/triggerFeedback.js +222 -30
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* @description 埋点统计模块导出入口
|
|
3
3
|
* @author 无浊
|
|
4
4
|
*/
|
|
5
|
-
export { wrapServerWithAnalytics } from './tracker.js';
|
|
5
|
+
export { wrapServerWithAnalytics, SESSION_ID } from './tracker.js';
|
|
6
6
|
export { AnalyticsReporter } from './reporter.js';
|
|
7
7
|
export type { AnalyticsEvent, AnalyticsConfig, ReportResponse } from './types.js';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/analytics/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
6
|
import type { AnalyticsConfig } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* 会话ID(进程级别唯一)
|
|
9
|
+
*/
|
|
10
|
+
export declare const SESSION_ID: `${string}-${string}-${string}-${string}-${string}`;
|
|
7
11
|
/**
|
|
8
12
|
* 包装 McpServer 实例,添加埋点追踪
|
|
9
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/analytics/tracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/analytics/tracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAkB,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlE;;GAEG;AACH,eAAO,MAAM,UAAU,qDAAe,CAAC;AAwBvC;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,eAAe,GACtB,IAAI,CAkJN"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/analytics/tracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD;;GAEG;AACH,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/analytics/tracker.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.js"],"names":[],"mappings":"AAqCA,kCAA6C;;;;;;;AAhC7C,+BAA2C"}
|
package/dist/config.js
CHANGED
|
@@ -5,23 +5,27 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
5
5
|
const __dirname = path.dirname(__filename);
|
|
6
6
|
// 从环境变量或命令行参数获取项目根目录
|
|
7
7
|
function getProjectRoot() {
|
|
8
|
-
//
|
|
8
|
+
// 优先级:环境变量 > 当前工作目录 > 命令行参数
|
|
9
|
+
// 这样的优先级更适合 MCP 客户端通过 env 或 cwd 配置传入工作区路径
|
|
10
|
+
// 1. 优先使用环境变量(从 MCP 客户端配置的 env.PROJECT_ROOT 传入)
|
|
11
|
+
if (process.env.PROJECT_ROOT) {
|
|
12
|
+
return process.env.PROJECT_ROOT;
|
|
13
|
+
}
|
|
14
|
+
// 2. 使用当前工作目录(从 MCP 客户端配置的 cwd 传入)
|
|
15
|
+
const cwd = process.cwd();
|
|
9
16
|
const args = process.argv.slice(2);
|
|
10
|
-
//
|
|
17
|
+
// 检查是否通过命令行参数指定了路径
|
|
11
18
|
const projectRootArg = args.find((arg) => arg.startsWith("--project-root="));
|
|
12
19
|
if (projectRootArg) {
|
|
13
20
|
return projectRootArg.split("=")[1];
|
|
14
21
|
}
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// 检查环境变量
|
|
20
|
-
if (process.env.PROJECT_ROOT) {
|
|
21
|
-
return process.env.PROJECT_ROOT;
|
|
22
|
+
// 检查位置参数(第一个非选项参数)
|
|
23
|
+
const positionalArg = args.find((arg) => !arg.startsWith("--"));
|
|
24
|
+
if (positionalArg) {
|
|
25
|
+
return positionalArg;
|
|
22
26
|
}
|
|
23
|
-
// 默认使用当前工作目录
|
|
24
|
-
return
|
|
27
|
+
// 3. 默认使用当前工作目录
|
|
28
|
+
return cwd;
|
|
25
29
|
}
|
|
26
30
|
export const PROJECT_ROOT = getProjectRoot();
|
|
27
31
|
export { __dirname };
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.js"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,cAAc;AACd,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,qBAAqB;AACrB,SAAS,cAAc;IACrB,4BAA4B;IAC5B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.js"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,cAAc;AACd,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,qBAAqB;AACrB,SAAS,cAAc;IACrB,4BAA4B;IAC5B,0CAA0C;IAE1C,gDAAgD;IAChD,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC7B,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAClC,CAAC;IAED,mCAAmC;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnC,mBAAmB;IACnB,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC7E,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,mBAAmB;IACnB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,gBAAgB;IAChB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,cAAc,EAAE,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,CAAC;AAErB,SAAS;AACT,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,kDAAkD;IAClD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,KAAK,OAAO;IAElD,sBAAsB;IACtB,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAC1C,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,oBAAoB;QACzD,CAAC,CAAC;YACE,kDAAkD,EAAG,OAAO;YAC5D,mDAAmD,CAAE,OAAO;SAC7D;IAEL,uBAAuB;IACvB,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC;IAEhF,eAAe;IACf,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,GAAG,EAAE,EAAE,CAAC;CACnE,CAAC"}
|
|
@@ -7,8 +7,14 @@ export function triggerFeedback({ componentName }: {
|
|
|
7
7
|
}[];
|
|
8
8
|
data: {
|
|
9
9
|
traceId: `${string}-${string}-${string}-${string}-${string}`;
|
|
10
|
+
sessionId: `${string}-${string}-${string}-${string}-${string}`;
|
|
10
11
|
status: string;
|
|
12
|
+
port: number;
|
|
11
13
|
error?: undefined;
|
|
14
|
+
focusedInstances?: undefined;
|
|
15
|
+
deferredInstances?: undefined;
|
|
16
|
+
totalInstances?: undefined;
|
|
17
|
+
failedInstances?: undefined;
|
|
12
18
|
};
|
|
13
19
|
} | {
|
|
14
20
|
content: {
|
|
@@ -17,8 +23,62 @@ export function triggerFeedback({ componentName }: {
|
|
|
17
23
|
}[];
|
|
18
24
|
data: {
|
|
19
25
|
traceId: `${string}-${string}-${string}-${string}-${string}`;
|
|
26
|
+
sessionId: `${string}-${string}-${string}-${string}-${string}`;
|
|
20
27
|
status: string;
|
|
21
28
|
error: any;
|
|
29
|
+
port: number;
|
|
30
|
+
focusedInstances?: undefined;
|
|
31
|
+
deferredInstances?: undefined;
|
|
32
|
+
totalInstances?: undefined;
|
|
33
|
+
failedInstances?: undefined;
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
content: {
|
|
37
|
+
type: string;
|
|
38
|
+
text: string;
|
|
39
|
+
}[];
|
|
40
|
+
data: {
|
|
41
|
+
traceId: `${string}-${string}-${string}-${string}-${string}`;
|
|
42
|
+
sessionId: `${string}-${string}-${string}-${string}-${string}`;
|
|
43
|
+
status: string;
|
|
44
|
+
focusedInstances: number;
|
|
45
|
+
deferredInstances: number;
|
|
46
|
+
totalInstances: number;
|
|
47
|
+
port?: undefined;
|
|
48
|
+
error?: undefined;
|
|
49
|
+
failedInstances?: undefined;
|
|
50
|
+
};
|
|
51
|
+
} | {
|
|
52
|
+
content: {
|
|
53
|
+
type: string;
|
|
54
|
+
text: string;
|
|
55
|
+
}[];
|
|
56
|
+
data: {
|
|
57
|
+
traceId: `${string}-${string}-${string}-${string}-${string}`;
|
|
58
|
+
sessionId: `${string}-${string}-${string}-${string}-${string}`;
|
|
59
|
+
status: string;
|
|
60
|
+
deferredInstances: number;
|
|
61
|
+
totalInstances: number;
|
|
62
|
+
port?: undefined;
|
|
63
|
+
error?: undefined;
|
|
64
|
+
focusedInstances?: undefined;
|
|
65
|
+
failedInstances?: undefined;
|
|
66
|
+
};
|
|
67
|
+
} | {
|
|
68
|
+
content: {
|
|
69
|
+
type: string;
|
|
70
|
+
text: string;
|
|
71
|
+
}[];
|
|
72
|
+
data: {
|
|
73
|
+
traceId: `${string}-${string}-${string}-${string}-${string}`;
|
|
74
|
+
sessionId: `${string}-${string}-${string}-${string}-${string}`;
|
|
75
|
+
status: string;
|
|
76
|
+
totalInstances: number;
|
|
77
|
+
failedInstances: number;
|
|
78
|
+
port?: undefined;
|
|
79
|
+
error?: undefined;
|
|
80
|
+
focusedInstances?: undefined;
|
|
81
|
+
deferredInstances?: undefined;
|
|
22
82
|
};
|
|
23
83
|
}>;
|
|
24
84
|
export namespace triggerFeedbackSchema {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triggerFeedback.d.ts","sourceRoot":"","sources":["../../src/tools/triggerFeedback.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"triggerFeedback.d.ts","sourceRoot":"","sources":["../../src/tools/triggerFeedback.js"],"names":[],"mappings":"AAsHA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8IC;;;;kBApQiB,KAAK"}
|
|
@@ -1,62 +1,231 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import crypto from "crypto";
|
|
3
3
|
import http from "http";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import os from "os";
|
|
7
|
+
import { PROJECT_ROOT } from "../config.js";
|
|
8
|
+
import { SESSION_ID } from "../analytics/tracker.js";
|
|
4
9
|
export const triggerFeedbackSchema = {
|
|
5
10
|
componentName: z.string().describe("组件名称"),
|
|
6
11
|
};
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* 获取实例注册表文件路径
|
|
14
|
+
* @returns {string} 实例注册表文件路径
|
|
15
|
+
*/
|
|
16
|
+
function getInstancesFilePath() {
|
|
17
|
+
const homeDir = os.homedir();
|
|
18
|
+
return path.join(homeDir, ".mcp-feedback", "instances.json");
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 获取全局配置文件路径(旧格式,用于向后兼容)
|
|
22
|
+
* @returns {string} 全局配置文件路径
|
|
23
|
+
*/
|
|
24
|
+
function getGlobalConfigPath() {
|
|
25
|
+
const homeDir = os.homedir();
|
|
26
|
+
return path.join(homeDir, ".mcp-feedback", "ports.json");
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 从全局配置文件读取插件端口(旧格式,用于向后兼容)
|
|
30
|
+
* @param {string} workspacePath - 工作区路径
|
|
31
|
+
* @returns {number|null} 端口号,失败返回 null
|
|
32
|
+
*/
|
|
33
|
+
function getPluginPort(workspacePath) {
|
|
34
|
+
const configPath = getGlobalConfigPath();
|
|
35
|
+
if (!fs.existsSync(configPath)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
13
38
|
try {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
39
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
40
|
+
const allConfigs = JSON.parse(content);
|
|
41
|
+
// 查找匹配的工作区配置
|
|
42
|
+
const config = allConfigs[workspacePath];
|
|
43
|
+
return config ? config.port : null;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error("读取端口配置失败:", error.message);
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 从实例注册表读取所有活跃实例
|
|
52
|
+
* @returns {Array} 实例列表
|
|
53
|
+
*/
|
|
54
|
+
function getAllActiveInstances() {
|
|
55
|
+
const instancesPath = getInstancesFilePath();
|
|
56
|
+
if (!fs.existsSync(instancesPath)) {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const content = fs.readFileSync(instancesPath, "utf-8");
|
|
61
|
+
const registry = JSON.parse(content);
|
|
62
|
+
return Object.values(registry.instances || {});
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
console.error("读取实例注册表失败:", error.message);
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 发送 HTTP 请求到指定端口
|
|
71
|
+
* @param {number} port - 端口号
|
|
72
|
+
* @param {string} componentName - 组件名称
|
|
73
|
+
* @param {string} traceId - 追踪ID
|
|
74
|
+
* @param {string} sessionId - 会话ID
|
|
75
|
+
* @returns {Promise<Object>} 响应结果
|
|
76
|
+
*/
|
|
77
|
+
function sendTriggerRequest(port, componentName, traceId, sessionId) {
|
|
78
|
+
const url = `http://127.0.0.1:${port}/trigger-feedback?component=${encodeURIComponent(componentName)}&traceId=${traceId}&sessionId=${sessionId}`;
|
|
79
|
+
return new Promise((resolve, reject) => {
|
|
80
|
+
const req = http.get(url, (res) => {
|
|
81
|
+
let data = "";
|
|
82
|
+
res.on("data", (chunk) => {
|
|
83
|
+
data += chunk;
|
|
24
84
|
});
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
85
|
+
res.on("end", () => {
|
|
86
|
+
try {
|
|
87
|
+
const response = JSON.parse(data);
|
|
88
|
+
resolve({ success: true, port, response });
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
resolve({ success: true, port, response: {} });
|
|
92
|
+
}
|
|
29
93
|
});
|
|
30
94
|
});
|
|
95
|
+
req.on("error", (err) => {
|
|
96
|
+
resolve({ success: false, port, error: err.message });
|
|
97
|
+
});
|
|
98
|
+
// 设置超时 1.5 秒
|
|
99
|
+
req.setTimeout(1500, () => {
|
|
100
|
+
req.destroy();
|
|
101
|
+
resolve({ success: false, port, error: "Request timeout" });
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
export async function triggerFeedback({ componentName }) {
|
|
106
|
+
// 1. 生成 TraceID
|
|
107
|
+
const traceId = crypto.randomUUID();
|
|
108
|
+
// 2. 尝试从新格式读取所有活跃实例
|
|
109
|
+
const instances = getAllActiveInstances();
|
|
110
|
+
// 3. 如果没有找到实例,尝试旧格式(向后兼容)
|
|
111
|
+
if (instances.length === 0) {
|
|
112
|
+
const legacyPort = getPluginPort(PROJECT_ROOT) || 9999;
|
|
113
|
+
console.log(`使用旧格式端口配置: ${legacyPort}`);
|
|
114
|
+
try {
|
|
115
|
+
const result = await sendTriggerRequest(legacyPort, componentName, traceId, SESSION_ID);
|
|
116
|
+
if (result.success) {
|
|
117
|
+
return {
|
|
118
|
+
content: [
|
|
119
|
+
{
|
|
120
|
+
type: "text",
|
|
121
|
+
text: `✅ 已触发反馈机制 (TraceID: ${traceId}, SessionID: ${SESSION_ID}, 端口: ${legacyPort})`,
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
data: {
|
|
125
|
+
traceId,
|
|
126
|
+
sessionId: SESSION_ID,
|
|
127
|
+
status: "triggered",
|
|
128
|
+
port: legacyPort,
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
throw new Error(result.error);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return {
|
|
138
|
+
content: [
|
|
139
|
+
{
|
|
140
|
+
type: "text",
|
|
141
|
+
text: `⚠️ 触发反馈失败 (TraceID: ${traceId}, SessionID: ${SESSION_ID})
|
|
142
|
+
PROJECT_ROOT: ${PROJECT_ROOT}
|
|
143
|
+
原因: ${error.message}
|
|
144
|
+
目标端口: ${legacyPort}
|
|
145
|
+
(这通常意味着本地 IDE 插件未启动或端口不可达)`,
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
data: {
|
|
149
|
+
traceId,
|
|
150
|
+
sessionId: SESSION_ID,
|
|
151
|
+
status: "failed",
|
|
152
|
+
error: error.message,
|
|
153
|
+
port: legacyPort,
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// 4. 使用新格式:广播到所有活跃实例
|
|
159
|
+
console.log(`找到 ${instances.length} 个活跃实例,开始广播...`);
|
|
160
|
+
const results = await Promise.all(instances.map((instance) => sendTriggerRequest(instance.port, componentName, traceId, SESSION_ID)));
|
|
161
|
+
// 5. 分析结果
|
|
162
|
+
const successResults = results.filter((r) => r.success);
|
|
163
|
+
const focusedResults = successResults.filter((r) => r.response && r.response.hasFocus);
|
|
164
|
+
const deferredResults = successResults.filter((r) => r.response && r.response.status === "deferred");
|
|
165
|
+
// 6. 如果有窗口有焦点,认为触发成功
|
|
166
|
+
if (focusedResults.length > 0) {
|
|
167
|
+
const focusedPorts = focusedResults.map((r) => r.port).join(", ");
|
|
31
168
|
return {
|
|
32
169
|
content: [
|
|
33
170
|
{
|
|
34
171
|
type: "text",
|
|
35
|
-
text: `✅ 已触发反馈机制 (TraceID: ${traceId})
|
|
172
|
+
text: `✅ 已触发反馈机制 (TraceID: ${traceId}, SessionID: ${SESSION_ID})
|
|
173
|
+
有焦点的窗口: ${focusedResults.length} 个 (端口: ${focusedPorts})
|
|
174
|
+
缓存的窗口: ${deferredResults.length} 个`,
|
|
36
175
|
},
|
|
37
176
|
],
|
|
38
177
|
data: {
|
|
39
178
|
traceId,
|
|
179
|
+
sessionId: SESSION_ID,
|
|
40
180
|
status: "triggered",
|
|
181
|
+
focusedInstances: focusedResults.length,
|
|
182
|
+
deferredInstances: deferredResults.length,
|
|
183
|
+
totalInstances: instances.length,
|
|
41
184
|
},
|
|
42
185
|
};
|
|
43
186
|
}
|
|
44
|
-
|
|
187
|
+
// 7. 如果没有窗口有焦点,但有缓存的窗口
|
|
188
|
+
if (deferredResults.length > 0) {
|
|
189
|
+
const deferredPorts = deferredResults.map((r) => r.port).join(", ");
|
|
45
190
|
return {
|
|
46
191
|
content: [
|
|
47
192
|
{
|
|
48
193
|
type: "text",
|
|
49
|
-
text:
|
|
50
|
-
|
|
51
|
-
|
|
194
|
+
text: `⏳ 反馈已缓存 (TraceID: ${traceId}, SessionID: ${SESSION_ID})
|
|
195
|
+
所有窗口都没有焦点,反馈已缓存到状态栏
|
|
196
|
+
缓存的窗口: ${deferredResults.length} 个 (端口: ${deferredPorts})
|
|
197
|
+
用户可以点击状态栏按钮提交反馈`,
|
|
52
198
|
},
|
|
53
199
|
],
|
|
54
200
|
data: {
|
|
55
201
|
traceId,
|
|
56
|
-
|
|
57
|
-
|
|
202
|
+
sessionId: SESSION_ID,
|
|
203
|
+
status: "deferred",
|
|
204
|
+
deferredInstances: deferredResults.length,
|
|
205
|
+
totalInstances: instances.length,
|
|
58
206
|
},
|
|
59
207
|
};
|
|
60
208
|
}
|
|
209
|
+
// 8. 所有实例都失败
|
|
210
|
+
const failedResults = results.filter((r) => !r.success);
|
|
211
|
+
const errorMessages = failedResults.map((r) => `端口 ${r.port}: ${r.error}`).join("\n");
|
|
212
|
+
return {
|
|
213
|
+
content: [
|
|
214
|
+
{
|
|
215
|
+
type: "text",
|
|
216
|
+
text: `⚠️ 触发反馈失败 (TraceID: ${traceId}, SessionID: ${SESSION_ID})
|
|
217
|
+
找到 ${instances.length} 个实例,但全部连接失败
|
|
218
|
+
${errorMessages}
|
|
219
|
+
(这通常意味着本地 IDE 插件未启动或端口不可达)`,
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
data: {
|
|
223
|
+
traceId,
|
|
224
|
+
sessionId: SESSION_ID,
|
|
225
|
+
status: "failed",
|
|
226
|
+
totalInstances: instances.length,
|
|
227
|
+
failedInstances: failedResults.length,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
61
230
|
}
|
|
62
231
|
//# sourceMappingURL=triggerFeedback.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"triggerFeedback.js","sourceRoot":"","sources":["../../src/tools/triggerFeedback.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"triggerFeedback.js","sourceRoot":"","sources":["../../src/tools/triggerFeedback.js"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/config.js
CHANGED
|
@@ -7,27 +7,32 @@ const __dirname = path.dirname(__filename);
|
|
|
7
7
|
|
|
8
8
|
// 从环境变量或命令行参数获取项目根目录
|
|
9
9
|
function getProjectRoot() {
|
|
10
|
-
//
|
|
10
|
+
// 优先级:环境变量 > 当前工作目录 > 命令行参数
|
|
11
|
+
// 这样的优先级更适合 MCP 客户端通过 env 或 cwd 配置传入工作区路径
|
|
12
|
+
|
|
13
|
+
// 1. 优先使用环境变量(从 MCP 客户端配置的 env.PROJECT_ROOT 传入)
|
|
14
|
+
if (process.env.PROJECT_ROOT) {
|
|
15
|
+
return process.env.PROJECT_ROOT;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// 2. 使用当前工作目录(从 MCP 客户端配置的 cwd 传入)
|
|
19
|
+
const cwd = process.cwd();
|
|
11
20
|
const args = process.argv.slice(2);
|
|
12
21
|
|
|
13
|
-
//
|
|
22
|
+
// 检查是否通过命令行参数指定了路径
|
|
14
23
|
const projectRootArg = args.find((arg) => arg.startsWith("--project-root="));
|
|
15
24
|
if (projectRootArg) {
|
|
16
25
|
return projectRootArg.split("=")[1];
|
|
17
26
|
}
|
|
18
27
|
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// 检查环境变量
|
|
25
|
-
if (process.env.PROJECT_ROOT) {
|
|
26
|
-
return process.env.PROJECT_ROOT;
|
|
28
|
+
// 检查位置参数(第一个非选项参数)
|
|
29
|
+
const positionalArg = args.find((arg) => !arg.startsWith("--"));
|
|
30
|
+
if (positionalArg) {
|
|
31
|
+
return positionalArg;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
// 默认使用当前工作目录
|
|
30
|
-
return
|
|
34
|
+
// 3. 默认使用当前工作目录
|
|
35
|
+
return cwd;
|
|
31
36
|
}
|
|
32
37
|
|
|
33
38
|
export const PROJECT_ROOT = getProjectRoot();
|
|
@@ -1,69 +1,261 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import crypto from "crypto";
|
|
3
3
|
import http from "http";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import os from "os";
|
|
7
|
+
import { PROJECT_ROOT } from "../config.js";
|
|
8
|
+
import { SESSION_ID } from "../analytics/tracker.js";
|
|
4
9
|
|
|
5
10
|
export const triggerFeedbackSchema = {
|
|
6
11
|
componentName: z.string().describe("组件名称"),
|
|
7
12
|
};
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
/**
|
|
15
|
+
* 获取实例注册表文件路径
|
|
16
|
+
* @returns {string} 实例注册表文件路径
|
|
17
|
+
*/
|
|
18
|
+
function getInstancesFilePath() {
|
|
19
|
+
const homeDir = os.homedir();
|
|
20
|
+
return path.join(homeDir, ".mcp-feedback", "instances.json");
|
|
21
|
+
}
|
|
12
22
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
/**
|
|
24
|
+
* 获取全局配置文件路径(旧格式,用于向后兼容)
|
|
25
|
+
* @returns {string} 全局配置文件路径
|
|
26
|
+
*/
|
|
27
|
+
function getGlobalConfigPath() {
|
|
28
|
+
const homeDir = os.homedir();
|
|
29
|
+
return path.join(homeDir, ".mcp-feedback", "ports.json");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 从全局配置文件读取插件端口(旧格式,用于向后兼容)
|
|
34
|
+
* @param {string} workspacePath - 工作区路径
|
|
35
|
+
* @returns {number|null} 端口号,失败返回 null
|
|
36
|
+
*/
|
|
37
|
+
function getPluginPort(workspacePath) {
|
|
38
|
+
const configPath = getGlobalConfigPath();
|
|
39
|
+
|
|
40
|
+
if (!fs.existsSync(configPath)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
17
43
|
|
|
18
|
-
// 3. 发送 HTTP 请求 (fire and forget pattern, but we wait for connection to ensure it was sent)
|
|
19
44
|
try {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// 我们只关心请求是否发出,不严格关心响应内容,但为了严谨可以读取一下
|
|
23
|
-
res.resume();
|
|
24
|
-
resolve();
|
|
25
|
-
});
|
|
45
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
46
|
+
const allConfigs = JSON.parse(content);
|
|
26
47
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
48
|
+
// 查找匹配的工作区配置
|
|
49
|
+
const config = allConfigs[workspacePath];
|
|
50
|
+
return config ? config.port : null;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error("读取端口配置失败:", error.message);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 从实例注册表读取所有活跃实例
|
|
59
|
+
* @returns {Array} 实例列表
|
|
60
|
+
*/
|
|
61
|
+
function getAllActiveInstances() {
|
|
62
|
+
const instancesPath = getInstancesFilePath();
|
|
63
|
+
|
|
64
|
+
if (!fs.existsSync(instancesPath)) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
32
67
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
68
|
+
try {
|
|
69
|
+
const content = fs.readFileSync(instancesPath, "utf-8");
|
|
70
|
+
const registry = JSON.parse(content);
|
|
71
|
+
return Object.values(registry.instances || {});
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error("读取实例注册表失败:", error.message);
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 发送 HTTP 请求到指定端口
|
|
80
|
+
* @param {number} port - 端口号
|
|
81
|
+
* @param {string} componentName - 组件名称
|
|
82
|
+
* @param {string} traceId - 追踪ID
|
|
83
|
+
* @param {string} sessionId - 会话ID
|
|
84
|
+
* @returns {Promise<Object>} 响应结果
|
|
85
|
+
*/
|
|
86
|
+
function sendTriggerRequest(port, componentName, traceId, sessionId) {
|
|
87
|
+
const url = `http://127.0.0.1:${port}/trigger-feedback?component=${encodeURIComponent(
|
|
88
|
+
componentName
|
|
89
|
+
)}&traceId=${traceId}&sessionId=${sessionId}`;
|
|
90
|
+
|
|
91
|
+
return new Promise((resolve, reject) => {
|
|
92
|
+
const req = http.get(url, (res) => {
|
|
93
|
+
let data = "";
|
|
94
|
+
res.on("data", (chunk) => {
|
|
95
|
+
data += chunk;
|
|
96
|
+
});
|
|
97
|
+
res.on("end", () => {
|
|
98
|
+
try {
|
|
99
|
+
const response = JSON.parse(data);
|
|
100
|
+
resolve({ success: true, port, response });
|
|
101
|
+
} catch (error) {
|
|
102
|
+
resolve({ success: true, port, response: {} });
|
|
103
|
+
}
|
|
37
104
|
});
|
|
38
105
|
});
|
|
39
106
|
|
|
107
|
+
req.on("error", (err) => {
|
|
108
|
+
resolve({ success: false, port, error: err.message });
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// 设置超时 1.5 秒
|
|
112
|
+
req.setTimeout(1500, () => {
|
|
113
|
+
req.destroy();
|
|
114
|
+
resolve({ success: false, port, error: "Request timeout" });
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export async function triggerFeedback({ componentName }) {
|
|
120
|
+
// 1. 生成 TraceID
|
|
121
|
+
const traceId = crypto.randomUUID();
|
|
122
|
+
|
|
123
|
+
// 2. 尝试从新格式读取所有活跃实例
|
|
124
|
+
const instances = getAllActiveInstances();
|
|
125
|
+
|
|
126
|
+
// 3. 如果没有找到实例,尝试旧格式(向后兼容)
|
|
127
|
+
if (instances.length === 0) {
|
|
128
|
+
const legacyPort = getPluginPort(PROJECT_ROOT) || 9999;
|
|
129
|
+
console.log(`使用旧格式端口配置: ${legacyPort}`);
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const result = await sendTriggerRequest(legacyPort, componentName, traceId, SESSION_ID);
|
|
133
|
+
|
|
134
|
+
if (result.success) {
|
|
135
|
+
return {
|
|
136
|
+
content: [
|
|
137
|
+
{
|
|
138
|
+
type: "text",
|
|
139
|
+
text: `✅ 已触发反馈机制 (TraceID: ${traceId}, SessionID: ${SESSION_ID}, 端口: ${legacyPort})`,
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
data: {
|
|
143
|
+
traceId,
|
|
144
|
+
sessionId: SESSION_ID,
|
|
145
|
+
status: "triggered",
|
|
146
|
+
port: legacyPort,
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
} else {
|
|
150
|
+
throw new Error(result.error);
|
|
151
|
+
}
|
|
152
|
+
} catch (error) {
|
|
153
|
+
return {
|
|
154
|
+
content: [
|
|
155
|
+
{
|
|
156
|
+
type: "text",
|
|
157
|
+
text: `⚠️ 触发反馈失败 (TraceID: ${traceId}, SessionID: ${SESSION_ID})
|
|
158
|
+
PROJECT_ROOT: ${PROJECT_ROOT}
|
|
159
|
+
原因: ${error.message}
|
|
160
|
+
目标端口: ${legacyPort}
|
|
161
|
+
(这通常意味着本地 IDE 插件未启动或端口不可达)`,
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
data: {
|
|
165
|
+
traceId,
|
|
166
|
+
sessionId: SESSION_ID,
|
|
167
|
+
status: "failed",
|
|
168
|
+
error: error.message,
|
|
169
|
+
port: legacyPort,
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 4. 使用新格式:广播到所有活跃实例
|
|
176
|
+
console.log(`找到 ${instances.length} 个活跃实例,开始广播...`);
|
|
177
|
+
|
|
178
|
+
const results = await Promise.all(
|
|
179
|
+
instances.map((instance) =>
|
|
180
|
+
sendTriggerRequest(instance.port, componentName, traceId, SESSION_ID)
|
|
181
|
+
)
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
// 5. 分析结果
|
|
185
|
+
const successResults = results.filter((r) => r.success);
|
|
186
|
+
const focusedResults = successResults.filter(
|
|
187
|
+
(r) => r.response && r.response.hasFocus
|
|
188
|
+
);
|
|
189
|
+
const deferredResults = successResults.filter(
|
|
190
|
+
(r) => r.response && r.response.status === "deferred"
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// 6. 如果有窗口有焦点,认为触发成功
|
|
194
|
+
if (focusedResults.length > 0) {
|
|
195
|
+
const focusedPorts = focusedResults.map((r) => r.port).join(", ");
|
|
40
196
|
return {
|
|
41
197
|
content: [
|
|
42
198
|
{
|
|
43
199
|
type: "text",
|
|
44
|
-
text: `✅ 已触发反馈机制 (TraceID: ${traceId})
|
|
200
|
+
text: `✅ 已触发反馈机制 (TraceID: ${traceId}, SessionID: ${SESSION_ID})
|
|
201
|
+
有焦点的窗口: ${focusedResults.length} 个 (端口: ${focusedPorts})
|
|
202
|
+
缓存的窗口: ${deferredResults.length} 个`,
|
|
45
203
|
},
|
|
46
204
|
],
|
|
47
205
|
data: {
|
|
48
206
|
traceId,
|
|
207
|
+
sessionId: SESSION_ID,
|
|
49
208
|
status: "triggered",
|
|
209
|
+
focusedInstances: focusedResults.length,
|
|
210
|
+
deferredInstances: deferredResults.length,
|
|
211
|
+
totalInstances: instances.length,
|
|
50
212
|
},
|
|
51
213
|
};
|
|
52
|
-
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// 7. 如果没有窗口有焦点,但有缓存的窗口
|
|
217
|
+
if (deferredResults.length > 0) {
|
|
218
|
+
const deferredPorts = deferredResults.map((r) => r.port).join(", ");
|
|
53
219
|
return {
|
|
54
220
|
content: [
|
|
55
221
|
{
|
|
56
222
|
type: "text",
|
|
57
|
-
text:
|
|
58
|
-
|
|
59
|
-
|
|
223
|
+
text: `⏳ 反馈已缓存 (TraceID: ${traceId}, SessionID: ${SESSION_ID})
|
|
224
|
+
所有窗口都没有焦点,反馈已缓存到状态栏
|
|
225
|
+
缓存的窗口: ${deferredResults.length} 个 (端口: ${deferredPorts})
|
|
226
|
+
用户可以点击状态栏按钮提交反馈`,
|
|
60
227
|
},
|
|
61
228
|
],
|
|
62
229
|
data: {
|
|
63
230
|
traceId,
|
|
64
|
-
|
|
65
|
-
|
|
231
|
+
sessionId: SESSION_ID,
|
|
232
|
+
status: "deferred",
|
|
233
|
+
deferredInstances: deferredResults.length,
|
|
234
|
+
totalInstances: instances.length,
|
|
66
235
|
},
|
|
67
236
|
};
|
|
68
237
|
}
|
|
238
|
+
|
|
239
|
+
// 8. 所有实例都失败
|
|
240
|
+
const failedResults = results.filter((r) => !r.success);
|
|
241
|
+
const errorMessages = failedResults.map((r) => `端口 ${r.port}: ${r.error}`).join("\n");
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
content: [
|
|
245
|
+
{
|
|
246
|
+
type: "text",
|
|
247
|
+
text: `⚠️ 触发反馈失败 (TraceID: ${traceId}, SessionID: ${SESSION_ID})
|
|
248
|
+
找到 ${instances.length} 个实例,但全部连接失败
|
|
249
|
+
${errorMessages}
|
|
250
|
+
(这通常意味着本地 IDE 插件未启动或端口不可达)`,
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
data: {
|
|
254
|
+
traceId,
|
|
255
|
+
sessionId: SESSION_ID,
|
|
256
|
+
status: "failed",
|
|
257
|
+
totalInstances: instances.length,
|
|
258
|
+
failedInstances: failedResults.length,
|
|
259
|
+
},
|
|
260
|
+
};
|
|
69
261
|
}
|