@zhin.js/agent 0.0.17 → 0.0.19

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 (61) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +14 -8
  3. package/lib/builtin-tools.d.ts +5 -137
  4. package/lib/builtin-tools.d.ts.map +1 -1
  5. package/lib/builtin-tools.js +321 -732
  6. package/lib/builtin-tools.js.map +1 -1
  7. package/lib/discover-agents.d.ts +28 -0
  8. package/lib/discover-agents.d.ts.map +1 -0
  9. package/lib/discover-agents.js +116 -0
  10. package/lib/discover-agents.js.map +1 -0
  11. package/lib/discover-skills.d.ts +49 -0
  12. package/lib/discover-skills.d.ts.map +1 -0
  13. package/lib/discover-skills.js +297 -0
  14. package/lib/discover-skills.js.map +1 -0
  15. package/lib/discover-tools.d.ts +56 -0
  16. package/lib/discover-tools.d.ts.map +1 -0
  17. package/lib/discover-tools.js +263 -0
  18. package/lib/discover-tools.js.map +1 -0
  19. package/lib/discovery-utils.d.ts +27 -0
  20. package/lib/discovery-utils.d.ts.map +1 -0
  21. package/lib/discovery-utils.js +96 -0
  22. package/lib/discovery-utils.js.map +1 -0
  23. package/lib/file-policy.d.ts +41 -4
  24. package/lib/file-policy.d.ts.map +1 -1
  25. package/lib/file-policy.js +126 -4
  26. package/lib/file-policy.js.map +1 -1
  27. package/lib/index.d.ts +1 -1
  28. package/lib/index.d.ts.map +1 -1
  29. package/lib/index.js +1 -1
  30. package/lib/index.js.map +1 -1
  31. package/lib/init/create-zhin-agent.d.ts.map +1 -1
  32. package/lib/init/create-zhin-agent.js +3 -1
  33. package/lib/init/create-zhin-agent.js.map +1 -1
  34. package/lib/init/register-builtin-tools.d.ts.map +1 -1
  35. package/lib/init/register-builtin-tools.js +51 -54
  36. package/lib/init/register-builtin-tools.js.map +1 -1
  37. package/lib/zhin-agent/config.js +1 -1
  38. package/lib/zhin-agent/config.js.map +1 -1
  39. package/lib/zhin-agent/exec-policy.d.ts +48 -2
  40. package/lib/zhin-agent/exec-policy.d.ts.map +1 -1
  41. package/lib/zhin-agent/exec-policy.js +184 -23
  42. package/lib/zhin-agent/exec-policy.js.map +1 -1
  43. package/lib/zhin-agent/prompt.d.ts +14 -0
  44. package/lib/zhin-agent/prompt.d.ts.map +1 -1
  45. package/lib/zhin-agent/prompt.js +192 -45
  46. package/lib/zhin-agent/prompt.js.map +1 -1
  47. package/package.json +3 -3
  48. package/src/builtin-tools.ts +333 -835
  49. package/src/discover-agents.ts +138 -0
  50. package/src/discover-skills.ts +325 -0
  51. package/src/discover-tools.ts +302 -0
  52. package/src/discovery-utils.ts +96 -0
  53. package/src/file-policy.ts +152 -4
  54. package/src/index.ts +5 -1
  55. package/src/init/create-zhin-agent.ts +3 -1
  56. package/src/init/register-builtin-tools.ts +51 -62
  57. package/src/zhin-agent/config.ts +1 -1
  58. package/src/zhin-agent/exec-policy.ts +229 -24
  59. package/src/zhin-agent/prompt.ts +209 -47
  60. package/tests/exec-policy.test.ts +355 -0
  61. package/tests/file-policy.test.ts +189 -1
