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.
Files changed (146) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +36 -22
  2. package/.github/ISSUE_TEMPLATE/config.yml +10 -13
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +38 -13
  4. package/.github/PULL_REQUEST_TEMPLATE.md +65 -30
  5. package/.github/workflows/ci.yml +2 -2
  6. package/.github/workflows/release.yml +5 -5
  7. package/.github/workflows/swebench-real.yml +2 -2
  8. package/CONTRIBUTING.md +52 -3
  9. package/README.md +656 -636
  10. package/agent-team/.env.example +13 -0
  11. package/agent-team/README.md +42 -0
  12. package/agent-team/agents/__init__.py +0 -0
  13. package/agent-team/agents/l1_acquisition.py +207 -0
  14. package/agent-team/agents/l2_content.py +237 -0
  15. package/agent-team/agents/l3_conversion.py +148 -0
  16. package/agent-team/agents/l4_analysis.py +118 -0
  17. package/agent-team/agents/l5_management.py +52 -0
  18. package/agent-team/agents/registry.py +60 -0
  19. package/agent-team/config.py +39 -0
  20. package/agent-team/core/__init__.py +0 -0
  21. package/agent-team/core/agent.py +73 -0
  22. package/agent-team/core/models.py +347 -0
  23. package/agent-team/core/scheduler.py +150 -0
  24. package/agent-team/core/task.py +121 -0
  25. package/agent-team/feihongzhi.db +0 -0
  26. package/agent-team/llm/__init__.py +12 -0
  27. package/agent-team/llm/base.py +22 -0
  28. package/agent-team/llm/doubao_llm.py +52 -0
  29. package/agent-team/llm/mock_llm.py +42 -0
  30. package/agent-team/main.py +235 -0
  31. package/agent-team/requirements.txt +2 -0
  32. package/agent-team/skill_packager.py +248 -0
  33. 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
  34. 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
  35. 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
  36. 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
  37. 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
  38. 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
  39. 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
  40. 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
  41. 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
  42. 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
  43. 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
  44. 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
  45. 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
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. 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
  58. 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
  59. 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
  60. 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
  61. 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
  62. 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
  63. 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
  64. 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
  65. 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
  66. 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
  67. package/agent-team/tests/__init__.py +0 -0
  68. package/agent-team/tests/test_core.py +156 -0
  69. package/dist/agent/agent-session.js +103 -0
  70. package/dist/agent/agent-session.js.map +1 -0
  71. package/dist/agent/orchestrator.js +8 -0
  72. package/dist/agent/orchestrator.js.map +1 -1
  73. package/dist/agent/steer.js +52 -0
  74. package/dist/agent/steer.js.map +1 -0
  75. package/dist/cli/run.js +2 -0
  76. package/dist/cli/run.js.map +1 -1
  77. package/dist/cli/version.js +1 -1
  78. package/dist/enterprise/policy.js +40 -17
  79. package/dist/enterprise/policy.js.map +1 -1
  80. package/dist/memory/honcho-store.js +231 -0
  81. package/dist/memory/honcho-store.js.map +1 -0
  82. package/dist/shared/log-rotator.js +238 -0
  83. package/dist/shared/log-rotator.js.map +1 -0
  84. package/dist/shared/sqlite-store.js +512 -0
  85. package/dist/shared/sqlite-store.js.map +1 -0
  86. package/dist/tools/agents/agents-bridge.js +144 -0
  87. package/dist/tools/agents/agents-bridge.js.map +1 -0
  88. package/dist/tools/desktop/desktop-guard.js +81 -0
  89. package/dist/tools/desktop/desktop-guard.js.map +1 -0
  90. package/dist/tools/desktop/desktop.tool.js +201 -0
  91. package/dist/tools/desktop/desktop.tool.js.map +1 -0
  92. package/dist/tools/desktop/feihong-win.js +163 -0
  93. package/dist/tools/desktop/feihong-win.js.map +1 -0
  94. package/dist/tools/desktop/index.js +37 -0
  95. package/dist/tools/desktop/index.js.map +1 -0
  96. package/dist/tools/docker-sandbox.js +212 -0
  97. package/dist/tools/docker-sandbox.js.map +1 -0
  98. package/dist/tools/index.js +2 -0
  99. package/dist/tools/index.js.map +1 -1
  100. package/dist/tools/mcp/index.js +10 -2
  101. package/dist/tools/mcp/index.js.map +1 -1
  102. package/dist/tools/mcp/mcp-client.js +4 -0
  103. package/dist/tools/mcp/mcp-client.js.map +1 -1
  104. package/dist/tools/sandbox.js +28 -0
  105. package/dist/tools/sandbox.js.map +1 -1
  106. package/dist/web/public/favicon.svg +11 -0
  107. package/dist/web/public/index.html +4 -1
  108. package/dist/web/public/public/css/style.css +1756 -0
  109. package/dist/web/public/public/favicon.svg +11 -0
  110. package/dist/web/public/public/index.html +1246 -0
  111. package/dist/web/public/public/js/api.js +558 -0
  112. package/dist/web/public/public/js/app.js +2233 -0
  113. package/dist/web/public/public/js/mock-api.js +259 -0
  114. package/dist/web/public/public/js/monaco-editor.js +363 -0
  115. package/dist/web/public/public/js/ui.js +2217 -0
  116. package/dist/web/public/public/js/utils.js +214 -0
  117. package/dist/web/public/public/manifest.json +59 -0
  118. package/dist/web/public/public/robots.txt +14 -0
  119. package/dist/web/public/public/service-worker.js +149 -0
  120. package/dist/web/public/robots.txt +14 -0
  121. package/dist/web/server.js +70 -0
  122. package/dist/web/server.js.map +1 -1
  123. 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
  124. package/docs/API.md +827 -0
  125. package/docs/App/346/212/200/346/234/257/350/257/264/346/230/216/344/271/246.md +3 -3
  126. 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
  127. 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
  128. 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
  129. package/docs/P5-pi-compare-real-report.json +138 -0
  130. package/docs/P5-pi-compare-report.json +125 -0
  131. package/docs/PROJECT-ANALYSIS-AND-TEST.md +721 -0
  132. 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
  133. 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
  134. 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
  135. package/docs/SWE-bench-300-agnes-2.5-flash-/346/234/200/347/273/210/346/212/245/345/221/212.json +2012 -0
  136. package/docs/SWE-bench-300-agnes-2.5-flash-/350/267/221/345/210/206/346/212/245/345/221/212.md +74 -0
  137. package/docs/SWE-bench-Lite-DeepSeek-V4-Flash-/350/267/221/345/210/206/346/212/245/345/221/212.md +102 -0
  138. package/docs/TECHNICAL-SPECIFICATION.md +812 -0
  139. package/docs/TECHNICAL-SPECIFICATION.pdf +0 -0
  140. package/docs/UPGRADE-v7.9.0.md +291 -0
  141. package/docs/UPGRADE-v8.0.0.md +237 -0
  142. 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
  143. package/docs/Windows/346/211/213/350/204/232/346/216/245/345/205/245/346/214/207/345/215/227.md +181 -0
  144. package/docs//344/275/277/347/224/250/350/257/264/346/230/216/344/271/246-v8.0.0.md +922 -0
  145. package/docs//344/275/277/347/224/250/350/257/264/346/230/216/344/271/246-v8.0.1.md +146 -0
  146. 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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"}