harmony-build 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/README.md +265 -0
- package/dist/packages/arkanalyzer-mcp/src/index.d.ts +5 -0
- package/dist/packages/arkanalyzer-mcp/src/index.js +220 -0
- package/dist/packages/arkanalyzer-mcp/src/index.js.map +1 -0
- package/dist/packages/arkcheck-mcp/src/index.d.ts +5 -0
- package/dist/packages/arkcheck-mcp/src/index.js +160 -0
- package/dist/packages/arkcheck-mcp/src/index.js.map +1 -0
- package/dist/packages/arkcheck-mcp/src/rules.d.ts +15 -0
- package/dist/packages/arkcheck-mcp/src/rules.js +90 -0
- package/dist/packages/arkcheck-mcp/src/rules.js.map +1 -0
- package/dist/packages/dev-mcp/src/hvigor-bridge.d.ts +31 -0
- package/dist/packages/dev-mcp/src/hvigor-bridge.js +179 -0
- package/dist/packages/dev-mcp/src/hvigor-bridge.js.map +1 -0
- package/dist/packages/dev-mcp/src/index.d.ts +5 -0
- package/dist/packages/dev-mcp/src/index.js +256 -0
- package/dist/packages/dev-mcp/src/index.js.map +1 -0
- package/dist/packages/dev-mcp/src/log-stream.d.ts +56 -0
- package/dist/packages/dev-mcp/src/log-stream.js +147 -0
- package/dist/packages/dev-mcp/src/log-stream.js.map +1 -0
- package/dist/packages/harmony-knowledge-mcp/src/index.d.ts +5 -0
- package/dist/packages/harmony-knowledge-mcp/src/index.js +164 -0
- package/dist/packages/harmony-knowledge-mcp/src/index.js.map +1 -0
- package/dist/packages/hdc-mcp/src/hdc-runner.d.ts +32 -0
- package/dist/packages/hdc-mcp/src/hdc-runner.js +60 -0
- package/dist/packages/hdc-mcp/src/hdc-runner.js.map +1 -0
- package/dist/packages/hdc-mcp/src/index.d.ts +5 -0
- package/dist/packages/hdc-mcp/src/index.js +155 -0
- package/dist/packages/hdc-mcp/src/index.js.map +1 -0
- package/dist/packages/hvigor-mcp/src/index.d.ts +5 -0
- package/dist/packages/hvigor-mcp/src/index.js +300 -0
- package/dist/packages/hvigor-mcp/src/index.js.map +1 -0
- package/dist/packages/hvigor-mcp/src/log-parser.d.ts +28 -0
- package/dist/packages/hvigor-mcp/src/log-parser.js +65 -0
- package/dist/packages/hvigor-mcp/src/log-parser.js.map +1 -0
- package/dist/packages/mcp-common/src/entry.d.ts +1 -0
- package/dist/packages/mcp-common/src/entry.js +22 -0
- package/dist/packages/mcp-common/src/entry.js.map +1 -0
- package/dist/packages/mcp-common/src/errors.d.ts +13 -0
- package/dist/packages/mcp-common/src/errors.js +23 -0
- package/dist/packages/mcp-common/src/errors.js.map +1 -0
- package/dist/packages/mcp-common/src/index.d.ts +6 -0
- package/dist/packages/mcp-common/src/index.js +7 -0
- package/dist/packages/mcp-common/src/index.js.map +1 -0
- package/dist/packages/mcp-common/src/logger.d.ts +11 -0
- package/dist/packages/mcp-common/src/logger.js +32 -0
- package/dist/packages/mcp-common/src/logger.js.map +1 -0
- package/dist/packages/mcp-common/src/mcp-helpers.d.ts +41 -0
- package/dist/packages/mcp-common/src/mcp-helpers.js +94 -0
- package/dist/packages/mcp-common/src/mcp-helpers.js.map +1 -0
- package/dist/packages/mcp-common/src/safe-exec.d.ts +23 -0
- package/dist/packages/mcp-common/src/safe-exec.js +74 -0
- package/dist/packages/mcp-common/src/safe-exec.js.map +1 -0
- package/dist/packages/mcp-common/src/sandbox.d.ts +31 -0
- package/dist/packages/mcp-common/src/sandbox.js +96 -0
- package/dist/packages/mcp-common/src/sandbox.js.map +1 -0
- package/dist/packages/profiler-mcp/src/index.d.ts +5 -0
- package/dist/packages/profiler-mcp/src/index.js +148 -0
- package/dist/packages/profiler-mcp/src/index.js.map +1 -0
- package/dist/packages/profiler-mcp/src/trace-analyzer.d.ts +38 -0
- package/dist/packages/profiler-mcp/src/trace-analyzer.js +95 -0
- package/dist/packages/profiler-mcp/src/trace-analyzer.js.map +1 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.js +61 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/server/handlers.d.ts +11 -0
- package/dist/src/server/handlers.js +33 -0
- package/dist/src/server/handlers.js.map +1 -0
- package/dist/src/server/tools.d.ts +23 -0
- package/dist/src/server/tools.js +57 -0
- package/dist/src/server/tools.js.map +1 -0
- package/package.json +54 -0
- package//345/217/221/345/270/203/346/214/207/345/215/227.md +45 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/hdc-mcp/src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* hvigor-mcp: 鸿蒙 hvigor 构建系统的 MCP Server 化。
|
|
4
|
+
*
|
|
5
|
+
* 工具:
|
|
6
|
+
* - build_hap 编译 HAP/APP
|
|
7
|
+
* - clean 清理产物
|
|
8
|
+
* - sign_hap 签名(透传 hvigor sign 任务)
|
|
9
|
+
* - parse_build_log 从给定的 stdout/stderr 文本解析诊断(offline 用,便于 Self-Refine)
|
|
10
|
+
* - run_task 运行任意 hvigor 任务(白名单子集)
|
|
11
|
+
*/
|
|
12
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
13
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
14
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
import fs from "node:fs/promises";
|
|
17
|
+
import fsSync from "node:fs";
|
|
18
|
+
import os from "node:os";
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
import { createLogger, HarmonyMcpError, isMainModule, PathSandbox, registerTools, runCommand, } from "@harmony-mcp/common";
|
|
21
|
+
import { parseBuildLog } from "./log-parser.js";
|
|
22
|
+
const logger = createLogger("hvigor-mcp");
|
|
23
|
+
// v0.2: allowedRoots 现在只是"显式额外允许"的可选项;缺省也 OK,
|
|
24
|
+
// sandbox 会在收到 project_dir 时自动向上识别鸿蒙工程根并加入白名单。
|
|
25
|
+
const allowedRoots = (process.env.HARMONY_MCP_ALLOWED_ROOTS ?? "")
|
|
26
|
+
.split(path.delimiter)
|
|
27
|
+
.filter(Boolean);
|
|
28
|
+
const sandbox = new PathSandbox({ allowedRoots, autoDetectProjectRoot: true });
|
|
29
|
+
const HVIGOR_BIN_LEGACY_ENV = process.env.HVIGOR_BIN; // kept for backward compat, see resolveHvigorBin
|
|
30
|
+
void HVIGOR_BIN_LEGACY_ENV;
|
|
31
|
+
const TASK_WHITELIST = new Set([
|
|
32
|
+
"assembleHap",
|
|
33
|
+
"assembleApp",
|
|
34
|
+
"assembleHsp",
|
|
35
|
+
"clean",
|
|
36
|
+
"syncProject",
|
|
37
|
+
"signHap",
|
|
38
|
+
"test",
|
|
39
|
+
]);
|
|
40
|
+
// ---------- Schemas ----------
|
|
41
|
+
const ProjectField = z
|
|
42
|
+
.string()
|
|
43
|
+
.describe("鸿蒙工程根目录绝对路径(必须在 HARMONY_MCP_ALLOWED_ROOTS 之内)");
|
|
44
|
+
const BuildHapSchema = z.object({
|
|
45
|
+
project_dir: ProjectField,
|
|
46
|
+
module: z.string().optional().describe("可选 module 名"),
|
|
47
|
+
build_mode: z.enum(["debug", "release"]).default("debug")
|
|
48
|
+
.describe("通过 -p buildMode=... 传给 hvigor;不是 --mode(--mode 是工程自定义 product 名)"),
|
|
49
|
+
product: z.string().optional()
|
|
50
|
+
.describe("工程 build-profile.json5 里定义的 product 名(对应 hvigor --mode 参数);不填则使用工程默认 product"),
|
|
51
|
+
no_daemon: z.boolean().default(true).describe("禁用 hvigor daemon,保证 CI 稳定"),
|
|
52
|
+
});
|
|
53
|
+
const CleanSchema = z.object({
|
|
54
|
+
project_dir: ProjectField,
|
|
55
|
+
});
|
|
56
|
+
const SignHapSchema = z.object({
|
|
57
|
+
project_dir: ProjectField,
|
|
58
|
+
module: z.string().optional(),
|
|
59
|
+
});
|
|
60
|
+
const ParseBuildLogSchema = z.object({
|
|
61
|
+
stdout: z.string().default("").describe("hvigor 编译过程的 stdout"),
|
|
62
|
+
stderr: z.string().default("").describe("hvigor 编译过程的 stderr"),
|
|
63
|
+
});
|
|
64
|
+
const RunTaskSchema = z.object({
|
|
65
|
+
project_dir: ProjectField,
|
|
66
|
+
task: z.string().describe(`hvigor 任务名,必须在白名单内:${[...TASK_WHITELIST].join(", ")}`),
|
|
67
|
+
});
|
|
68
|
+
// ---------- Helpers ----------
|
|
69
|
+
/**
|
|
70
|
+
* 解析当前应使用哪个 hvigor 可执行文件。
|
|
71
|
+
* 优先级(v0.2):
|
|
72
|
+
* 1. 工程根下的 hvigorw / hvigorw.bat(标准做法,依赖工程内 hvigor wrapper)
|
|
73
|
+
* 2. 环境变量 HVIGOR_BIN(用户显式指定)
|
|
74
|
+
* 3. DevEco-Studio 自带的 hvigorw(macOS 默认 /Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw)
|
|
75
|
+
* 4. PATH 里能直接找到的 hvigorw
|
|
76
|
+
* 全部都找不到时抛 HVIGOR_BIN_NOT_FOUND,附带可执行的修复建议。
|
|
77
|
+
*/
|
|
78
|
+
function resolveHvigorBin(projectDir) {
|
|
79
|
+
const isWin = process.platform === "win32";
|
|
80
|
+
const localName = isWin ? "hvigorw.bat" : "hvigorw";
|
|
81
|
+
const localBin = path.join(projectDir, localName);
|
|
82
|
+
if (fsSync.existsSync(localBin))
|
|
83
|
+
return { bin: localBin, source: "project" };
|
|
84
|
+
if (process.env.HVIGOR_BIN) {
|
|
85
|
+
if (fsSync.existsSync(process.env.HVIGOR_BIN)) {
|
|
86
|
+
return { bin: process.env.HVIGOR_BIN, source: "env" };
|
|
87
|
+
}
|
|
88
|
+
// 环境变量给的是命令名,交给 spawn 走 PATH 解析
|
|
89
|
+
return { bin: process.env.HVIGOR_BIN, source: "env" };
|
|
90
|
+
}
|
|
91
|
+
// DevEco Studio 常见安装位置
|
|
92
|
+
const candidates = [];
|
|
93
|
+
if (process.platform === "darwin") {
|
|
94
|
+
candidates.push("/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw", path.join(os.homedir(), "Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw"));
|
|
95
|
+
}
|
|
96
|
+
else if (process.platform === "linux") {
|
|
97
|
+
candidates.push(path.join(os.homedir(), "DevEco-Studio/tools/hvigor/bin/hvigorw"), "/opt/DevEco-Studio/tools/hvigor/bin/hvigorw");
|
|
98
|
+
}
|
|
99
|
+
else if (isWin) {
|
|
100
|
+
candidates.push("C:\\Program Files\\Huawei\\DevEco Studio\\tools\\hvigor\\bin\\hvigorw.bat");
|
|
101
|
+
}
|
|
102
|
+
for (const c of candidates) {
|
|
103
|
+
if (fsSync.existsSync(c))
|
|
104
|
+
return { bin: c, source: "deveco" };
|
|
105
|
+
}
|
|
106
|
+
return { bin: "hvigorw", source: "path" };
|
|
107
|
+
}
|
|
108
|
+
async function ensureHarmonyProject(cwd) {
|
|
109
|
+
const hvigorFile = path.join(cwd, "hvigorfile.ts");
|
|
110
|
+
try {
|
|
111
|
+
await fs.access(hvigorFile);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
throw new HarmonyMcpError("NOT_A_HARMONY_PROJECT", `${cwd} 下未发现 hvigorfile.ts,看起来不是鸿蒙工程`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 候选 SDK 目录的"完整度"打分(越高越好):
|
|
119
|
+
* +100 含 default/hms(DevEco 整合包,含华为 HMS API,最完整)
|
|
120
|
+
* +50 含 default/openharmony 或顶层 openharmony
|
|
121
|
+
* +10 每个直接子目录下含 ets/toolchains/native 之一
|
|
122
|
+
* 0 表示完全不是 SDK。
|
|
123
|
+
*/
|
|
124
|
+
function scoreSdkRoot(dir) {
|
|
125
|
+
let score = 0;
|
|
126
|
+
try {
|
|
127
|
+
if (fsSync.existsSync(path.join(dir, "default/hms")))
|
|
128
|
+
score += 100;
|
|
129
|
+
if (fsSync.existsSync(path.join(dir, "default/openharmony")))
|
|
130
|
+
score += 50;
|
|
131
|
+
if (fsSync.existsSync(path.join(dir, "openharmony")))
|
|
132
|
+
score += 30;
|
|
133
|
+
const entries = fsSync.readdirSync(dir, { withFileTypes: true });
|
|
134
|
+
for (const ent of entries) {
|
|
135
|
+
if (!ent.isDirectory())
|
|
136
|
+
continue;
|
|
137
|
+
const sub = path.join(dir, ent.name);
|
|
138
|
+
for (const marker of ["ets", "toolchains", "native"]) {
|
|
139
|
+
if (fsSync.existsSync(path.join(sub, marker))) {
|
|
140
|
+
score += 10;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
/* fall through */
|
|
148
|
+
}
|
|
149
|
+
return score;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* 找一个可用的 DEVECO_SDK_HOME。
|
|
153
|
+
* v0.2.2 策略:把所有候选都"打分",挑分数最高的(>0)。
|
|
154
|
+
* 这样无论本机装了多套 SDK,都会优先选**完整度最高**的——通常就是 DevEco.app 内置的整合包。
|
|
155
|
+
* 用户显式设置 DEVECO_SDK_HOME 时尊重用户选择。
|
|
156
|
+
*/
|
|
157
|
+
function resolveDevecoSdkHome() {
|
|
158
|
+
const envVal = process.env.DEVECO_SDK_HOME;
|
|
159
|
+
if (envVal && fsSync.existsSync(envVal))
|
|
160
|
+
return envVal;
|
|
161
|
+
const home = os.homedir();
|
|
162
|
+
const candidates = [];
|
|
163
|
+
if (process.platform === "darwin") {
|
|
164
|
+
candidates.push("/Applications/DevEco-Studio.app/Contents/sdk", "/Applications/DevEco-Studio.app/Contents/SDK", path.join(home, "Applications/DevEco-Studio.app/Contents/sdk"), path.join(home, "Library/OpenHarmony/Sdk"), path.join(home, "Library/Huawei/Sdk"));
|
|
165
|
+
}
|
|
166
|
+
else if (process.platform === "linux") {
|
|
167
|
+
candidates.push("/opt/DevEco-Studio/sdk", path.join(home, "OpenHarmony/Sdk"), path.join(home, "Huawei/Sdk"));
|
|
168
|
+
}
|
|
169
|
+
else if (process.platform === "win32") {
|
|
170
|
+
candidates.push("C:\\Program Files\\Huawei\\DevEco Studio\\sdk", path.join(home, "AppData\\Local\\Huawei\\Sdk"));
|
|
171
|
+
}
|
|
172
|
+
let best;
|
|
173
|
+
for (const c of candidates) {
|
|
174
|
+
if (!fsSync.existsSync(c))
|
|
175
|
+
continue;
|
|
176
|
+
const s = scoreSdkRoot(c);
|
|
177
|
+
if (s > 0 && (!best || s > best.score))
|
|
178
|
+
best = { dir: c, score: s };
|
|
179
|
+
}
|
|
180
|
+
if (best)
|
|
181
|
+
return best.dir;
|
|
182
|
+
// 都打分 0:起码挑一个存在的让 hvigor 自己报更准确的错
|
|
183
|
+
for (const c of candidates)
|
|
184
|
+
if (fsSync.existsSync(c))
|
|
185
|
+
return c;
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
async function runHvigor(projectDir, args, timeoutMs = 600_000) {
|
|
189
|
+
const cwd = sandbox.resolve(projectDir);
|
|
190
|
+
await ensureHarmonyProject(cwd);
|
|
191
|
+
const { bin, source } = resolveHvigorBin(cwd);
|
|
192
|
+
const sdkHome = resolveDevecoSdkHome();
|
|
193
|
+
const env = {};
|
|
194
|
+
if (sdkHome)
|
|
195
|
+
env.DEVECO_SDK_HOME = sdkHome;
|
|
196
|
+
logger.info("invoking hvigor", { bin, source, cwd, args, sdkHome });
|
|
197
|
+
let r;
|
|
198
|
+
try {
|
|
199
|
+
r = await runCommand(bin, args, { cwd, timeoutMs, env });
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (err instanceof HarmonyMcpError && err.code === "EXEC_SPAWN_FAILED") {
|
|
203
|
+
throw new HarmonyMcpError("HVIGOR_BIN_NOT_FOUND", `无法启动 hvigor 命令:${bin}(来源 ${source})。
|
|
204
|
+
工程根 ${cwd} 下不存在 hvigorw / hvigorw.bat,且系统 PATH 与 DevEco-Studio 默认安装位置也未找到。
|
|
205
|
+
修复建议(任选其一):
|
|
206
|
+
1. 用 DevEco Studio 打开该工程一次,IDE 会自动生成 hvigorw、hvigorw.bat、hvigor/hvigor-wrapper.js 等文件。
|
|
207
|
+
2. 从其他能正常构建的鸿蒙工程复制以下文件到本工程根:
|
|
208
|
+
- hvigorw(并 chmod +x hvigorw)
|
|
209
|
+
- hvigorw.bat
|
|
210
|
+
- hvigor/hvigor-wrapper.js(若缺失)
|
|
211
|
+
3. 通过环境变量显式指定 hvigor 可执行路径:
|
|
212
|
+
export HVIGOR_BIN=/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw
|
|
213
|
+
4. 将 DevEco 安装目录里的 hvigor 加入 PATH:
|
|
214
|
+
export PATH="/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin:$PATH"
|
|
215
|
+
随后重新调用 build_hap 即可。`, { project_dir: cwd, attempted_bin: bin, source, args, original: err.message });
|
|
216
|
+
}
|
|
217
|
+
throw err;
|
|
218
|
+
}
|
|
219
|
+
const parsed = parseBuildLog(r.stdout, r.stderr);
|
|
220
|
+
return {
|
|
221
|
+
...parsed,
|
|
222
|
+
exit_code: r.exitCode,
|
|
223
|
+
duration_ms: r.durationMs,
|
|
224
|
+
truncated: r.truncated,
|
|
225
|
+
hvigor_bin: bin,
|
|
226
|
+
hvigor_bin_source: source,
|
|
227
|
+
deveco_sdk_home: sdkHome ?? null,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
// ---------- Tools ----------
|
|
231
|
+
export const NAMESPACE = "hvigor";
|
|
232
|
+
export const tools = [
|
|
233
|
+
{
|
|
234
|
+
name: "build_hap",
|
|
235
|
+
description: "编译 HAP/APP;返回结构化诊断(errors/warnings/hap_paths)",
|
|
236
|
+
schema: BuildHapSchema,
|
|
237
|
+
handler: async (a) => {
|
|
238
|
+
const args = [];
|
|
239
|
+
if (a.no_daemon)
|
|
240
|
+
args.push("--no-daemon");
|
|
241
|
+
args.push("assembleHap");
|
|
242
|
+
// hvigor 的 --mode 是工程自定义 product 名(如 default / module),不能传 debug/release
|
|
243
|
+
if (a.product)
|
|
244
|
+
args.push("--mode", "module", "-p", `product=${a.product}`);
|
|
245
|
+
// build_mode 走属性传递,hvigor 内部用 buildMode 区分调试/正式
|
|
246
|
+
args.push("-p", `buildMode=${a.build_mode}`);
|
|
247
|
+
if (a.module)
|
|
248
|
+
args.push("-p", `module=${a.module}`);
|
|
249
|
+
return runHvigor(a.project_dir, args);
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
name: "clean",
|
|
254
|
+
description: "清理工程产物(hvigorw clean)",
|
|
255
|
+
schema: CleanSchema,
|
|
256
|
+
handler: async (a) => runHvigor(a.project_dir, ["clean", "--no-daemon"]),
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: "sign_hap",
|
|
260
|
+
description: "对 HAP 进行签名(hvigorw signHap)",
|
|
261
|
+
schema: SignHapSchema,
|
|
262
|
+
handler: async (a) => {
|
|
263
|
+
const args = ["signHap", "--no-daemon"];
|
|
264
|
+
if (a.module)
|
|
265
|
+
args.push("-p", `module=${a.module}`);
|
|
266
|
+
return runHvigor(a.project_dir, args);
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
name: "parse_build_log",
|
|
271
|
+
description: "把 hvigor 编译输出解析为结构化诊断;可在 Agent 本地读到日志后调用",
|
|
272
|
+
schema: ParseBuildLogSchema,
|
|
273
|
+
handler: async (a) => parseBuildLog(a.stdout, a.stderr),
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
name: "run_task",
|
|
277
|
+
description: "运行任意 hvigor 任务(白名单受限)",
|
|
278
|
+
schema: RunTaskSchema,
|
|
279
|
+
handler: async (a) => {
|
|
280
|
+
if (!TASK_WHITELIST.has(a.task)) {
|
|
281
|
+
throw new HarmonyMcpError("TASK_NOT_ALLOWED", `task ${a.task} not in whitelist`, { allowed: [...TASK_WHITELIST] });
|
|
282
|
+
}
|
|
283
|
+
return runHvigor(a.project_dir, [a.task, "--no-daemon"]);
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
];
|
|
287
|
+
// ---------- Boot ----------
|
|
288
|
+
async function main() {
|
|
289
|
+
const server = new Server({ name: "harmony-hvigor-mcp", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
290
|
+
registerTools(server, { ListToolsRequestSchema, CallToolRequestSchema }, tools);
|
|
291
|
+
await server.connect(new StdioServerTransport());
|
|
292
|
+
logger.info("hvigor-mcp server started", { allowedRoots, autoResolveHvigor: true });
|
|
293
|
+
}
|
|
294
|
+
if (isMainModule(import.meta.url)) {
|
|
295
|
+
main().catch((err) => {
|
|
296
|
+
logger.error("fatal", { err: String(err) });
|
|
297
|
+
process.exit(1);
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/hvigor-mcp/src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hvigor 编译日志解析器。
|
|
3
|
+
*
|
|
4
|
+
* 目标:把人类可读的 build 输出转成 Agent 友好的结构化对象:
|
|
5
|
+
* { ok, errors[], warnings[], hap_paths[] }
|
|
6
|
+
*
|
|
7
|
+
* 规则覆盖(first pass,按需扩展):
|
|
8
|
+
* - ArkTS / TS 编译错误: file.ets:line:col - error TSxxxx: <msg>
|
|
9
|
+
* - hvigor 任务错误: ERROR: ... 后跟 At <file>:<line>:<col>
|
|
10
|
+
* - 警告: warning|WARN
|
|
11
|
+
* - 输出产物: "Built successfully" / hap_path 行
|
|
12
|
+
*/
|
|
13
|
+
export interface BuildDiagnostic {
|
|
14
|
+
severity: "error" | "warning";
|
|
15
|
+
file?: string;
|
|
16
|
+
line?: number;
|
|
17
|
+
column?: number;
|
|
18
|
+
code?: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ParsedBuildLog {
|
|
22
|
+
ok: boolean;
|
|
23
|
+
errors: BuildDiagnostic[];
|
|
24
|
+
warnings: BuildDiagnostic[];
|
|
25
|
+
hap_paths: string[];
|
|
26
|
+
summary: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function parseBuildLog(stdout: string, stderr: string): ParsedBuildLog;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hvigor 编译日志解析器。
|
|
3
|
+
*
|
|
4
|
+
* 目标:把人类可读的 build 输出转成 Agent 友好的结构化对象:
|
|
5
|
+
* { ok, errors[], warnings[], hap_paths[] }
|
|
6
|
+
*
|
|
7
|
+
* 规则覆盖(first pass,按需扩展):
|
|
8
|
+
* - ArkTS / TS 编译错误: file.ets:line:col - error TSxxxx: <msg>
|
|
9
|
+
* - hvigor 任务错误: ERROR: ... 后跟 At <file>:<line>:<col>
|
|
10
|
+
* - 警告: warning|WARN
|
|
11
|
+
* - 输出产物: "Built successfully" / hap_path 行
|
|
12
|
+
*/
|
|
13
|
+
const TS_LINE = /^(.+\.(?:ets|ts)):(\d+):(\d+)\s+-\s+(error|warning)\s+(TS\d+):\s+(.+)$/;
|
|
14
|
+
const HVIGOR_ERR = /^>\s*ERROR:\s+(.+)$/;
|
|
15
|
+
const HVIGOR_AT = /^\s+At\s+(.+?):(\d+):(\d+)$/;
|
|
16
|
+
const HAP_LINE = /(?:[\w./\\-]+\/)?[\w.-]+\.hap\b/g;
|
|
17
|
+
const BUILT_OK = /BUILD\s+SUCCESSFUL|Built\s+successfully/i;
|
|
18
|
+
const BUILT_FAIL = /BUILD\s+FAILED|Build\s+failed/i;
|
|
19
|
+
export function parseBuildLog(stdout, stderr) {
|
|
20
|
+
const errors = [];
|
|
21
|
+
const warnings = [];
|
|
22
|
+
const hapPaths = [];
|
|
23
|
+
const lines = (stdout + "\n" + stderr).split(/\r?\n/);
|
|
24
|
+
let pendingHvigorErr = null;
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
const ts = TS_LINE.exec(line);
|
|
27
|
+
if (ts) {
|
|
28
|
+
const diag = {
|
|
29
|
+
severity: ts[4] === "error" ? "error" : "warning",
|
|
30
|
+
file: ts[1],
|
|
31
|
+
line: Number(ts[2]),
|
|
32
|
+
column: Number(ts[3]),
|
|
33
|
+
code: ts[5],
|
|
34
|
+
message: ts[6].trim(),
|
|
35
|
+
};
|
|
36
|
+
(diag.severity === "error" ? errors : warnings).push(diag);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const herr = HVIGOR_ERR.exec(line);
|
|
40
|
+
if (herr) {
|
|
41
|
+
pendingHvigorErr = herr[1].trim();
|
|
42
|
+
errors.push({ severity: "error", message: pendingHvigorErr });
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const at = HVIGOR_AT.exec(line);
|
|
46
|
+
if (at && errors.length > 0) {
|
|
47
|
+
const last = errors[errors.length - 1];
|
|
48
|
+
last.file = at[1];
|
|
49
|
+
last.line = Number(at[2]);
|
|
50
|
+
last.column = Number(at[3]);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
for (const m of line.matchAll(HAP_LINE)) {
|
|
54
|
+
const p = m[0];
|
|
55
|
+
if (!hapPaths.includes(p))
|
|
56
|
+
hapPaths.push(p);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const ok = errors.length === 0 && (BUILT_OK.test(stdout + stderr) || !BUILT_FAIL.test(stdout + stderr));
|
|
60
|
+
const summary = ok
|
|
61
|
+
? `BUILD OK; warnings=${warnings.length}; hap=${hapPaths.length}`
|
|
62
|
+
: `BUILD FAILED; errors=${errors.length}; warnings=${warnings.length}`;
|
|
63
|
+
return { ok, errors, warnings, hap_paths: hapPaths, summary };
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=log-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-parser.js","sourceRoot":"","sources":["../../../../packages/hvigor-mcp/src/log-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isMainModule(metaUrl: string): boolean;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "是否作为主入口运行"的 ESM 守卫工具。
|
|
3
|
+
*
|
|
4
|
+
* 用法:
|
|
5
|
+
* if (isMainModule(import.meta.url)) main().catch(...);
|
|
6
|
+
*
|
|
7
|
+
* 这样同一个文件,既能直接 `node dist/index.js` 启动,
|
|
8
|
+
* 又能被聚合包 `import` 进去复用 tools 数组而不触发 server 启动。
|
|
9
|
+
*/
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
export function isMainModule(metaUrl) {
|
|
13
|
+
if (!process.argv[1])
|
|
14
|
+
return false;
|
|
15
|
+
try {
|
|
16
|
+
return path.resolve(process.argv[1]) === path.resolve(fileURLToPath(metaUrl));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../../../packages/mcp-common/src/entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一的错误类型,便于 MCP server 把异常转成结构化响应。
|
|
3
|
+
*/
|
|
4
|
+
export declare class HarmonyMcpError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
readonly details?: unknown;
|
|
7
|
+
constructor(code: string, message: string, details?: unknown);
|
|
8
|
+
}
|
|
9
|
+
export declare function toErrorPayload(err: unknown): {
|
|
10
|
+
code: string;
|
|
11
|
+
message: string;
|
|
12
|
+
details?: unknown;
|
|
13
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一的错误类型,便于 MCP server 把异常转成结构化响应。
|
|
3
|
+
*/
|
|
4
|
+
export class HarmonyMcpError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
details;
|
|
7
|
+
constructor(code, message, details) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.name = "HarmonyMcpError";
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.details = details;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function toErrorPayload(err) {
|
|
15
|
+
if (err instanceof HarmonyMcpError) {
|
|
16
|
+
return { code: err.code, message: err.message, details: err.details };
|
|
17
|
+
}
|
|
18
|
+
if (err instanceof Error) {
|
|
19
|
+
return { code: "INTERNAL_ERROR", message: err.message };
|
|
20
|
+
}
|
|
21
|
+
return { code: "INTERNAL_ERROR", message: String(err) };
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../../packages/mcp-common/src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,OAAO,CAAW;IAElC,YAAY,IAAY,EAAE,OAAe,EAAE,OAAiB;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/mcp-common/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 极简结构化日志,写到 stderr(stdio MCP server 的约定:stdout 只能放协议消息)。
|
|
3
|
+
*/
|
|
4
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
5
|
+
export interface Logger {
|
|
6
|
+
debug(msg: string, ctx?: Record<string, unknown>): void;
|
|
7
|
+
info(msg: string, ctx?: Record<string, unknown>): void;
|
|
8
|
+
warn(msg: string, ctx?: Record<string, unknown>): void;
|
|
9
|
+
error(msg: string, ctx?: Record<string, unknown>): void;
|
|
10
|
+
}
|
|
11
|
+
export declare function createLogger(server: string): Logger;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 极简结构化日志,写到 stderr(stdio MCP server 的约定:stdout 只能放协议消息)。
|
|
3
|
+
*/
|
|
4
|
+
const LEVEL_PRIORITY = {
|
|
5
|
+
debug: 10,
|
|
6
|
+
info: 20,
|
|
7
|
+
warn: 30,
|
|
8
|
+
error: 40,
|
|
9
|
+
};
|
|
10
|
+
const envLevel = (process.env.HARMONY_MCP_LOG_LEVEL ?? "info").toLowerCase();
|
|
11
|
+
const threshold = LEVEL_PRIORITY[envLevel] ?? LEVEL_PRIORITY.info;
|
|
12
|
+
function log(server, level, msg, ctx) {
|
|
13
|
+
if (LEVEL_PRIORITY[level] < threshold)
|
|
14
|
+
return;
|
|
15
|
+
const record = {
|
|
16
|
+
ts: new Date().toISOString(),
|
|
17
|
+
level,
|
|
18
|
+
server,
|
|
19
|
+
msg,
|
|
20
|
+
...(ctx ?? {}),
|
|
21
|
+
};
|
|
22
|
+
process.stderr.write(JSON.stringify(record) + "\n");
|
|
23
|
+
}
|
|
24
|
+
export function createLogger(server) {
|
|
25
|
+
return {
|
|
26
|
+
debug: (msg, ctx) => log(server, "debug", msg, ctx),
|
|
27
|
+
info: (msg, ctx) => log(server, "info", msg, ctx),
|
|
28
|
+
warn: (msg, ctx) => log(server, "warn", msg, ctx),
|
|
29
|
+
error: (msg, ctx) => log(server, "error", msg, ctx),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../packages/mcp-common/src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,cAAc,GAA6B;IAC/C,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,IAAI,EAAE,EAAE;IACR,KAAK,EAAE,EAAE;CACV,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,MAAM,CAAC,CAAC,WAAW,EAAc,CAAC;AACzF,MAAM,SAAS,GAAG,cAAc,CAAC,QAAQ,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC;AASlE,SAAS,GAAG,CAAC,MAAc,EAAE,KAAe,EAAE,GAAW,EAAE,GAA6B;IACtF,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,SAAS;QAAE,OAAO;IAC9C,MAAM,MAAM,GAAG;QACb,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,KAAK;QACL,MAAM;QACN,GAAG;QACH,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;KACf,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC;QACnD,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC;QACjD,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC;QACjD,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC;KACpD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP 服务器通用脚手架:
|
|
3
|
+
* - registerTools(server, defs):声明式地一次性注册 ListTools / CallTool 两个处理器
|
|
4
|
+
* - zodToJsonSchema:把 zod 对象转成 MCP 需要的 JSON Schema(仅支持本项目用到的子集)
|
|
5
|
+
* - ok(data) / fail(err):MCP tool 响应的便捷构造器
|
|
6
|
+
*
|
|
7
|
+
* 该模块只依赖 zod 的类型;@modelcontextprotocol/sdk 由调用方注入,避免 common 强耦合。
|
|
8
|
+
*/
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
export interface ToolDef<TSchema extends z.ZodObject<z.ZodRawShape>> {
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
schema: TSchema;
|
|
14
|
+
handler: (args: z.infer<TSchema>) => Promise<unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface McpServerLike {
|
|
17
|
+
setRequestHandler: (schema: any, handler: (req: any) => Promise<any>) => void;
|
|
18
|
+
}
|
|
19
|
+
export interface RegisterToolsDeps {
|
|
20
|
+
ListToolsRequestSchema: any;
|
|
21
|
+
CallToolRequestSchema: any;
|
|
22
|
+
}
|
|
23
|
+
export declare function registerTools(server: McpServerLike, deps: RegisterToolsDeps, tools: ToolDef<z.ZodObject<z.ZodRawShape>>[]): void;
|
|
24
|
+
export declare function ok(data: unknown): {
|
|
25
|
+
content: {
|
|
26
|
+
type: "text";
|
|
27
|
+
text: string;
|
|
28
|
+
}[];
|
|
29
|
+
};
|
|
30
|
+
export declare function fail(payload: {
|
|
31
|
+
code: string;
|
|
32
|
+
message: string;
|
|
33
|
+
details?: unknown;
|
|
34
|
+
}): {
|
|
35
|
+
isError: boolean;
|
|
36
|
+
content: {
|
|
37
|
+
type: "text";
|
|
38
|
+
text: string;
|
|
39
|
+
}[];
|
|
40
|
+
};
|
|
41
|
+
export declare function zodToJsonSchema(schema: z.ZodObject<z.ZodRawShape>): Record<string, unknown>;
|