@@ -0,0 +1,297 @@
1
+ /**
2
+ * 技能发现(SKILL.md 文件扫描与加载)
3
+ *
4
+ * 加载顺序:Workspace(cwd/skills)> Local(~/.zhin/skills)> data/skills > 已加载插件包 skills/
5
+ * 同名先发现者优先,支持平台/依赖兼容性过滤
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import { exec } from 'child_process';
10
+ import { promisify } from 'util';
11
+ import { Logger } from '@zhin.js/core';
12
+ import { getSkillSearchDirectories, getDataDir } from './discovery-utils.js';
13
+ const execAsync = promisify(exec);
14
+ const logger = new Logger(null, 'builtin-tools');
15
+ // ============================================================================
16
+ // 发现
17
+ // ============================================================================
18
+ /**
19
+ * 扫描技能目录,发现 SKILL.md 技能文件
20
+ * @param root 根插件(可选):用于追加插件包内 `skills/` 扫描,与 `activate_skill` 查找路径一致
21
+ */
22
+ export async function discoverWorkspaceSkills(root) {
23
+ const skills = [];
24
+ const seenNames = new Set();
25
+ const dataDir = getDataDir();
26
+ const skillDirs = getSkillSearchDirectories(root ?? undefined);
27
+ // 确保 data/skills 目录存在
28
+ const defaultSkillDir = path.join(dataDir, 'skills');
29
+ if (!fs.existsSync(defaultSkillDir)) {
30
+ fs.mkdirSync(defaultSkillDir, { recursive: true });
31
+ logger.debug(`Created skill directory: ${defaultSkillDir}`);
32
+ }
33
+ for (const skillsDir of skillDirs) {
34
+ if (!fs.existsSync(skillsDir))
35
+ continue;
36
+ let entries;
37
+ try {
38
+ entries = await fs.promises.readdir(skillsDir, { withFileTypes: true });
39
+ }
40
+ catch {
41
+ continue;
42
+ }
43
+ for (const entry of entries) {
44
+ if (!entry.isDirectory())
45
+ continue;
46
+ const skillMdPath = path.join(skillsDir, entry.name, 'SKILL.md');
47
+ if (!fs.existsSync(skillMdPath))
48
+ continue;
49
+ try {
50
+ const content = await fs.promises.readFile(skillMdPath, 'utf-8');
51
+ const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*(?:\n|$)/);
52
+ if (!match) {
53
+ logger.debug(`Skill文件 ${skillMdPath} 没有有效的frontmatter格式`);
54
+ continue;
55
+ }
56
+ let jsYaml;
57
+ try {
58
+ jsYaml = await import('js-yaml');
59
+ if (jsYaml.default)
60
+ jsYaml = jsYaml.default;
61
+ }
62
+ catch (e) {
63
+ logger.warn(`Unable to import js-yaml module: ${e}`);
64
+ continue;
65
+ }
66
+ const metadata = jsYaml.load(match[1]);
67
+ if (!metadata || !metadata.name || !metadata.description) {
68
+ logger.debug(`Skill文件 ${skillMdPath} 缺少必需的 name/description 字段`);
69
+ continue;
70
+ }
71
+ // 平台兼容检查
72
+ const compat = metadata.compatibility || {};
73
+ if (compat.os && Array.isArray(compat.os)) {
74
+ const currentOs = process.platform === 'darwin' ? 'darwin' : process.platform === 'win32' ? 'windows' : 'linux';
75
+ if (!compat.os.includes(currentOs)) {
76
+ logger.debug(`Skipping skill '${metadata.name}' (unsupported OS)`);
77
+ continue;
78
+ }
79
+ }
80
+ // 依赖检查
81
+ const requiresBins = metadata.requires?.bins || compat.deps || metadata.deps || [];
82
+ const requiresEnv = metadata.requires?.env || [];
83
+ const binsToCheck = Array.isArray(requiresBins) ? requiresBins : [];
84
+ const envToCheck = Array.isArray(requiresEnv) ? requiresEnv : [];
85
+ const requiresMissing = [];
86
+ for (const bin of binsToCheck) {
87
+ try {
88
+ await execAsync(`which ${bin} 2>/dev/null`);
89
+ }
90
+ catch {
91
+ requiresMissing.push(`CLI: ${bin}`);
92
+ }
93
+ }
94
+ for (const envKey of envToCheck) {
95
+ if (!process.env[envKey]) {
96
+ requiresMissing.push(`ENV: ${envKey}`);
97
+ }
98
+ }
99
+ const available = requiresMissing.length === 0;
100
+ if (seenNames.has(metadata.name)) {
101
+ logger.debug(`Skill '${metadata.name}' 已由先序目录加载,跳过: ${skillMdPath}`);
102
+ continue;
103
+ }
104
+ seenNames.add(metadata.name);
105
+ skills.push({
106
+ name: metadata.name,
107
+ description: metadata.description,
108
+ keywords: metadata.keywords || [],
109
+ tags: [...(metadata.tags || []), 'workspace-skill'],
110
+ toolNames: Array.isArray(metadata.tools) ? metadata.tools : [],
111
+ filePath: skillMdPath,
112
+ always: Boolean(metadata.always),
113
+ available,
114
+ requiresMissing: requiresMissing.length > 0 ? requiresMissing : undefined,
115
+ });
116
+ logger.debug(`Skill发现成功: ${metadata.name}, tools: ${JSON.stringify(metadata.tools || [])}`);
117
+ }
118
+ catch (e) {
119
+ logger.warn(`Failed to parse SKILL.md in ${skillMdPath}:`, e);
120
+ }
121
+ }
122
+ }
123
+ return skills;
124
+ }
125
+ // ============================================================================
126
+ // 辅助函数
127
+ // ============================================================================
128
+ /**
129
+ * 获取 frontmatter 中 always: true 的技能名列表(用于常驻注入 system prompt)
130
+ */
131
+ export function getAlwaysSkillNames(skills) {
132
+ return skills.filter(s => s.always && s.available).map(s => s.name);
133
+ }
134
+ function stripFrontmatter(content) {
135
+ const match = content.match(/^---\s*\n[\s\S]*?\n---\s*(?:\n|$)/);
136
+ if (match)
137
+ return content.slice(match[0].length).trim();
138
+ return content.trim();
139
+ }
140
+ /**
141
+ * 加载 always 技能的正文内容并拼接为「Active Skills」段
142
+ */
143
+ export async function loadAlwaysSkillsContent(skills) {
144
+ const always = skills.filter(s => s.always && s.available);
145
+ if (always.length === 0)
146
+ return '';
147
+ const parts = [];
148
+ for (const s of always) {
149
+ try {
150
+ const content = await fs.promises.readFile(s.filePath, 'utf-8');
151
+ const body = stripFrontmatter(content);
152
+ parts.push(`### Skill: ${s.name}\n\n${body}`);
153
+ }
154
+ catch (e) {
155
+ logger.warn(`Failed to load always skill ${s.name}: ${e.message}`);
156
+ }
157
+ }
158
+ return parts.join('\n\n---\n\n');
159
+ }
160
+ function escapeXml(s) {
161
+ return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
162
+ }
163
+ /**
164
+ * 构建技能列表的 XML 摘要,供 model 区分可用/不可用及缺失依赖
165
+ */
166
+ export function buildSkillsSummaryXML(skills) {
167
+ if (skills.length === 0)
168
+ return '';
169
+ const lines = ['<skills>'];
170
+ for (const s of skills) {
171
+ const available = s.available !== false;
172
+ lines.push(` <skill available="${available}">`);
173
+ lines.push(` <name>${escapeXml(s.name)}</name>`);
174
+ lines.push(` <description>${escapeXml(s.description)}</description>`);
175
+ lines.push(` <location>${escapeXml(s.filePath)}</location>`);
176
+ if (!available && s.requiresMissing && s.requiresMissing.length > 0) {
177
+ lines.push(` <requires>${escapeXml(s.requiresMissing.join(', '))}</requires>`);
178
+ }
179
+ lines.push(' </skill>');
180
+ }
181
+ lines.push('</skills>');
182
+ return lines.join('\n');
183
+ }
184
+ // ============================================================================
185
+ // 技能内容解析(activate_skill 使用)
186
+ // ============================================================================
187
+ /**
188
+ * 检查技能声明的依赖是否在环境中可用;若有缺失返回提示文案,否则返回空字符串
189
+ */
190
+ export async function checkSkillDeps(content) {
191
+ const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
192
+ if (!fmMatch)
193
+ return '';
194
+ let jsYaml;
195
+ try {
196
+ jsYaml = await import('js-yaml');
197
+ if (jsYaml.default)
198
+ jsYaml = jsYaml.default;
199
+ }
200
+ catch {
201
+ return '';
202
+ }
203
+ const metadata = jsYaml.load(fmMatch[1]);
204
+ if (!metadata)
205
+ return '';
206
+ const compat = metadata.compatibility || {};
207
+ const deps = compat.deps || metadata.deps;
208
+ if (!deps || !Array.isArray(deps))
209
+ return '';
210
+ const missing = [];
211
+ for (const dep of deps) {
212
+ try {
213
+ await execAsync(`which ${dep} 2>/dev/null`);
214
+ }
215
+ catch {
216
+ missing.push(dep);
217
+ }
218
+ }
219
+ if (missing.length === 0)
220
+ return '';
221
+ return `⚠️ 当前环境缺少以下依赖,请先安装后再使用本技能:${missing.join(', ')}`;
222
+ }
223
+ /**
224
+ * 从 SKILL.md 全文中提取精简的执行指令
225
+ * 只保留 frontmatter(工具列表)和执行规则,去掉示例、测试场景等冗余内容
226
+ */
227
+ export function extractSkillInstructions(name, content, maxBodyLen = 4000) {
228
+ const lines = [];
229
+ lines.push(`Skill '${name}' activated. 请立即根据以下指导执行工具调用:`);
230
+ lines.push('');
231
+ const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---/);
232
+ if (fmMatch) {
233
+ const fmContent = fmMatch[1];
234
+ const toolsMatch = fmContent.match(/tools:\s*\n((?:\s+-\s+.+\n?)+)/);
235
+ if (toolsMatch) {
236
+ lines.push('## 可用工具');
237
+ lines.push(toolsMatch[0].trim());
238
+ lines.push('');
239
+ }
240
+ }
241
+ const bodyAfterFm = fmMatch && fmMatch.index !== undefined
242
+ ? content.slice(fmMatch.index + fmMatch[0].length).replace(/^\s+/, '')
243
+ : content;
244
+ // Priority: "## 快速操作" / "## Quick Actions" summary for small models
245
+ const quickActionsMatch = bodyAfterFm.match(/## (?:快速操作|Quick\s*Actions)[\s\S]*?(?=\n## [^\s]|$)/i);
246
+ if (quickActionsMatch && maxBodyLen <= 2000) {
247
+ lines.push(quickActionsMatch[0].trim());
248
+ lines.push('');
249
+ lines.push('## 立即行动');
250
+ lines.push('根据上面的指导,立即调用工具完成用户请求。禁止重复调用 activate_skill,禁止用文本描述代替实际工具调用。');
251
+ return lines.join('\n');
252
+ }
253
+ const rulesMatch = content.match(/## 执行规则[\s\S]*?(?=\n## [^\s]|$)/);
254
+ const workflowMatch = content.match(/## (?:Workflow|Instructions|使用说明)[\s\S]*?(?=\n## [^\s]|$)/);
255
+ if (rulesMatch) {
256
+ lines.push(rulesMatch[0].trim());
257
+ lines.push('');
258
+ }
259
+ else if (workflowMatch) {
260
+ lines.push(workflowMatch[0].trim());
261
+ lines.push('');
262
+ }
263
+ else if (bodyAfterFm.trim()) {
264
+ const firstH2 = bodyAfterFm.match(/\n## [^\s]/);
265
+ const intro = firstH2 ? bodyAfterFm.slice(0, firstH2.index).trim() : bodyAfterFm.trim();
266
+ const quickStartMatch = bodyAfterFm.match(/## (?:快速开始|Quick\s*Start|Getting\s*Started)[\s\S]*?(?=\n## [^\s]|$)/i);
267
+ const authMatch = bodyAfterFm.match(/## (?:认证|Authentication|Auth)[\s\S]*?(?=\n## [^\s]|$)/i);
268
+ if (quickStartMatch || (intro.length < 200 && bodyAfterFm.length > intro.length)) {
269
+ lines.push('## 指导');
270
+ lines.push(intro);
271
+ lines.push('');
272
+ const extra = [];
273
+ if (quickStartMatch)
274
+ extra.push(quickStartMatch[0].trim());
275
+ if (authMatch)
276
+ extra.push(authMatch[0].trim());
277
+ if (extra.length > 0) {
278
+ const joined = extra.join('\n\n');
279
+ lines.push(joined.length > maxBodyLen ? joined.slice(0, maxBodyLen) + '\n...(truncated)' : joined);
280
+ }
281
+ else {
282
+ const rest = bodyAfterFm.slice(intro.length).trim();
283
+ lines.push(rest.length > maxBodyLen ? rest.slice(0, maxBodyLen) + '\n...(truncated)' : rest);
284
+ }
285
+ lines.push('');
286
+ }
287
+ else if (intro) {
288
+ lines.push('## 指导');
289
+ lines.push(intro);
290
+ lines.push('');
291
+ }
292
+ }
293
+ lines.push('## 立即行动');
294
+ lines.push('根据上面的指导,立即调用工具完成用户请求。禁止重复调用 activate_skill,禁止用文本描述代替实际工具调用。');
295
+ return lines.join('\n');
296
+ }
297
+ //# sourceMappingURL=discover-skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover-skills.js","sourceRoot":"","sources":["../src/discover-skills.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * 文件化 Tool 发现(*.tool.md 文件扫描与构建)
3
+ *
4
+ * 加载顺序与 skills/agents 一致:Workspace > ~/.zhin > data > 插件包
5
+ * 同名先发现者优先
6
+ */
7
+ import { type Plugin } from '@zhin.js/core';
8
+ export interface ToolParamShorthand {
9
+ type: string;
10
+ description?: string;
11
+ required?: boolean;
12
+ enum?: string[];
13
+ default?: any;
14
+ }
15
+ export interface ToolMeta {
16
+ name: string;
17
+ description: string;
18
+ /** 简写参数定义(frontmatter 格式) */
19
+ parameters?: Record<string, ToolParamShorthand>;
20
+ /** 命令配置 */
21
+ command?: {
22
+ pattern?: string;
23
+ alias?: string[];
24
+ examples?: string[];
25
+ };
26
+ platforms?: string[];
27
+ scopes?: string[];
28
+ permissionLevel?: string;
29
+ tags?: string[];
30
+ keywords?: string[];
31
+ kind?: string;
32
+ hidden?: boolean;
33
+ /** handler 文件路径(相对于 .tool.md) */
34
+ handler?: string;
35
+ /** *.tool.md 文件的绝对路径 */
36
+ filePath: string;
37
+ /** body 内容(无 handler 时作为 prompt 模板) */
38
+ templateBody?: string;
39
+ }
40
+ /**
41
+ * 从根插件树收集:根插件与直接子插件包目录下的 `tools/`
42
+ */
43
+ export declare function collectPluginToolSearchRoots(root: Plugin | null | undefined): string[];
44
+ /**
45
+ * 获取所有 tool 搜索目录(标准目录 + 插件包 tools/)
46
+ */
47
+ export declare function getToolSearchDirectories(root?: Plugin | null): string[];
48
+ /**
49
+ * 扫描 tools/ 目录,发现 *.tool.md 文件
50
+ */
51
+ export declare function discoverWorkspaceTools(root?: Plugin | null): Promise<ToolMeta[]>;
52
+ /**
53
+ * 将 ToolMeta 转换为 Tool 对象(包含 execute 函数)
54
+ */
55
+ export declare function buildToolFromMeta(meta: ToolMeta): Promise<import('@zhin.js/core').Tool | null>;
56
+ //# sourceMappingURL=discover-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover-tools.d.ts","sourceRoot":"","sources":["../src/discover-tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAU,KAAK,MAAM,EAA6B,MAAM,eAAe,CAAC;AAS/E,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAChD,WAAW;IACX,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAMD;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,CAgBtF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAUvE;AAMD;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CA+EtF;AAmFD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,eAAe,EAAE,IAAI,GAAG,IAAI,CAAC,CAmCpG"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * 文件化 Tool 发现(*.tool.md 文件扫描与构建)
3
+ *
4
+ * 加载顺序与 skills/agents 一致:Workspace > ~/.zhin > data > 插件包
5
+ * 同名先发现者优先
6
+ */
7
+ import * as fs from 'fs';
8
+ import * as os from 'os';
9
+ import * as path from 'path';
10
+ import { spawn } from 'child_process';
11
+ import { Logger } from '@zhin.js/core';
12
+ import { getDataDir } from './discovery-utils.js';
13
+ const logger = new Logger(null, 'builtin-tools');
14
+ // ============================================================================
15
+ // 目录收集
16
+ // ============================================================================
17
+ /**
18
+ * 从根插件树收集:根插件与直接子插件包目录下的 `tools/`
19
+ */
20
+ export function collectPluginToolSearchRoots(root) {
21
+ if (!root)
22
+ return [];
23
+ const dirs = [];
24
+ const push = (d) => { if (d && !dirs.includes(d))
25
+ dirs.push(d); };
26
+ const fromPlugin = (p) => {
27
+ if (!p?.filePath)
28
+ return;
29
+ const dir = path.dirname(p.filePath);
30
+ push(path.join(dir, 'tools'));
31
+ const dirName = path.basename(dir);
32
+ if (dirName === 'src' || dirName === 'lib') {
33
+ push(path.join(path.dirname(dir), 'tools'));
34
+ }
35
+ };
36
+ fromPlugin(root);
37
+ for (const child of root.children || [])
38
+ fromPlugin(child);
39
+ return dirs;
40
+ }
41
+ /**
42
+ * 获取所有 tool 搜索目录(标准目录 + 插件包 tools/)
43
+ */
44
+ export function getToolSearchDirectories(root) {
45
+ const list = [
46
+ path.join(process.cwd(), 'tools'),
47
+ path.join(os.homedir(), '.zhin', 'tools'),
48
+ path.join(getDataDir(), 'tools'),
49
+ ];
50
+ for (const d of collectPluginToolSearchRoots(root ?? undefined)) {
51
+ if (!list.includes(d))
52
+ list.push(d);
53
+ }
54
+ return list;
55
+ }
56
+ // ============================================================================
57
+ // 发现
58
+ // ============================================================================
59
+ /**
60
+ * 扫描 tools/ 目录,发现 *.tool.md 文件
61
+ */
62
+ export async function discoverWorkspaceTools(root) {
63
+ const tools = [];
64
+ const seenNames = new Set();
65
+ const toolDirs = getToolSearchDirectories(root);
66
+ for (const toolsDir of toolDirs) {
67
+ if (!fs.existsSync(toolsDir))
68
+ continue;
69
+ let entries;
70
+ try {
71
+ entries = await fs.promises.readdir(toolsDir, { withFileTypes: true });
72
+ }
73
+ catch {
74
+ continue;
75
+ }
76
+ for (const entry of entries) {
77
+ let toolMdPath;
78
+ if (entry.isFile() && entry.name.endsWith('.tool.md')) {
79
+ toolMdPath = path.join(toolsDir, entry.name);
80
+ }
81
+ else if (entry.isDirectory()) {
82
+ const nested = path.join(toolsDir, entry.name, `${entry.name}.tool.md`);
83
+ if (fs.existsSync(nested))
84
+ toolMdPath = nested;
85
+ }
86
+ if (!toolMdPath)
87
+ continue;
88
+ try {
89
+ const content = await fs.promises.readFile(toolMdPath, 'utf-8');
90
+ const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*(?:\n|$)/);
91
+ if (!match) {
92
+ logger.debug(`Tool文件 ${toolMdPath} 没有有效的frontmatter格式`);
93
+ continue;
94
+ }
95
+ let jsYaml;
96
+ try {
97
+ jsYaml = await import('js-yaml');
98
+ if (jsYaml.default)
99
+ jsYaml = jsYaml.default;
100
+ }
101
+ catch (e) {
102
+ logger.warn(`Unable to import js-yaml module: ${e}`);
103
+ continue;
104
+ }
105
+ const metadata = jsYaml.load(match[1]);
106
+ if (!metadata || !metadata.name || !metadata.description) {
107
+ logger.debug(`Tool文件 ${toolMdPath} 缺少必需的 name/description 字段`);
108
+ continue;
109
+ }
110
+ if (seenNames.has(metadata.name)) {
111
+ logger.debug(`Tool '${metadata.name}' 已由先序目录加载,跳过: ${toolMdPath}`);
112
+ continue;
113
+ }
114
+ seenNames.add(metadata.name);
115
+ const body = content.replace(/^---\s*\n[\s\S]*?\n---\s*(?:\n|$)/, '').trim();
116
+ tools.push({
117
+ name: metadata.name,
118
+ description: metadata.description,
119
+ parameters: metadata.parameters || undefined,
120
+ command: metadata.command || undefined,
121
+ platforms: metadata.platforms,
122
+ scopes: metadata.scopes,
123
+ permissionLevel: metadata.permissionLevel,
124
+ tags: metadata.tags || [],
125
+ keywords: metadata.keywords || [],
126
+ kind: metadata.kind,
127
+ hidden: metadata.hidden,
128
+ handler: metadata.handler,
129
+ filePath: toolMdPath,
130
+ templateBody: !metadata.handler && body ? body : undefined,
131
+ });
132
+ logger.debug(`Tool发现成功: ${metadata.name}`);
133
+ }
134
+ catch (e) {
135
+ logger.warn(`Failed to parse tool.md in ${toolMdPath}:`, e);
136
+ }
137
+ }
138
+ }
139
+ return tools;
140
+ }
141
+ // ============================================================================
142
+ // 构建
143
+ // ============================================================================
144
+ function shorthandToSchema(params) {
145
+ const properties = {};
146
+ const required = [];
147
+ for (const [key, param] of Object.entries(params)) {
148
+ properties[key] = {
149
+ type: param.type || 'string',
150
+ description: param.description || key,
151
+ };
152
+ if (param.enum)
153
+ properties[key].enum = param.enum;
154
+ if (param.default !== undefined)
155
+ properties[key].default = param.default;
156
+ if (param.required)
157
+ required.push(key);
158
+ }
159
+ return { type: 'object', properties, required: required.length > 0 ? required : undefined };
160
+ }
161
+ async function loadToolHandler(handlerPath, toolMdPath) {
162
+ const resolved = path.resolve(path.dirname(toolMdPath), handlerPath);
163
+ if (!fs.existsSync(resolved)) {
164
+ logger.warn(`Tool handler 文件不存在: ${resolved}`);
165
+ return undefined;
166
+ }
167
+ const ext = path.extname(resolved).toLowerCase();
168
+ // Python script handler: spawn subprocess, pass args via JSON stdin, return stdout
169
+ if (ext === '.py') {
170
+ return async (args) => {
171
+ const input = JSON.stringify(args);
172
+ const pythonBin = process.env.PYTHON_BIN || 'python3';
173
+ try {
174
+ const result = await new Promise((resolve, reject) => {
175
+ const child = spawn(pythonBin, [resolved], {
176
+ stdio: ['pipe', 'pipe', 'pipe'],
177
+ timeout: 30_000,
178
+ });
179
+ let stdout = '';
180
+ let stderr = '';
181
+ child.stdout.on('data', (d) => { stdout += d.toString(); });
182
+ child.stderr.on('data', (d) => { stderr += d.toString(); });
183
+ child.on('close', (code) => {
184
+ if (stderr)
185
+ logger.debug(`[Python handler] ${resolved} stderr: ${stderr.trim()}`);
186
+ if (code !== 0)
187
+ reject(new Error(`Python exited with code ${code}: ${stderr.trim()}`));
188
+ else
189
+ resolve(stdout.trim());
190
+ });
191
+ child.on('error', reject);
192
+ child.stdin.write(input);
193
+ child.stdin.end();
194
+ });
195
+ return result;
196
+ }
197
+ catch (e) {
198
+ return `Error running Python handler: ${e.message ?? String(e)}`;
199
+ }
200
+ };
201
+ }
202
+ // JS/TS handler: ESM import
203
+ try {
204
+ const fileUrl = `file://${resolved}?t=${Date.now()}`;
205
+ const mod = await import(fileUrl);
206
+ const fn = mod.default || mod;
207
+ if (typeof fn !== 'function') {
208
+ logger.warn(`Tool handler 未导出函数: ${resolved}`);
209
+ return undefined;
210
+ }
211
+ return fn;
212
+ }
213
+ catch (e) {
214
+ logger.warn(`Tool handler 加载失败 (${resolved}): ${e instanceof Error ? e.message : String(e)}`);
215
+ return undefined;
216
+ }
217
+ }
218
+ function buildTemplateExecute(body) {
219
+ return (args) => body.replace(/\{\{(\w+)\}\}/g, (_, k) => {
220
+ const val = args[k];
221
+ return val !== undefined && val !== null ? String(val) : '';
222
+ });
223
+ }
224
+ /**
225
+ * 将 ToolMeta 转换为 Tool 对象(包含 execute 函数)
226
+ */
227
+ export async function buildToolFromMeta(meta) {
228
+ let execute;
229
+ if (meta.handler) {
230
+ execute = await loadToolHandler(meta.handler, meta.filePath);
231
+ if (!execute)
232
+ return null;
233
+ }
234
+ else if (meta.templateBody) {
235
+ execute = buildTemplateExecute(meta.templateBody);
236
+ }
237
+ else {
238
+ logger.warn(`Tool '${meta.name}' 既没有 handler 也没有模板 body,跳过`);
239
+ return null;
240
+ }
241
+ const parameters = meta.parameters
242
+ ? shorthandToSchema(meta.parameters)
243
+ : { type: 'object', properties: {} };
244
+ return {
245
+ name: meta.name,
246
+ description: meta.description,
247
+ parameters,
248
+ execute,
249
+ tags: meta.tags,
250
+ keywords: meta.keywords,
251
+ platforms: meta.platforms,
252
+ scopes: meta.scopes,
253
+ permissionLevel: meta.permissionLevel,
254
+ hidden: meta.hidden,
255
+ kind: meta.kind,
256
+ command: meta.command ? {
257
+ pattern: meta.command.pattern,
258
+ alias: meta.command.alias,
259
+ examples: meta.command.examples,
260
+ } : undefined,
261
+ };
262
+ }
263
+ //# sourceMappingURL=discover-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover-tools.js","sourceRoot":"","sources":["../src/discover-tools.ts"],"names":[],"mappings":"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"}