feihong-code 7.6.0 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +36 -22
- package/.github/ISSUE_TEMPLATE/config.yml +10 -13
- package/.github/ISSUE_TEMPLATE/feature_request.md +38 -13
- package/.github/PULL_REQUEST_TEMPLATE.md +65 -30
- package/.github/workflows/ci.yml +2 -2
- package/.github/workflows/release.yml +5 -5
- package/.github/workflows/swebench-real.yml +2 -2
- package/CONTRIBUTING.md +52 -3
- package/README.md +656 -636
- package/agent-team/.env.example +13 -0
- package/agent-team/README.md +42 -0
- package/agent-team/agents/__init__.py +0 -0
- package/agent-team/agents/l1_acquisition.py +207 -0
- package/agent-team/agents/l2_content.py +237 -0
- package/agent-team/agents/l3_conversion.py +148 -0
- package/agent-team/agents/l4_analysis.py +118 -0
- package/agent-team/agents/l5_management.py +52 -0
- package/agent-team/agents/registry.py +60 -0
- package/agent-team/config.py +39 -0
- package/agent-team/core/__init__.py +0 -0
- package/agent-team/core/agent.py +73 -0
- package/agent-team/core/models.py +347 -0
- package/agent-team/core/scheduler.py +150 -0
- package/agent-team/core/task.py +121 -0
- package/agent-team/feihongzhi.db +0 -0
- package/agent-team/llm/__init__.py +12 -0
- package/agent-team/llm/base.py +22 -0
- package/agent-team/llm/doubao_llm.py +52 -0
- package/agent-team/llm/mock_llm.py +42 -0
- package/agent-team/main.py +235 -0
- package/agent-team/requirements.txt +2 -0
- package/agent-team/skill_packager.py +248 -0
- package/agent-team/skills/01_AI/350/216/267/345/256/242/347/272/277/347/264/242/351/233/267/350/276/276/SKILL.md +40 -0
- package/agent-team/skills/01_AI/350/216/267/345/256/242/347/272/277/347/264/242/351/233/267/350/276/276/run.py +111 -0
- package/agent-team/skills/02_AI/351/224/200/345/224/256/350/267/237/350/277/233/351/224/200/345/206/240/SKILL.md +38 -0
- package/agent-team/skills/02_AI/351/224/200/345/224/256/350/267/237/350/277/233/351/224/200/345/206/240/run.py +108 -0
- package/agent-team/skills/03_/350/257/204/350/256/272/345/214/272/345/225/206/346/234/272/350/257/206/345/210/253/345/256/230/SKILL.md +38 -0
- package/agent-team/skills/03_/350/257/204/350/256/272/345/214/272/345/225/206/346/234/272/350/257/206/345/210/253/345/256/230/run.py +106 -0
- package/agent-team/skills/04_/345/256/242/346/210/267/350/201/212/345/244/251/346/210/220/344/272/244/345/210/206/346/236/220/345/256/230/SKILL.md +37 -0
- package/agent-team/skills/04_/345/256/242/346/210/267/350/201/212/345/244/251/346/210/220/344/272/244/345/210/206/346/236/220/345/256/230/run.py +107 -0
- package/agent-team/skills/05_/345/220/214/350/241/214/347/210/206/346/254/276/351/233/267/350/276/276/SKILL.md +38 -0
- package/agent-team/skills/05_/345/220/214/350/241/214/347/210/206/346/254/276/351/233/267/350/276/276/run.py +99 -0
- package/agent-team/skills/06_/346/257/217/346/227/245/347/262/276/345/207/206/350/216/267/345/256/242/351/200/211/351/242/230/345/256/230/SKILL.md +39 -0
- package/agent-team/skills/06_/346/257/217/346/227/245/347/262/276/345/207/206/350/216/267/345/256/242/351/200/211/351/242/230/345/256/230/run.py +103 -0
- package/agent-team/skills/07_AI/345/244/226/350/264/270/345/274/200/345/217/221/345/256/242/346/210/267/345/221/230/345/267/245/SKILL.md +39 -0
- package/agent-team/skills/07_AI/345/244/226/350/264/270/345/274/200/345/217/221/345/256/242/346/210/267/345/221/230/345/267/245/run.py +103 -0
- package/agent-team/skills/08_/345/260/217/347/272/242/344/271/246/347/262/276/345/207/206/350/216/267/345/256/242/345/221/230/345/267/245/SKILL.md +40 -0
- package/agent-team/skills/08_/345/260/217/347/272/242/344/271/246/347/262/276/345/207/206/350/216/267/345/256/242/345/221/230/345/267/245/run.py +97 -0
- package/agent-team/skills/09_/347/247/201/345/237/237/345/256/242/346/210/267/345/210/206/345/261/202/350/267/237/350/277/233/345/256/230/SKILL.md +38 -0
- package/agent-team/skills/09_/347/247/201/345/237/237/345/256/242/346/210/267/345/210/206/345/261/202/350/267/237/350/277/233/345/256/230/run.py +106 -0
- package/agent-team/skills/10_GEO/345/225/206/346/234/272/350/257/212/346/226/255/345/256/230/SKILL.md +38 -0
- package/agent-team/skills/10_GEO/345/225/206/346/234/272/350/257/212/346/226/255/345/256/230/run.py +108 -0
- package/agent-team/skills/11_/344/270/200/344/272/272/345/205/254/345/217/270AI/345/221/230/345/267/245/350/260/203/345/272/246/345/256/230/SKILL.md +37 -0
- package/agent-team/skills/11_/344/270/200/344/272/272/345/205/254/345/217/270AI/345/221/230/345/267/245/350/260/203/345/272/246/345/256/230/run.py +111 -0
- package/agent-team/skills/12_/350/200/201/346/235/277/347/237/255/350/247/206/351/242/221/350/216/267/345/256/242/350/204/232/346/234/254/345/256/230/SKILL.md +39 -0
- package/agent-team/skills/12_/350/200/201/346/235/277/347/237/255/350/247/206/351/242/221/350/216/267/345/256/242/350/204/232/346/234/254/345/256/230/run.py +104 -0
- package/agent-team/skills/13_/345/215/232/344/270/273/350/264/246/345/217/267/346/267/261/345/272/246/346/213/206/350/247/243/345/256/230/SKILL.md +37 -0
- package/agent-team/skills/13_/345/215/232/344/270/273/350/264/246/345/217/267/346/267/261/345/272/246/346/213/206/350/247/243/345/256/230/run.py +105 -0
- package/agent-team/skills/14_AI/347/237/255/350/247/206/351/242/221/350/207/252/345/212/250/345/211/252/350/276/221/345/270/210/SKILL.md +39 -0
- package/agent-team/skills/14_AI/347/237/255/350/247/206/351/242/221/350/207/252/345/212/250/345/211/252/350/276/221/345/270/210/run.py +108 -0
- package/agent-team/skills/15_/345/205/254/344/274/227/345/217/267/350/207/252/345/212/250/350/277/220/350/220/245/345/217/221/345/270/203/345/256/230/SKILL.md +38 -0
- package/agent-team/skills/15_/345/205/254/344/274/227/345/217/267/350/207/252/345/212/250/350/277/220/350/220/245/345/217/221/345/270/203/345/256/230/run.py +105 -0
- package/agent-team/skills/16_/350/241/214/344/270/232/346/267/261/345/272/246/345/210/206/346/236/220/345/270/210/SKILL.md +38 -0
- package/agent-team/skills/16_/350/241/214/344/270/232/346/267/261/345/272/246/345/210/206/346/236/220/345/270/210/run.py +108 -0
- package/agent-team/skills/17_/346/212/225/350/265/204/347/240/224/347/251/266/345/222/250/350/257/242/345/256/230/SKILL.md +38 -0
- package/agent-team/skills/17_/346/212/225/350/265/204/347/240/224/347/251/266/345/222/250/350/257/242/345/256/230/run.py +106 -0
- package/agent-team/tests/__init__.py +0 -0
- package/agent-team/tests/test_core.py +156 -0
- package/dist/agent/agent-session.js +103 -0
- package/dist/agent/agent-session.js.map +1 -0
- package/dist/agent/orchestrator.js +8 -0
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/steer.js +52 -0
- package/dist/agent/steer.js.map +1 -0
- package/dist/cli/run.js +2 -0
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/enterprise/policy.js +40 -17
- package/dist/enterprise/policy.js.map +1 -1
- package/dist/memory/honcho-store.js +231 -0
- package/dist/memory/honcho-store.js.map +1 -0
- package/dist/shared/log-rotator.js +238 -0
- package/dist/shared/log-rotator.js.map +1 -0
- package/dist/shared/sqlite-store.js +512 -0
- package/dist/shared/sqlite-store.js.map +1 -0
- package/dist/tools/agents/agents-bridge.js +144 -0
- package/dist/tools/agents/agents-bridge.js.map +1 -0
- package/dist/tools/desktop/desktop-guard.js +81 -0
- package/dist/tools/desktop/desktop-guard.js.map +1 -0
- package/dist/tools/desktop/desktop.tool.js +201 -0
- package/dist/tools/desktop/desktop.tool.js.map +1 -0
- package/dist/tools/desktop/feihong-win.js +163 -0
- package/dist/tools/desktop/feihong-win.js.map +1 -0
- package/dist/tools/desktop/index.js +37 -0
- package/dist/tools/desktop/index.js.map +1 -0
- package/dist/tools/docker-sandbox.js +212 -0
- package/dist/tools/docker-sandbox.js.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcp/index.js +10 -2
- package/dist/tools/mcp/index.js.map +1 -1
- package/dist/tools/mcp/mcp-client.js +4 -0
- package/dist/tools/mcp/mcp-client.js.map +1 -1
- package/dist/tools/sandbox.js +28 -0
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/web/public/favicon.svg +11 -0
- package/dist/web/public/index.html +4 -1
- package/dist/web/public/public/css/style.css +1756 -0
- package/dist/web/public/public/favicon.svg +11 -0
- package/dist/web/public/public/index.html +1246 -0
- package/dist/web/public/public/js/api.js +558 -0
- package/dist/web/public/public/js/app.js +2233 -0
- package/dist/web/public/public/js/mock-api.js +259 -0
- package/dist/web/public/public/js/monaco-editor.js +363 -0
- package/dist/web/public/public/js/ui.js +2217 -0
- package/dist/web/public/public/js/utils.js +214 -0
- package/dist/web/public/public/manifest.json +59 -0
- package/dist/web/public/public/robots.txt +14 -0
- package/dist/web/public/public/service-worker.js +149 -0
- package/dist/web/public/robots.txt +14 -0
- package/dist/web/server.js +70 -0
- package/dist/web/server.js.map +1 -1
- package/docs/AI/345/221/230/345/267/245/345/206/233/345/233/242-/346/225/264/345/220/210/350/257/264/346/230/216.md +68 -0
- package/docs/API.md +827 -0
- package/docs/App/346/212/200/346/234/257/350/257/264/346/230/216/344/271/246.md +3 -3
- package/docs/P1.1-P3-P5/345/267/245/347/250/213/345/256/236/346/226/275/346/200/273/347/273/223.md +328 -0
- package/docs/P5-Pi/345/257/271/347/205/247/350/257/204/346/265/213/346/212/245/345/221/212-mock/346/250/241/345/274/217.json +125 -0
- package/docs/P5-Pi/345/257/271/347/205/247/350/257/204/346/265/213/346/212/245/345/221/212-/347/234/237/345/256/236/346/250/241/345/236/213.json +138 -0
- package/docs/P5-pi-compare-real-report.json +138 -0
- package/docs/P5-pi-compare-report.json +125 -0
- package/docs/PROJECT-ANALYSIS-AND-TEST.md +721 -0
- package/docs/Pi-Agent/346/216/245/345/205/245/351/243/236/350/231/271Code-MVP/351/233/206/346/210/220/344/272/244/344/273/230/347/211/251.md +355 -0
- package/docs/Pi-Agent/346/216/245/345/205/245/351/243/236/350/231/271Code/344/273/267/345/200/274/345/210/206/346/236/220-/345/274/200/345/217/221/346/226/207/346/241/243.md +291 -0
- package/docs/Pi-Agent/346/216/245/345/205/245/351/243/236/350/231/271Code/344/273/267/345/200/274/351/207/215/344/274/260-/345/217/257/350/247/206/345/214/226.html +84 -0
- package/docs/SWE-bench-300-agnes-2.5-flash-/346/234/200/347/273/210/346/212/245/345/221/212.json +2012 -0
- package/docs/SWE-bench-300-agnes-2.5-flash-/350/267/221/345/210/206/346/212/245/345/221/212.md +74 -0
- package/docs/SWE-bench-Lite-DeepSeek-V4-Flash-/350/267/221/345/210/206/346/212/245/345/221/212.md +102 -0
- package/docs/TECHNICAL-SPECIFICATION.md +812 -0
- package/docs/TECHNICAL-SPECIFICATION.pdf +0 -0
- package/docs/UPGRADE-v7.9.0.md +291 -0
- package/docs/UPGRADE-v8.0.0.md +237 -0
- package/docs/Windows/346/211/213/350/204/232-POC/346/274/224/347/244/272/350/204/232/346/234/254.md +131 -0
- package/docs/Windows/346/211/213/350/204/232/346/216/245/345/205/245/346/214/207/345/215/227.md +181 -0
- package/docs//344/275/277/347/224/250/350/257/264/346/230/216/344/271/246-v8.0.0.md +922 -0
- package/docs//344/275/277/347/224/250/350/257/264/346/230/216/344/271/246-v8.0.1.md +146 -0
- package/package.json +7 -6
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.agentsTools = exports.feihongAgentsSubmitTool = exports.feihongAgentsListTool = void 0;
|
|
4
|
+
exports.resolveLlmEnv = resolveLlmEnv;
|
|
5
|
+
/**
|
|
6
|
+
* 飞虹 Code (对标 Muse Code · 自研内核)
|
|
7
|
+
* 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
|
|
8
|
+
*
|
|
9
|
+
* AI 员工军团桥接层(agent-team · feihongzhi_agents 整合)
|
|
10
|
+
*
|
|
11
|
+
* 把 Python 实现的「AI 员工军团」CLI(main.py:submit/list-agents/stats/run-once…)
|
|
12
|
+
* 封装为飞虹原生工具,并接入飞虹模型路由:
|
|
13
|
+
* - 从 loadConfig().models.providers 取第一个 openai-compatible(带 apiKey)provider
|
|
14
|
+
* - 映射为 DOUBAO_API_KEY / DOUBAO_MODEL / DOUBAO_BASE_URL + LLM_PROVIDER=doubao
|
|
15
|
+
* (agent-team 的 LLM 适配器兼容 OpenAI 接口,火山方舟/OpenAI 兼容端点均可)
|
|
16
|
+
* - 无可用 provider 时回退 LLM_PROVIDER=mock(本地确定性,跑通全链路)
|
|
17
|
+
*
|
|
18
|
+
* 安全:apiKey 只作为子进程环境变量传递,不回显、不落盘、不进审计摘要。
|
|
19
|
+
*/
|
|
20
|
+
const child_process_1 = require("child_process");
|
|
21
|
+
const fs_1 = require("fs");
|
|
22
|
+
const path_1 = require("path");
|
|
23
|
+
const zod_1 = require("zod");
|
|
24
|
+
const config_1 = require("../../shared/config");
|
|
25
|
+
const logger_1 = require("../../shared/logger");
|
|
26
|
+
/** agent-team 目录:FEIHONG_AGENT_TEAM_DIR 覆盖,缺省 <仓库根>/agent-team */
|
|
27
|
+
function resolveAgentTeamDir() {
|
|
28
|
+
const env = process.env.FEIHONG_AGENT_TEAM_DIR;
|
|
29
|
+
if (env?.trim())
|
|
30
|
+
return (0, path_1.resolve)(env);
|
|
31
|
+
return (0, path_1.resolve)(process.cwd(), 'agent-team');
|
|
32
|
+
}
|
|
33
|
+
/** Python 解释器:FEIHONG_PYTHON 覆盖,缺省 python */
|
|
34
|
+
function resolvePython() {
|
|
35
|
+
return process.env.FEIHONG_PYTHON || 'python';
|
|
36
|
+
}
|
|
37
|
+
/** 从飞虹模型路由取 LLM 环境变量(只取 key 名,不取 key 值回显) */
|
|
38
|
+
function resolveLlmEnv() {
|
|
39
|
+
try {
|
|
40
|
+
const cfg = (0, config_1.loadConfig)();
|
|
41
|
+
const provider = cfg.models.providers.find((p) => p.type === 'openai-compatible' && p.apiKey && p.baseURL);
|
|
42
|
+
if (provider) {
|
|
43
|
+
return {
|
|
44
|
+
LLM_PROVIDER: 'doubao',
|
|
45
|
+
DOUBAO_API_KEY: provider.apiKey ?? '',
|
|
46
|
+
DOUBAO_MODEL: provider.model ?? 'doubao-seed-1-6-250615',
|
|
47
|
+
DOUBAO_BASE_URL: provider.baseURL,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
logger_1.logger.warn('读取模型路由失败,回退 mock LLM', { error: e instanceof Error ? e.message : String(e) });
|
|
53
|
+
}
|
|
54
|
+
return { LLM_PROVIDER: 'mock' };
|
|
55
|
+
}
|
|
56
|
+
/** 执行 agent-team CLI(同步,输出 JSON 文本);首次调用先静默 init-db(幂等) */
|
|
57
|
+
function runCli(args, _ctx, envExtra = {}) {
|
|
58
|
+
const teamDir = resolveAgentTeamDir();
|
|
59
|
+
if (!(0, fs_1.existsSync)((0, path_1.join)(teamDir, 'main.py'))) {
|
|
60
|
+
return { ok: false, output: '', error: `agent-team 未就位(缺 ${teamDir}/main.py)` };
|
|
61
|
+
}
|
|
62
|
+
const env = { ...resolveLlmEnv(), ...envExtra };
|
|
63
|
+
const py = resolvePython();
|
|
64
|
+
// init-db 幂等(CREATE TABLE IF NOT EXISTS),保证 stats/submit 可查 DB
|
|
65
|
+
(0, child_process_1.spawnSync)(py, ['main.py', 'init-db'], { cwd: teamDir, env: { ...process.env, ...env }, encoding: 'utf8', timeout: 60000 });
|
|
66
|
+
const r = (0, child_process_1.spawnSync)(py, ['main.py', ...args], {
|
|
67
|
+
cwd: teamDir,
|
|
68
|
+
env: { ...process.env, ...env },
|
|
69
|
+
encoding: 'utf8',
|
|
70
|
+
timeout: 180000,
|
|
71
|
+
});
|
|
72
|
+
if (r.error) {
|
|
73
|
+
return { ok: false, output: '', error: `agent-team 启动失败: ${r.error.message}` };
|
|
74
|
+
}
|
|
75
|
+
if (r.status !== 0) {
|
|
76
|
+
return { ok: false, output: '', error: (r.stderr || r.stdout || '').slice(0, 500) };
|
|
77
|
+
}
|
|
78
|
+
return { ok: true, output: r.stdout || '' };
|
|
79
|
+
}
|
|
80
|
+
/* ================= feihong_agents_list(只读) ================= */
|
|
81
|
+
const listSchema = zod_1.z.object({
|
|
82
|
+
/** 可选子命令:agents=员工清单(默认)/ stats=任务统计 */
|
|
83
|
+
scope: zod_1.z.enum(['agents', 'stats']).optional(),
|
|
84
|
+
});
|
|
85
|
+
exports.feihongAgentsListTool = {
|
|
86
|
+
name: 'feihong_agents_list',
|
|
87
|
+
description: '查询 AI 员工军团:员工清单(17 个 AI 员工,按 L1-L5 分层)或任务统计。只读,不改状态。',
|
|
88
|
+
jsonSchema: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
scope: { type: 'string', enum: ['agents', 'stats'], description: 'agents=员工清单(默认)| stats=任务统计' },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
schema: listSchema,
|
|
95
|
+
async execute(args, ctx) {
|
|
96
|
+
const { scope = 'agents' } = listSchema.parse(args);
|
|
97
|
+
const r = runCli([scope === 'stats' ? 'stats' : 'list-agents'], ctx);
|
|
98
|
+
return r.ok ? { ok: true, output: r.output } : { ok: false, output: '', error: r.error };
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
/* ================= feihong_agents_submit(写 · 需审批) ================= */
|
|
102
|
+
const submitSchema = zod_1.z.object({
|
|
103
|
+
/** 员工编号(1-17,对应 17 个 AI 员工;查清单用 feihong_agents_list) */
|
|
104
|
+
agentId: zod_1.z.union([zod_1.z.number(), zod_1.z.string()]),
|
|
105
|
+
/** 任务入参(JSON 字符串,字段见对应技能 SKILL.md) */
|
|
106
|
+
input: zod_1.z.string().min(1),
|
|
107
|
+
/** 是否立即执行一轮(默认 true;false 只入队待审批后执行) */
|
|
108
|
+
executeNow: zod_1.z.boolean().optional(),
|
|
109
|
+
});
|
|
110
|
+
exports.feihongAgentsSubmitTool = {
|
|
111
|
+
name: 'feihong_agents_submit',
|
|
112
|
+
description: '向 AI 员工军团提交任务(需审批):指定员工编号(1-17)与 JSON 入参。提交后自动执行一轮(LLM 用飞虹模型路由,未配置时 mock)。',
|
|
113
|
+
jsonSchema: {
|
|
114
|
+
type: 'object',
|
|
115
|
+
properties: {
|
|
116
|
+
agentId: { type: ['number', 'string'], description: '员工编号 1-17' },
|
|
117
|
+
input: { type: 'string', description: '任务入参 JSON 字符串(字段见对应技能 SKILL.md)' },
|
|
118
|
+
executeNow: { type: 'boolean', description: '是否立即执行(默认 true)' },
|
|
119
|
+
},
|
|
120
|
+
required: ['agentId', 'input'],
|
|
121
|
+
},
|
|
122
|
+
schema: submitSchema,
|
|
123
|
+
async execute(args, ctx) {
|
|
124
|
+
const { agentId, input, executeNow = true } = submitSchema.parse(args);
|
|
125
|
+
// module_id 为两位编号(01-17):兼容 1/"1"/"01" 输入
|
|
126
|
+
const moduleId = String(agentId).padStart(2, '0');
|
|
127
|
+
const submit = runCli(['submit', '--module', moduleId, '--input', input], ctx);
|
|
128
|
+
if (!submit.ok)
|
|
129
|
+
return { ok: false, output: '', error: submit.error };
|
|
130
|
+
const out = [submit.output];
|
|
131
|
+
if (executeNow) {
|
|
132
|
+
const once = runCli(['run-once'], ctx);
|
|
133
|
+
if (once.ok) {
|
|
134
|
+
out.push('--- 执行结果 ---', once.output);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
out.push('--- 执行失败 ---', once.error ?? '');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return { ok: true, output: out.join('\n') };
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
exports.agentsTools = [exports.feihongAgentsListTool, exports.feihongAgentsSubmitTool];
|
|
144
|
+
//# sourceMappingURL=agents-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-bridge.js","sourceRoot":"","sources":["../../../src/tools/agents/agents-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_BLOCKED_WINDOWS = exports.ALLOWED_ACTIONS = void 0;
|
|
4
|
+
exports.resolveBlockedWindows = resolveBlockedWindows;
|
|
5
|
+
exports.checkDesktopGuard = checkDesktopGuard;
|
|
6
|
+
exports.ALLOWED_ACTIONS = [
|
|
7
|
+
'type',
|
|
8
|
+
'click',
|
|
9
|
+
'mouse_click',
|
|
10
|
+
'drag',
|
|
11
|
+
'scroll',
|
|
12
|
+
'terminal_send',
|
|
13
|
+
'launch',
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* 危险窗口黑名单(子串匹配,不区分大小写)。
|
|
17
|
+
* 命中即拒绝——这些窗口一旦被 AI 操作,后果不可逆或涉及系统/凭据安全。
|
|
18
|
+
* 用户可通过环境变量 FEIHONG_DESKTOP_BLOCK_WINDOWS(逗号分隔)追加。
|
|
19
|
+
*/
|
|
20
|
+
exports.DEFAULT_BLOCKED_WINDOWS = [
|
|
21
|
+
'任务管理器',
|
|
22
|
+
'task manager',
|
|
23
|
+
'注册表编辑器',
|
|
24
|
+
'registry editor',
|
|
25
|
+
'用户账户控制',
|
|
26
|
+
'user account control',
|
|
27
|
+
'windows 安全中心',
|
|
28
|
+
'windows security',
|
|
29
|
+
'系统配置',
|
|
30
|
+
'system configuration',
|
|
31
|
+
'设备管理器',
|
|
32
|
+
'device manager',
|
|
33
|
+
'磁盘管理',
|
|
34
|
+
'disk management',
|
|
35
|
+
'本地安全策略',
|
|
36
|
+
'本地组策略',
|
|
37
|
+
];
|
|
38
|
+
/** 合并默认黑名单 + 用户扩展(FEIHONG_DESKTOP_BLOCK_WINDOWS) */
|
|
39
|
+
function resolveBlockedWindows(extra) {
|
|
40
|
+
const list = [...exports.DEFAULT_BLOCKED_WINDOWS];
|
|
41
|
+
if (extra?.trim()) {
|
|
42
|
+
for (const w of extra.split(',')) {
|
|
43
|
+
const s = w.trim().toLowerCase();
|
|
44
|
+
if (s)
|
|
45
|
+
list.push(s);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return list;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 停手线判定:返回 blocked 时,理由写入拒绝信息(模型可见,用于自我纠错)。
|
|
52
|
+
*/
|
|
53
|
+
function checkDesktopGuard(input, blockedWindows = exports.DEFAULT_BLOCKED_WINDOWS) {
|
|
54
|
+
const action = input.action ?? '';
|
|
55
|
+
const title = (input.windowTitle ?? '').trim();
|
|
56
|
+
// 1) 动作白名单
|
|
57
|
+
if (!exports.ALLOWED_ACTIONS.includes(action)) {
|
|
58
|
+
return {
|
|
59
|
+
blocked: true,
|
|
60
|
+
reason: `停手线:动作 "${action || '(空)'}" 不在白名单(${exports.ALLOWED_ACTIONS.join('/')})`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// 2) 目标窗口必填(launch 无窗口,豁免)
|
|
64
|
+
if (action !== 'launch' && !title) {
|
|
65
|
+
return {
|
|
66
|
+
blocked: true,
|
|
67
|
+
reason: '停手线:写操作必须显式指定 windowTitle(防误操作到无关窗口)',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// 3) 危险窗口黑名单
|
|
71
|
+
if (title) {
|
|
72
|
+
const t = title.toLowerCase();
|
|
73
|
+
for (const bad of blockedWindows) {
|
|
74
|
+
if (t.includes(bad.toLowerCase())) {
|
|
75
|
+
return { blocked: true, reason: `停手线:目标窗口 "${title}" 命中危险窗口黑名单(${bad})` };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { blocked: false };
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=desktop-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop-guard.js","sourceRoot":"","sources":["../../../src/tools/desktop/desktop-guard.ts"],"names":[],"mappings":";;;AA4DA,sDASC;AAUD,8CAkCC;AAxFY,QAAA,eAAe,GAAoB;IAC9C,MAAM;IACN,OAAO;IACP,aAAa;IACb,MAAM;IACN,QAAQ;IACR,eAAe;IACf,QAAQ;CACT,CAAC;AAEF;;;;GAIG;AACU,QAAA,uBAAuB,GAAa;IAC/C,OAAO;IACP,cAAc;IACd,QAAQ;IACR,iBAAiB;IACjB,QAAQ;IACR,sBAAsB;IACtB,cAAc;IACd,kBAAkB;IAClB,MAAM;IACN,sBAAsB;IACtB,OAAO;IACP,gBAAgB;IAChB,MAAM;IACN,iBAAiB;IACjB,QAAQ;IACR,OAAO;CACR,CAAC;AAEF,oDAAoD;AACpD,SAAgB,qBAAqB,CAAC,KAAc;IAClD,MAAM,IAAI,GAAG,CAAC,GAAG,+BAAuB,CAAC,CAAC;IAC1C,IAAI,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACjC,IAAI,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAOD;;GAEG;AACH,SAAgB,iBAAiB,CAC/B,KAAsB,EACtB,iBAA2B,+BAAuB;IAElD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAE/C,WAAW;IACX,IAAI,CAAC,uBAAe,CAAC,QAAQ,CAAC,MAAuB,CAAC,EAAE,CAAC;QACvD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,WAAW,MAAM,IAAI,KAAK,WAAW,uBAAe,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG;SAC1E,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QAClC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,sCAAsC;SAC/C,CAAC;IACJ,CAAC;IAED,aAAa;IACb,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAC9B,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;gBAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,KAAK,eAAe,GAAG,GAAG,EAAE,CAAC;YAC5E,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.feihongDesktopTools = exports.feihongDesktopVerifyTool = exports.feihongDesktopActTool = exports.feihongDesktopSeeTool = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* 飞虹 Code (对标 Muse Code · 自研内核)
|
|
6
|
+
* 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
|
|
7
|
+
*
|
|
8
|
+
* C 层 · feihong-desktop 原生工具(模型可见的强类型入口)
|
|
9
|
+
*
|
|
10
|
+
* 三个工具,对应「看 → 动 → 验」闭环:
|
|
11
|
+
* feihong_desktop_see 只读:桌面状态勘察(焦点/窗口/光标)
|
|
12
|
+
* feihong_desktop_act 写:标准动作序列(guard → focus → act → 取证)
|
|
13
|
+
* feihong_desktop_verify 只读:截图+状态回读,验证动作是否生效
|
|
14
|
+
*
|
|
15
|
+
* 与 MCP 直通工具(desktop_*)的区别:
|
|
16
|
+
* - zod 强类型参数(不再是 z.record 宽松透传)
|
|
17
|
+
* - 内置停手线 + 强制取证(MCP 直通没有)
|
|
18
|
+
* - 语义化动作名(type/click/launch…),模型心智负担更低
|
|
19
|
+
*/
|
|
20
|
+
const zod_1 = require("zod");
|
|
21
|
+
const feihong_win_1 = require("./feihong-win");
|
|
22
|
+
const desktop_guard_1 = require("./desktop-guard");
|
|
23
|
+
/** 从 ToolContext 取 runId(构造取证目录用) */
|
|
24
|
+
function runIdOf(ctx) {
|
|
25
|
+
return typeof ctx.runId === 'string' ? ctx.runId : String(ctx.runId ?? 'session');
|
|
26
|
+
}
|
|
27
|
+
/* ================= feihong_desktop_see(只读勘察) ================= */
|
|
28
|
+
const seeSchema = zod_1.z.object({
|
|
29
|
+
/** 可选:按窗口标题/进程名过滤可见窗口(子串匹配) */
|
|
30
|
+
filter: zod_1.z.string().optional(),
|
|
31
|
+
});
|
|
32
|
+
exports.feihongDesktopSeeTool = {
|
|
33
|
+
name: 'feihong_desktop_see',
|
|
34
|
+
description: '只读勘察当前 Windows 桌面:焦点窗口、可见窗口、光标位置。不改变任何状态。',
|
|
35
|
+
jsonSchema: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
filter: { type: 'string', description: '可选:按窗口标题/进程名过滤(子串匹配)' },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
schema: seeSchema,
|
|
42
|
+
async execute(args, ctx) {
|
|
43
|
+
const client = ctx._desktopClient;
|
|
44
|
+
if (!client) {
|
|
45
|
+
return { ok: false, output: '', error: 'feihong-desktop 未挂载(当前会话无 desktop MCP)' };
|
|
46
|
+
}
|
|
47
|
+
const { filter } = seeSchema.parse(args);
|
|
48
|
+
try {
|
|
49
|
+
const state = await client.callTool('desktop_state', {});
|
|
50
|
+
if (!state.ok)
|
|
51
|
+
return { ok: false, output: '', error: `desktop_state 失败: ${state.error ?? state.output}` };
|
|
52
|
+
let out = state.output;
|
|
53
|
+
if (filter) {
|
|
54
|
+
try {
|
|
55
|
+
const parsed = JSON.parse(state.output);
|
|
56
|
+
const hits = (parsed.visibleWindows ?? []).filter((w) => (w.title ?? '').toLowerCase().includes(filter.toLowerCase()) ||
|
|
57
|
+
(w.processName ?? '').toLowerCase().includes(filter.toLowerCase()));
|
|
58
|
+
out = JSON.stringify({ ...parsed, visibleWindows: hits, filteredBy: filter });
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// 服务器返回非 JSON 时不强行解析,原样返回
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { ok: true, output: out };
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
return { ok: false, output: '', error: e instanceof Error ? e.message : String(e) };
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
/* ================= feihong_desktop_act(写 · 标准动作序列) ================= */
|
|
72
|
+
const actSchema = zod_1.z.object({
|
|
73
|
+
/** 目标窗口标题(type/click/mouse_click/drag/scroll/terminal_send 必填;launch 豁免) */
|
|
74
|
+
windowTitle: zod_1.z.string().optional(),
|
|
75
|
+
/** 动作类型 */
|
|
76
|
+
action: zod_1.z.enum(desktop_guard_1.ALLOWED_ACTIONS),
|
|
77
|
+
/** type/terminal_send 的文本内容 */
|
|
78
|
+
text: zod_1.z.string().optional(),
|
|
79
|
+
/** click 的 UIA 元素名/automationId */
|
|
80
|
+
element: zod_1.z.string().optional(),
|
|
81
|
+
/** mouse_click / drag 起点坐标 */
|
|
82
|
+
x: zod_1.z.number().optional(),
|
|
83
|
+
y: zod_1.z.number().optional(),
|
|
84
|
+
/** drag 终点坐标 */
|
|
85
|
+
endX: zod_1.z.number().optional(),
|
|
86
|
+
endY: zod_1.z.number().optional(),
|
|
87
|
+
/** scroll 增量 */
|
|
88
|
+
deltaX: zod_1.z.number().optional(),
|
|
89
|
+
deltaY: zod_1.z.number().optional(),
|
|
90
|
+
/** launch 的应用命令 */
|
|
91
|
+
command: zod_1.z.string().optional(),
|
|
92
|
+
/** launch 等待窗口出现毫秒数(默认 5000) */
|
|
93
|
+
waitMs: zod_1.z.number().optional(),
|
|
94
|
+
});
|
|
95
|
+
exports.feihongDesktopActTool = {
|
|
96
|
+
name: 'feihong_desktop_act',
|
|
97
|
+
description: '对 Windows 桌面执行动作(需审批):type 键盘输入 / click UIA 点击 / mouse_click 坐标点击 / drag 拖拽 / scroll 滚动 / terminal_send 终端命令 / launch 启动应用。自动执行:停手线检查 → 聚焦目标窗口 → 动作 → 截图取证。',
|
|
98
|
+
jsonSchema: {
|
|
99
|
+
type: 'object',
|
|
100
|
+
properties: {
|
|
101
|
+
windowTitle: { type: 'string', description: '目标窗口标题(写操作必填)' },
|
|
102
|
+
action: { type: 'string', enum: desktop_guard_1.ALLOWED_ACTIONS, description: '动作类型' },
|
|
103
|
+
text: { type: 'string', description: 'type/terminal_send 的文本' },
|
|
104
|
+
element: { type: 'string', description: 'click 的 UIA 元素名' },
|
|
105
|
+
x: { type: 'number', description: 'mouse_click/drag 起点 x' },
|
|
106
|
+
y: { type: 'number', description: 'mouse_click/drag 起点 y' },
|
|
107
|
+
endX: { type: 'number', description: 'drag 终点 x' },
|
|
108
|
+
endY: { type: 'number', description: 'drag 终点 y' },
|
|
109
|
+
deltaX: { type: 'number', description: 'scroll 水平增量' },
|
|
110
|
+
deltaY: { type: 'number', description: 'scroll 垂直增量(负=向上)' },
|
|
111
|
+
command: { type: 'string', description: 'launch 的应用命令' },
|
|
112
|
+
waitMs: { type: 'number', description: 'launch 等待毫秒数' },
|
|
113
|
+
},
|
|
114
|
+
required: ['action'],
|
|
115
|
+
},
|
|
116
|
+
schema: actSchema,
|
|
117
|
+
async execute(args, ctx) {
|
|
118
|
+
const client = ctx._desktopClient;
|
|
119
|
+
if (!client) {
|
|
120
|
+
return { ok: false, output: '', error: 'feihong-desktop 未挂载(当前会话无 desktop MCP)' };
|
|
121
|
+
}
|
|
122
|
+
const p = actSchema.parse(args);
|
|
123
|
+
const forensics = new feihong_win_1.ForensicsLogger((0, feihong_win_1.resolveForensicsDir)(runIdOf(ctx)), client);
|
|
124
|
+
const r = await (0, feihong_win_1.feihongDesktopAct)(client, forensics, p);
|
|
125
|
+
if (!r.ok) {
|
|
126
|
+
return { ok: false, output: '', error: r.error, ...(r.forensicsPath ? { output: `取证: ${r.forensicsPath}` } : {}) };
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
ok: true,
|
|
130
|
+
output: `${r.output}\n[取证] ${r.forensicsPath ?? ''}\n[提示] 若需确认效果,调用 feihong_desktop_verify`,
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
/* ================= feihong_desktop_verify(只读回读验证) ================= */
|
|
135
|
+
const verifySchema = zod_1.z.object({
|
|
136
|
+
/** 期望出现的文本(在截图 OCR / 状态输出中匹配,子串) */
|
|
137
|
+
expectText: zod_1.z.string().optional(),
|
|
138
|
+
/** 期望处于焦点的窗口标题(子串) */
|
|
139
|
+
expectWindow: zod_1.z.string().optional(),
|
|
140
|
+
});
|
|
141
|
+
exports.feihongDesktopVerifyTool = {
|
|
142
|
+
name: 'feihong_desktop_verify',
|
|
143
|
+
description: '只读回读验证:截图 + 桌面状态,检查动作是否生效(期望文本是否出现/期望窗口是否聚焦)。',
|
|
144
|
+
jsonSchema: {
|
|
145
|
+
type: 'object',
|
|
146
|
+
properties: {
|
|
147
|
+
expectText: { type: 'string', description: '期望出现的文本(子串匹配)' },
|
|
148
|
+
expectWindow: { type: 'string', description: '期望聚焦的窗口标题(子串)' },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
schema: verifySchema,
|
|
152
|
+
async execute(args, ctx) {
|
|
153
|
+
const client = ctx._desktopClient;
|
|
154
|
+
if (!client) {
|
|
155
|
+
return { ok: false, output: '', error: 'feihong-desktop 未挂载(当前会话无 desktop MCP)' };
|
|
156
|
+
}
|
|
157
|
+
const { expectText, expectWindow } = verifySchema.parse(args);
|
|
158
|
+
try {
|
|
159
|
+
const [shot, state] = await Promise.all([
|
|
160
|
+
client.callTool('screenshot', {}),
|
|
161
|
+
client.callTool('desktop_state', {}),
|
|
162
|
+
]);
|
|
163
|
+
const checks = [];
|
|
164
|
+
let passed = true;
|
|
165
|
+
if (expectWindow) {
|
|
166
|
+
try {
|
|
167
|
+
const st = JSON.parse(state.output);
|
|
168
|
+
const focused = st.focusedWindow?.title ?? '';
|
|
169
|
+
const hit = focused.toLowerCase().includes(expectWindow.toLowerCase());
|
|
170
|
+
checks.push(`窗口焦点: ${hit ? '命中' : '未命中'}(当前焦点: ${focused || '(无)'})`);
|
|
171
|
+
if (!hit)
|
|
172
|
+
passed = false;
|
|
173
|
+
}
|
|
174
|
+
catch { /* 解析失败跳过该项 */ }
|
|
175
|
+
}
|
|
176
|
+
if (expectText) {
|
|
177
|
+
const ocrText = (shot.output ?? '') + (state.output ?? '');
|
|
178
|
+
const hit = ocrText.includes(expectText);
|
|
179
|
+
checks.push(`文本匹配: ${hit ? '命中' : '未命中'}(在截图/状态输出中检索 "${expectText}")`);
|
|
180
|
+
if (!hit)
|
|
181
|
+
passed = false;
|
|
182
|
+
}
|
|
183
|
+
if (checks.length === 0) {
|
|
184
|
+
checks.push('未提供期望条件,仅返回截图与状态(请用 expectText/expectWindow 做断言)');
|
|
185
|
+
}
|
|
186
|
+
return {
|
|
187
|
+
ok: true,
|
|
188
|
+
output: `验证${passed ? '通过' : '未通过'}:\n- ${checks.join('\n- ')}\n--- 状态 ---\n${state.output.slice(0, 400)}\n--- 截图返回 ---\n${shot.output.slice(0, 200)}`,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
return { ok: false, output: '', error: e instanceof Error ? e.message : String(e) };
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
exports.feihongDesktopTools = [
|
|
197
|
+
exports.feihongDesktopSeeTool,
|
|
198
|
+
exports.feihongDesktopActTool,
|
|
199
|
+
exports.feihongDesktopVerifyTool,
|
|
200
|
+
];
|
|
201
|
+
//# sourceMappingURL=desktop.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.tool.js","sourceRoot":"","sources":["../../../src/tools/desktop/desktop.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ForensicsLogger = void 0;
|
|
4
|
+
exports.resolveForensicsDir = resolveForensicsDir;
|
|
5
|
+
exports.feihongDesktopAct = feihongDesktopAct;
|
|
6
|
+
exports.forensicsDirExists = forensicsDirExists;
|
|
7
|
+
exports.touchFile = touchFile;
|
|
8
|
+
/**
|
|
9
|
+
* 飞虹 Code (对标 Muse Code · 自研内核)
|
|
10
|
+
* 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
|
|
11
|
+
*
|
|
12
|
+
* C 层 · feihong-win 内化核心(Windows 手脚标准动作序列)
|
|
13
|
+
*
|
|
14
|
+
* 把 desktop-touch-mcp 的零散 MCP 调用固化成一条纪律化流水线:
|
|
15
|
+
* probe(可选)→ guard(停手线)→ focus(验证目标窗口)→ act(执行动作)
|
|
16
|
+
* → verify(截图回读)→ forensics(取证落盘)
|
|
17
|
+
*
|
|
18
|
+
* 设计要点:
|
|
19
|
+
* - 复用主流程 attachMcpTools 创建的 McpClient(不重复 spawn 进程)
|
|
20
|
+
* - 取证目录:FH_HOME/forensics/<runId>/manifest.jsonl + shots/,与审计链同源
|
|
21
|
+
* - 每次写操作后强制截图取证,保证「操作留痕、可复盘、可甩锅」
|
|
22
|
+
*/
|
|
23
|
+
const fs_1 = require("fs");
|
|
24
|
+
const path_1 = require("path");
|
|
25
|
+
const os_1 = require("os");
|
|
26
|
+
const desktop_guard_1 = require("./desktop-guard");
|
|
27
|
+
/** 取证目录解析:FH_FORENSICS_DIR 覆盖,缺省 FH_HOME/forensics */
|
|
28
|
+
function resolveForensicsDir(runId) {
|
|
29
|
+
const base = process.env.FH_FORENSICS_DIR || (0, path_1.join)((0, os_1.homedir)(), '.feihong-code', 'forensics');
|
|
30
|
+
const dir = (0, path_1.join)(base, runId.replace(/[^a-zA-Z0-9_-]/g, '_'));
|
|
31
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
32
|
+
(0, fs_1.mkdirSync)((0, path_1.join)(dir, 'shots'), { recursive: true });
|
|
33
|
+
return dir;
|
|
34
|
+
}
|
|
35
|
+
/** 取证记录器:JSONL manifest + 截图目录 */
|
|
36
|
+
class ForensicsLogger {
|
|
37
|
+
dir;
|
|
38
|
+
client;
|
|
39
|
+
constructor(dir, client) {
|
|
40
|
+
this.dir = dir;
|
|
41
|
+
this.client = client;
|
|
42
|
+
}
|
|
43
|
+
/** 追加一条动作记录(工具/入参摘要/结果摘要/时间) */
|
|
44
|
+
record(entry) {
|
|
45
|
+
try {
|
|
46
|
+
(0, fs_1.appendFileSync)((0, path_1.join)(this.dir, 'manifest.jsonl'), JSON.stringify({ ts: new Date().toISOString(), ...entry }) + '\n', 'utf8');
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
// 取证写入失败不阻断主流程,但把错误带进返回(调用方可见)
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.warn('[forensics] manifest 写入失败:', e instanceof Error ? e.message : String(e));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** 执行后强制截图取证:截图返回全文记入 manifest;desktop-touch 磁盘缓存保留原图 */
|
|
55
|
+
async snapshot(note) {
|
|
56
|
+
const res = await this.client.callTool('screenshot', {});
|
|
57
|
+
this.record({ event: 'snapshot', note, screenshotOutput: res.output?.slice(0, 500) || '' });
|
|
58
|
+
return res;
|
|
59
|
+
}
|
|
60
|
+
get manifestPath() {
|
|
61
|
+
return (0, path_1.join)(this.dir, 'manifest.jsonl');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.ForensicsLogger = ForensicsLogger;
|
|
65
|
+
/** 动作 → desktop-touch MCP 工具调用映射(入参对齐已实测的工具 schema) */
|
|
66
|
+
function mapAction(p) {
|
|
67
|
+
switch (p.action) {
|
|
68
|
+
// type 用 '@active':feihong 层已 focus 目标窗口(停手线校验过标题),
|
|
69
|
+
// keyboard 直接瞄准当前前台窗口,规避「标题中英文差异导致 AutoGuard 拦截」。
|
|
70
|
+
case 'type':
|
|
71
|
+
return { tool: 'keyboard', args: { action: 'type', text: p.text ?? '', windowTitle: '@active' } };
|
|
72
|
+
case 'click':
|
|
73
|
+
return { tool: 'click_element', args: { name: p.element ?? '', windowTitle: p.windowTitle } };
|
|
74
|
+
case 'mouse_click':
|
|
75
|
+
return { tool: 'mouse_click', args: { x: p.x ?? 0, y: p.y ?? 0, windowTitle: p.windowTitle } };
|
|
76
|
+
case 'drag':
|
|
77
|
+
return {
|
|
78
|
+
tool: 'mouse_drag',
|
|
79
|
+
args: { startX: p.x ?? 0, startY: p.y ?? 0, endX: p.endX ?? 0, endY: p.endY ?? 0, windowTitle: p.windowTitle },
|
|
80
|
+
};
|
|
81
|
+
case 'scroll':
|
|
82
|
+
return { tool: 'scroll', args: { deltaX: p.deltaX ?? 0, deltaY: p.deltaY ?? -100, windowTitle: p.windowTitle } };
|
|
83
|
+
case 'terminal_send':
|
|
84
|
+
return { tool: 'terminal', args: { action: 'send', text: p.text ?? '', windowTitle: p.windowTitle } };
|
|
85
|
+
case 'launch':
|
|
86
|
+
return { tool: 'workspace_launch', args: { command: p.command ?? '', waitMs: p.waitMs ?? 5000 } };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* MCP 结果语义判定:desktop-touch 的感知守卫/错误码会以"正常返回"携带错误文本,
|
|
91
|
+
* 仅看 MCP 层 ok 会漏判。命中错误码 → 视为失败,并保留原始输出供模型复盘。
|
|
92
|
+
*/
|
|
93
|
+
const DESKTOP_ERROR_CODES = [
|
|
94
|
+
'AutoGuardBlocked',
|
|
95
|
+
'GuardFailed',
|
|
96
|
+
'DestinationRequired',
|
|
97
|
+
'ElementDisabled',
|
|
98
|
+
'InvokePatternNotSupported',
|
|
99
|
+
'WindowNotFound',
|
|
100
|
+
'FocusFailed',
|
|
101
|
+
];
|
|
102
|
+
function isDesktopError(output) {
|
|
103
|
+
for (const code of DESKTOP_ERROR_CODES) {
|
|
104
|
+
if (output.includes(code))
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 标准动作序列:guard → focus(launch 豁免)→ act → 取证截图
|
|
111
|
+
* 返回结构化结果:动作输出 + 取证 manifest 路径 + 截图回读
|
|
112
|
+
*/
|
|
113
|
+
async function feihongDesktopAct(client, forensics, params) {
|
|
114
|
+
// 1) 停手线(硬编码,任何角色不可绕过)
|
|
115
|
+
const guard = (0, desktop_guard_1.checkDesktopGuard)({ windowTitle: params.windowTitle, action: params.action });
|
|
116
|
+
if (guard.blocked) {
|
|
117
|
+
forensics.record({ event: 'act_blocked', action: params.action, windowTitle: params.windowTitle, reason: guard.reason });
|
|
118
|
+
return { ok: false, output: '', error: guard.reason, forensicsPath: forensics.manifestPath };
|
|
119
|
+
}
|
|
120
|
+
// 2) 聚焦目标窗口(launch 无既有窗口,豁免)
|
|
121
|
+
if (params.action !== 'launch' && params.windowTitle) {
|
|
122
|
+
const f = await client.callTool('focus_window', { title: params.windowTitle });
|
|
123
|
+
if (!f.ok) {
|
|
124
|
+
forensics.record({ event: 'focus_failed', windowTitle: params.windowTitle, error: f.error });
|
|
125
|
+
return { ok: false, output: '', error: `聚焦窗口失败: ${f.error ?? f.output}`, forensicsPath: forensics.manifestPath };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// 3) 执行动作
|
|
129
|
+
const { tool, args } = mapAction(params);
|
|
130
|
+
const res = await client.callTool(tool, args);
|
|
131
|
+
// 3.5) 结果语义判定:MCP 层 ok 但输出携带感知守卫错误码 → 视为失败
|
|
132
|
+
const semanticallyFailed = res.ok && isDesktopError(res.output ?? '');
|
|
133
|
+
// 4) 取证截图(无论成败都截图——失败现场同样可复盘)
|
|
134
|
+
const shot = await forensics.snapshot(`${params.action}@${params.windowTitle ?? params.command ?? ''}`);
|
|
135
|
+
forensics.record({
|
|
136
|
+
event: 'act',
|
|
137
|
+
action: params.action,
|
|
138
|
+
windowTitle: params.windowTitle,
|
|
139
|
+
command: params.command,
|
|
140
|
+
tool,
|
|
141
|
+
args: JSON.stringify(args).slice(0, 300),
|
|
142
|
+
resultOk: res.ok,
|
|
143
|
+
result: res.output?.slice(0, 300) || res.error || '',
|
|
144
|
+
shotOk: shot.ok,
|
|
145
|
+
});
|
|
146
|
+
if (!res.ok || semanticallyFailed) {
|
|
147
|
+
const errText = res.error ?? res.output ?? '';
|
|
148
|
+
const hint = semanticallyFailed
|
|
149
|
+
? '(desktop-touch 感知守卫拦截,请根据输出中的 suggest 调整后重试)'
|
|
150
|
+
: '';
|
|
151
|
+
return { ok: false, output: '', error: `${errText.slice(0, 400)}${hint}`, forensicsPath: forensics.manifestPath };
|
|
152
|
+
}
|
|
153
|
+
return { ok: true, output: res.output, forensicsPath: forensics.manifestPath };
|
|
154
|
+
}
|
|
155
|
+
/** 目录是否已存在(测试辅助) */
|
|
156
|
+
function forensicsDirExists(dir) {
|
|
157
|
+
return (0, fs_1.existsSync)((0, path_1.join)(dir, 'manifest.jsonl')) || (0, fs_1.existsSync)(dir);
|
|
158
|
+
}
|
|
159
|
+
/** 写一个空占位文件(测试辅助,正常流程由 resolveForensicsDir 创建) */
|
|
160
|
+
function touchFile(p) {
|
|
161
|
+
(0, fs_1.writeFileSync)(p, '', 'utf8');
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=feihong-win.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feihong-win.js","sourceRoot":"","sources":["../../../src/tools/desktop/feihong-win.ts"],"names":[],"mappings":"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"}
|