@eevee-ta/cli 0.1.0-beta.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 (70) hide show
  1. package/README.md +492 -0
  2. package/assets/skills/eevee-mcp/SKILL.md +127 -0
  3. package/assets/skills/eevee-mcp/reference.md +105 -0
  4. package/assets/skills/eevee-migration/SKILL.md +181 -0
  5. package/assets/skills/eevee-project-setup/SKILL.md +266 -0
  6. package/dist/src/bin/cli.js +237 -0
  7. package/dist/src/bin/cli.js.map +1 -0
  8. package/dist/src/commands/business-command.js +340 -0
  9. package/dist/src/commands/business-command.js.map +1 -0
  10. package/dist/src/commands/config-command.js +71 -0
  11. package/dist/src/commands/config-command.js.map +1 -0
  12. package/dist/src/commands/intl-command.js +131 -0
  13. package/dist/src/commands/intl-command.js.map +1 -0
  14. package/dist/src/commands/lint-command.js +105 -0
  15. package/dist/src/commands/lint-command.js.map +1 -0
  16. package/dist/src/commands/mcp-command.js +167 -0
  17. package/dist/src/commands/mcp-command.js.map +1 -0
  18. package/dist/src/commands/skill-command.js +116 -0
  19. package/dist/src/commands/skill-command.js.map +1 -0
  20. package/dist/src/lib/args.js +77 -0
  21. package/dist/src/lib/args.js.map +1 -0
  22. package/dist/src/lib/business-catalog.js +445 -0
  23. package/dist/src/lib/business-catalog.js.map +1 -0
  24. package/dist/src/lib/config.js +69 -0
  25. package/dist/src/lib/config.js.map +1 -0
  26. package/dist/src/lib/intl-catalog.js +58 -0
  27. package/dist/src/lib/intl-catalog.js.map +1 -0
  28. package/dist/src/lib/intl-config.js +125 -0
  29. package/dist/src/lib/intl-config.js.map +1 -0
  30. package/dist/src/lib/intl-downloader.js +217 -0
  31. package/dist/src/lib/intl-downloader.js.map +1 -0
  32. package/dist/src/lib/intl-serializers/csv.js +25 -0
  33. package/dist/src/lib/intl-serializers/csv.js.map +1 -0
  34. package/dist/src/lib/intl-serializers/custom.js +23 -0
  35. package/dist/src/lib/intl-serializers/custom.js.map +1 -0
  36. package/dist/src/lib/intl-serializers/index.js +22 -0
  37. package/dist/src/lib/intl-serializers/index.js.map +1 -0
  38. package/dist/src/lib/intl-serializers/js.js +10 -0
  39. package/dist/src/lib/intl-serializers/js.js.map +1 -0
  40. package/dist/src/lib/intl-serializers/json.js +7 -0
  41. package/dist/src/lib/intl-serializers/json.js.map +1 -0
  42. package/dist/src/lib/intl-serializers/properties.js +43 -0
  43. package/dist/src/lib/intl-serializers/properties.js.map +1 -0
  44. package/dist/src/lib/intl-serializers/ts.js +16 -0
  45. package/dist/src/lib/intl-serializers/ts.js.map +1 -0
  46. package/dist/src/lib/intl-serializers/xml.js +21 -0
  47. package/dist/src/lib/intl-serializers/xml.js.map +1 -0
  48. package/dist/src/lib/json.js +40 -0
  49. package/dist/src/lib/json.js.map +1 -0
  50. package/dist/src/lib/lint-config.js +180 -0
  51. package/dist/src/lib/lint-config.js.map +1 -0
  52. package/dist/src/lib/lint-java.js +226 -0
  53. package/dist/src/lib/lint-java.js.map +1 -0
  54. package/dist/src/lib/lint-types.js +2 -0
  55. package/dist/src/lib/lint-types.js.map +1 -0
  56. package/dist/src/lib/lint-web.js +183 -0
  57. package/dist/src/lib/lint-web.js.map +1 -0
  58. package/dist/src/lib/lint.js +192 -0
  59. package/dist/src/lib/lint.js.map +1 -0
  60. package/dist/src/lib/mcp-client.js +185 -0
  61. package/dist/src/lib/mcp-client.js.map +1 -0
  62. package/dist/src/lib/output.js +34 -0
  63. package/dist/src/lib/output.js.map +1 -0
  64. package/dist/src/lib/skill-installer.js +123 -0
  65. package/dist/src/lib/skill-installer.js.map +1 -0
  66. package/dist/src/lib/tool-docs.js +66 -0
  67. package/dist/src/lib/tool-docs.js.map +1 -0
  68. package/dist/src/lib/types.js +2 -0
  69. package/dist/src/lib/types.js.map +1 -0
  70. package/package.json +33 -0
@@ -0,0 +1,71 @@
1
+ import { CliError, hasFlag, optionCount, parseArgs, requireOption } from '../lib/args.js';
2
+ import { configPath, loadConfigFile, maskToken, resolveRuntimeConfig, saveConfigFile, } from '../lib/config.js';
3
+ const OPTION_SPECS = [
4
+ { long: 'url', value: true },
5
+ { long: 'token', value: true },
6
+ { long: 'reveal' },
7
+ ];
8
+ export async function runConfig(subcommand, argv) {
9
+ const parsed = parseArgs(argv, OPTION_SPECS);
10
+ if (subcommand === 'path') {
11
+ console.log(configPath());
12
+ return;
13
+ }
14
+ if (subcommand === 'set') {
15
+ const patches = {};
16
+ if (parsed.options.has('url'))
17
+ patches.url = requireOption(parsed.options, 'url');
18
+ if (parsed.options.has('token'))
19
+ patches.token = requireOption(parsed.options, 'token');
20
+ if (!patches.url && !patches.token) {
21
+ throw new CliError('用法: eevee config set --url <mcp-url> [--token <token>]', 64);
22
+ }
23
+ await saveConfigFile(patches);
24
+ console.log(`已写入 ${configPath()}`);
25
+ return;
26
+ }
27
+ if (subcommand === 'unset') {
28
+ if (optionCount(parsed.options, ['url', 'token']) === 0) {
29
+ throw new CliError('用法: eevee config unset <--url|--token>', 64);
30
+ }
31
+ const patch = {};
32
+ if (parsed.options.has('url'))
33
+ patch.url = undefined;
34
+ if (parsed.options.has('token'))
35
+ patch.token = undefined;
36
+ await saveConfigFile(patch);
37
+ console.log('配置已更新');
38
+ return;
39
+ }
40
+ if (subcommand === 'get') {
41
+ const key = parsed.positionals[0];
42
+ if (key !== 'url' && key !== 'token')
43
+ throw new CliError('用法: eevee config get <url|token> [--reveal]', 64);
44
+ const file = await loadConfigFile();
45
+ if (key === 'url')
46
+ console.log(file.url ?? '(未设置)');
47
+ else
48
+ console.log(hasFlag(parsed.options, 'reveal') ? file.token ?? '(未设置)' : maskToken(file.token));
49
+ return;
50
+ }
51
+ if (subcommand !== 'show')
52
+ throw new CliError(`未知子命令: config ${subcommand}`, 64);
53
+ const file = await loadConfigFile();
54
+ const environment = await resolveRuntimeConfig({});
55
+ const reveal = hasFlag(parsed.options, 'reveal');
56
+ const output = {
57
+ stored: {
58
+ url: file.url ?? null,
59
+ token: reveal ? file.token ?? null : maskToken(file.token),
60
+ path: configPath(),
61
+ },
62
+ effective: {
63
+ url: environment.url,
64
+ urlSource: process.env.EEVEE_MCP_URL ?? (file.url ? 'config.json' : 'default'),
65
+ token: reveal ? environment.token ?? null : maskToken(environment.token),
66
+ tokenSource: process.env.EEVEE_TOKEN ? 'EEVEE_TOKEN' : file.token ? 'config.json' : '(empty)',
67
+ },
68
+ };
69
+ console.log(JSON.stringify(output, null, 2));
70
+ }
71
+ //# sourceMappingURL=config-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-command.js","sourceRoot":"","sources":["../../../src/commands/config-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,131 @@
1
+ import { CliError, parseArgs, hasFlag, requireOption } from '../lib/args.js';
2
+ import { loadIntlConfig } from '../lib/intl-config.js';
3
+ import { downloadIntl } from '../lib/intl-downloader.js';
4
+ import { resolveRuntimeConfig, requireToken } from '../lib/config.js';
5
+ export async function runIntl(subcommand, argv) {
6
+ switch (subcommand) {
7
+ case 'download':
8
+ return await runDownload(argv);
9
+ case 'tags':
10
+ return await runTags(argv);
11
+ case 'versions':
12
+ return await runVersions(argv);
13
+ case 'languages':
14
+ return await runLanguages(argv);
15
+ default:
16
+ throw new CliError(`用法: eevee intl <download|tags|versions|languages>`);
17
+ }
18
+ }
19
+ // ---------- download ----------
20
+ async function runDownload(argv) {
21
+ const parsed = parseArgs(argv, [
22
+ { long: 'dry-run' },
23
+ { long: 'json' },
24
+ { long: 'config', value: true },
25
+ ]);
26
+ const config = await loadIntlConfig(typeof parsed.options.get('config') === 'string' ? String(parsed.options.get('config')) : undefined);
27
+ if (hasFlag(parsed.options, 'dry-run')) {
28
+ const summary = config.targets.map((t, i) => ({
29
+ index: i + 1,
30
+ outPath: t.outPath,
31
+ format: t.format ?? 'json',
32
+ splitByTag: t.splitByTag ?? false,
33
+ languages: t.languages,
34
+ projects: t.projects.map((p) => ({
35
+ projectId: p.projectId,
36
+ versions: p.versions ?? '(all)',
37
+ tags: p.tags ?? '(all)',
38
+ })),
39
+ }));
40
+ if (hasFlag(parsed.options, 'json')) {
41
+ console.log(JSON.stringify({ ok: true, data: { dryRun: true, targets: summary } }, null, 2));
42
+ }
43
+ else {
44
+ console.log('dry-run — 以下为将要执行的下载计划:\n');
45
+ for (const s of summary) {
46
+ console.log(`[${s.index}] outPath=${s.outPath} format=${s.format} splitByTag=${s.splitByTag}`);
47
+ console.log(` languages: ${JSON.stringify(s.languages)}`);
48
+ for (const p of s.projects) {
49
+ console.log(` project=${p.projectId} versions=${p.versions} tags=${p.tags}`);
50
+ }
51
+ }
52
+ }
53
+ return;
54
+ }
55
+ const result = await downloadIntl(config);
56
+ if (hasFlag(parsed.options, 'json')) {
57
+ console.log(JSON.stringify({ ok: true, data: result }, null, 2));
58
+ return;
59
+ }
60
+ console.log('✔ 下载完成\n');
61
+ for (const target of result.targets) {
62
+ console.log(`输出目录: ${target.outPath} 格式: ${target.format}`);
63
+ for (const file of target.files) {
64
+ console.log(` ${file.path} ${file.terms} 词条`);
65
+ }
66
+ }
67
+ console.log(`\n总计: ${result.totalTerms} 词条, 耗时 ${result.duration}ms`);
68
+ }
69
+ // ---------- tags / versions / languages ----------
70
+ async function queryApi(argv, apiPath) {
71
+ const parsed = parseArgs(argv, [
72
+ { long: 'project', value: true },
73
+ { long: 'json' },
74
+ ]);
75
+ const projectId = Number(requireOption(parsed.options, 'project'));
76
+ if (!Number.isInteger(projectId) || projectId <= 0)
77
+ throw new CliError('--project 必须是正整数');
78
+ const runtime = await resolveRuntimeConfig({});
79
+ requireToken(runtime.token);
80
+ const base = new URL(runtime.url);
81
+ base.pathname = base.pathname.replace(/\/mcp\/?$/, '');
82
+ const url = new URL(apiPath(projectId), base.origin + (base.pathname === '/' ? '' : base.pathname));
83
+ const response = await fetch(url, {
84
+ headers: { Authorization: `Bearer ${runtime.token}` },
85
+ signal: AbortSignal.timeout(15_000),
86
+ });
87
+ if (!response.ok)
88
+ throw new CliError(`API ${response.status}: ${url.pathname}`);
89
+ const json = await response.json();
90
+ return json.data;
91
+ }
92
+ async function runTags(argv) {
93
+ const parsed = parseArgs(argv, [{ long: 'project', value: true }, { long: 'json' }]);
94
+ const data = await queryApi(argv, (id) => `/api/v1/projects/${id}/tag-groups`);
95
+ if (hasFlag(parsed.options, 'json')) {
96
+ console.log(JSON.stringify({ ok: true, data }, null, 2));
97
+ return;
98
+ }
99
+ console.log('标签组 标签ID 标签名');
100
+ for (const group of data) {
101
+ for (const tag of group.tags ?? []) {
102
+ console.log(`${group.name.padEnd(14)} ${String(tag.id).padEnd(6)} ${tag.name}`);
103
+ }
104
+ }
105
+ }
106
+ async function runVersions(argv) {
107
+ const parsed = parseArgs(argv, [{ long: 'project', value: true }, { long: 'json' }]);
108
+ const data = await queryApi(argv, (id) => `/api/v1/projects/${id}/versions`);
109
+ if (hasFlag(parsed.options, 'json')) {
110
+ console.log(JSON.stringify({ ok: true, data }, null, 2));
111
+ return;
112
+ }
113
+ console.log('版本ID 版本名 词条数');
114
+ for (const v of data) {
115
+ console.log(`${String(v.id).padEnd(6)} ${(v.name ?? '').padEnd(12)} ${v.term_count ?? '-'}`);
116
+ }
117
+ }
118
+ async function runLanguages(argv) {
119
+ const parsed = parseArgs(argv, [{ long: 'json' }]);
120
+ const projectId = Number(requireOption(parseArgs(argv, [{ long: 'project', value: true }]).options, 'project'));
121
+ const data = await queryApi(argv, (id) => `/api/v1/projects/${id}`);
122
+ const locales = data.locales ?? (data.ref_locale ? [data.ref_locale] : []);
123
+ if (hasFlag(parsed.options, 'json')) {
124
+ console.log(JSON.stringify({ ok: true, data: locales }, null, 2));
125
+ return;
126
+ }
127
+ console.log('locale');
128
+ for (const locale of locales)
129
+ console.log(locale);
130
+ }
131
+ //# sourceMappingURL=intl-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intl-command.js","sourceRoot":"","sources":["../../../src/commands/intl-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ import path from 'node:path';
2
+ import { CliError, hasFlag, optionalOption, parseArgs } from '../lib/args.js';
3
+ import { runLintScan } from '../lib/lint.js';
4
+ export async function runLint(argv) {
5
+ let jsonRequested = false;
6
+ try {
7
+ const parsed = parseArgs(argv, [
8
+ { long: 'config', value: true },
9
+ { long: 'language', value: true },
10
+ { long: 'source', value: true },
11
+ { long: 'staged' },
12
+ { long: 'changed' },
13
+ { long: 'fix' },
14
+ { long: 'refresh' },
15
+ { long: 'no-refresh' },
16
+ { long: 'refresh-config', value: true },
17
+ { long: 'refresh-on-error', value: true },
18
+ { long: 'json' },
19
+ ]);
20
+ jsonRequested = hasFlag(parsed.options, 'json');
21
+ if (hasFlag(parsed.options, 'fix')) {
22
+ throw new CliError('当前没有可安全自动修复的问题;--fix 已保留。请按诊断 hint 修改,或让 Agent 根据 --json 生成补丁。', 64);
23
+ }
24
+ const sourceFlag = optionalOption(parsed.options, 'source');
25
+ if (sourceFlag && !['workspace', 'staged', 'changed'].includes(sourceFlag)) {
26
+ throw new CliError('--source 仅支持 workspace、staged 或 changed', 64);
27
+ }
28
+ let source = sourceFlag ?? 'workspace';
29
+ const staged = hasFlag(parsed.options, 'staged');
30
+ const changed = hasFlag(parsed.options, 'changed');
31
+ if (staged && changed)
32
+ throw new CliError('--staged 和 --changed 不能同时使用', 64);
33
+ if (staged)
34
+ source = 'staged';
35
+ if (changed)
36
+ source = 'changed';
37
+ const refresh = hasFlag(parsed.options, 'refresh');
38
+ const noRefresh = hasFlag(parsed.options, 'no-refresh');
39
+ if (noRefresh)
40
+ throw new CliError('词条同步是强制步骤,不支持 --no-refresh', 64);
41
+ const refreshOnError = optionalOption(parsed.options, 'refresh-on-error');
42
+ if (refreshOnError) {
43
+ throw new CliError('词条同步是强制步骤,不支持 --refresh-on-error', 64);
44
+ }
45
+ const languages = optionalOption(parsed.options, 'language')?.split(',').map((item) => item.trim());
46
+ const report = await runLintScan({
47
+ cwd: process.cwd(),
48
+ configPath: optionalOption(parsed.options, 'config'),
49
+ languages,
50
+ files: parsed.positionals,
51
+ source,
52
+ refresh: {
53
+ enabled: refresh ? true : undefined,
54
+ config: optionalOption(parsed.options, 'refresh-config'),
55
+ },
56
+ });
57
+ if (jsonRequested) {
58
+ console.log(JSON.stringify({ ok: true, data: report }, null, 2));
59
+ }
60
+ else {
61
+ renderHuman(report);
62
+ }
63
+ if (!report.passed)
64
+ process.exitCode = 1;
65
+ }
66
+ catch (error) {
67
+ if (!jsonRequested)
68
+ throw error;
69
+ const exitCode = error instanceof CliError && Number.isInteger(error.exitCode) ? error.exitCode : 1;
70
+ console.log(JSON.stringify({ ok: false, error: { message: error.message } }, null, 2));
71
+ process.exitCode = exitCode;
72
+ }
73
+ }
74
+ function renderHuman(report) {
75
+ if (report.refresh?.status === 'ok') {
76
+ console.log(`✔ 词条同步完成:${report.refresh.totalTerms ?? 0} 词条,耗时 ${report.refresh.duration ?? 0}ms`);
77
+ }
78
+ else if (report.refresh?.status === 'warn') {
79
+ console.warn('词条同步失败时不会继续检查');
80
+ }
81
+ if (report.issueCount === 0) {
82
+ console.log(`✔ ${report.source === 'workspace' ? '检查完成' : `检查 ${report.source} 文件完成`},未发现国际化问题`);
83
+ return;
84
+ }
85
+ console.log('EEVEE 国际化检查\n');
86
+ for (const file of report.files) {
87
+ for (const diagnostic of file.diagnostics) {
88
+ const relative = path.relative(report.root, diagnostic.file).replaceAll(path.sep, '/');
89
+ console.log(`${relative}:${diagnostic.line}:${diagnostic.column} error ${diagnostic.message} ${diagnostic.ruleId}`);
90
+ console.log(` ${diagnostic.excerpt}`);
91
+ console.log(` 建议: ${diagnostic.hint}`);
92
+ }
93
+ }
94
+ const byCode = groupCount(report.files.flatMap((file) => file.diagnostics.map((item) => item.code)));
95
+ console.log(`\n✖ ${report.issueCount} 个问题,覆盖 ${report.files.length} 个文件`);
96
+ console.log(` ${Object.entries(byCode).map(([code, count]) => `${code}: ${count}`).join(', ')}`);
97
+ console.log(' 自动修复: 当前规则需要业务决策,没有启用自动改写;可使用 --json 获取结构化建议');
98
+ }
99
+ function groupCount(values) {
100
+ const result = {};
101
+ for (const value of values)
102
+ result[value] = (result[value] ?? 0) + 1;
103
+ return result;
104
+ }
105
+ //# sourceMappingURL=lint-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint-command.js","sourceRoot":"","sources":["../../../src/commands/lint-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,167 @@
1
+ import { parseArgs, CliError, hasFlag, optionalOption } from '../lib/args.js';
2
+ import { resolveRuntimeConfig } from '../lib/config.js';
3
+ import { McpClient } from '../lib/mcp-client.js';
4
+ import { parseJsonObject } from '../lib/json.js';
5
+ import { isToolResult, renderValue } from '../lib/output.js';
6
+ import { mergeLiveTools, renderToolDoc } from '../lib/tool-docs.js';
7
+ const COMMON = [
8
+ { long: 'url', value: true },
9
+ { long: 'token', value: true },
10
+ { long: 'timeout', value: true, default: '60000' },
11
+ { long: 'json' },
12
+ ];
13
+ async function prepare(argv, specs = []) {
14
+ const parsed = parseArgs(argv, [...COMMON, ...specs]);
15
+ const timeoutValue = optionalOption(parsed.options, 'timeout') ?? '60000';
16
+ const timeout = Number(timeoutValue);
17
+ if (!Number.isSafeInteger(timeout) || timeout <= 0)
18
+ throw new CliError('--timeout 必须是正整数毫秒数', 64);
19
+ const config = await resolveRuntimeConfig({
20
+ url: optionalOption(parsed.options, 'url'),
21
+ token: optionalOption(parsed.options, 'token'),
22
+ });
23
+ return {
24
+ client: new McpClient(config, timeout),
25
+ url: config.url,
26
+ options: parsed.options,
27
+ positionals: parsed.positionals,
28
+ };
29
+ }
30
+ function render(value, invocation) {
31
+ return renderValue(value, { json: hasFlag(invocation.options, 'json'), raw: optionsHasRaw(invocation.options) });
32
+ }
33
+ function optionsHasRaw(options) {
34
+ return options.has('raw');
35
+ }
36
+ function printInvocationResult(value, invocation) {
37
+ const text = render(value, invocation);
38
+ if (isToolResult(value) && value.isError === true) {
39
+ console.error(text);
40
+ throw new CliError('MCP 返回 isError=true', 1);
41
+ }
42
+ console.log(text);
43
+ }
44
+ export async function runPing(argv) {
45
+ const invocation = await prepare(argv);
46
+ await invocation.client.ping();
47
+ printInvocationResult({
48
+ status: 'ok',
49
+ server: invocation.url,
50
+ }, invocation);
51
+ }
52
+ export async function runTools(subcommand, argv) {
53
+ if (subcommand === 'list')
54
+ return toolsList(argv);
55
+ if (subcommand === 'docs')
56
+ return toolDocs(argv);
57
+ if (subcommand === 'call')
58
+ return toolCall(argv);
59
+ throw new CliError('用法: eevee tools <list|docs|call>', 64);
60
+ }
61
+ async function toolsList(argv) {
62
+ const invocation = await prepare(argv, [{ long: 'raw' }]);
63
+ const result = await invocation.client.listTools();
64
+ if (!hasFlag(invocation.options, 'json') && !optionsHasRaw(invocation.options)) {
65
+ for (const tool of result.tools) {
66
+ console.log(`${tool.name}\t${tool.title ?? ''}\t${tool.description ?? ''}`);
67
+ }
68
+ return;
69
+ }
70
+ printInvocationResult(result, invocation);
71
+ }
72
+ async function toolDocs(argv) {
73
+ const invocation = await prepare(argv);
74
+ const live = await invocation.client.listTools();
75
+ const docs = mergeLiveTools(live.tools);
76
+ const requestedName = invocation.positionals[0];
77
+ const selected = requestedName ? docs.filter((doc) => doc.live.name === requestedName) : docs;
78
+ if (requestedName && selected.length === 0)
79
+ throw new CliError(`工具不存在: ${requestedName}`, 66);
80
+ console.log(selected.map(renderToolDoc).join('\n\n'));
81
+ }
82
+ async function toolCall(argv) {
83
+ const invocation = await prepare(argv, [
84
+ { long: 'args', value: true },
85
+ { long: 'raw' },
86
+ ]);
87
+ const name = invocation.positionals[0];
88
+ if (!name || name.startsWith('-'))
89
+ throw new CliError('用法: eevee tools call <tool-name> [JSON|@file]', 64);
90
+ const inlineJson = invocation.positionals[1];
91
+ const fileJson = optionalOption(invocation.options, 'args');
92
+ if (inlineJson && fileJson)
93
+ throw new CliError('--args 和位置 JSON 只能选择一个', 64);
94
+ const args = parseJsonObject(inlineJson ?? fileJson, '工具参数');
95
+ const result = await invocation.client.callTool(name, args);
96
+ printInvocationResult(result, invocation);
97
+ }
98
+ export async function runResources(subcommand, argv) {
99
+ if (!['list', 'templates', 'read', 'subscribe', 'unsubscribe'].includes(subcommand)) {
100
+ throw new CliError('用法: eevee resources <list|templates|read|subscribe|unsubscribe> [uri]', 64);
101
+ }
102
+ const needsUri = ['read', 'subscribe', 'unsubscribe'].includes(subcommand);
103
+ const invocation = await prepare(argv, needsUri ? [{ long: 'uri', value: true }] : []);
104
+ if (subcommand === 'list') {
105
+ printInvocationResult(await invocation.client.request('resources/list'), invocation);
106
+ return;
107
+ }
108
+ if (subcommand === 'templates') {
109
+ printInvocationResult(await invocation.client.request('resources/templates/list'), invocation);
110
+ return;
111
+ }
112
+ const uri = invocation.positionals[0] ?? optionalOption(invocation.options, 'uri');
113
+ if (!uri)
114
+ throw new CliError(`resources ${subcommand} 需要 URI`, 64);
115
+ printInvocationResult(await invocation.client.request(`resources/${subcommand}`, { uri }), invocation);
116
+ }
117
+ export async function runPrompts(subcommand, argv) {
118
+ if (!['list', 'get'].includes(subcommand))
119
+ throw new CliError('用法: eevee prompts <list|get>', 64);
120
+ if (subcommand === 'list') {
121
+ const invocation = await prepare(argv);
122
+ printInvocationResult(await invocation.client.request('prompts/list'), invocation);
123
+ return;
124
+ }
125
+ const invocation = await prepare(argv, [{ long: 'args', value: true }]);
126
+ const name = invocation.positionals[0];
127
+ if (!name || name.startsWith('-'))
128
+ throw new CliError('用法: eevee prompts get <name> [--args JSON]', 64);
129
+ const argumentsValue = parseJsonObject(optionalOption(invocation.options, 'args'), '--args');
130
+ printInvocationResult(await invocation.client.request('prompts/get', {
131
+ name,
132
+ arguments: argumentsValue,
133
+ }), invocation);
134
+ }
135
+ export async function runRequest(argv, notification = false) {
136
+ const specs = [...COMMON, ...(notification ? [{ long: 'params', value: true }] : [])];
137
+ const parsed = parseArgs(argv, specs);
138
+ const method = parsed.positionals[0];
139
+ if (!method || method.startsWith('-')) {
140
+ throw new CliError(notification
141
+ ? '用法: eevee notify <method> --params JSON'
142
+ : '用法: eevee request <method> [JSON|@file]', 64);
143
+ }
144
+ const params = notification
145
+ ? parseJsonObject(optionalOption(parsed.options, 'params'), '--params')
146
+ : parseJsonObject(parsed.positionals[1], 'params');
147
+ const config = await resolveRuntimeConfig({
148
+ url: optionalOption(parsed.options, 'url'),
149
+ token: optionalOption(parsed.options, 'token'),
150
+ });
151
+ const client = new McpClient(config, Number(optionalOption(parsed.options, 'timeout') ?? 60_000));
152
+ const result = await client.request(method, params, notification);
153
+ if (notification) {
154
+ console.log(hasFlag(parsed.options, 'json')
155
+ ? JSON.stringify({ ok: true, data: { sent: true } }, null, 2)
156
+ : '通知已发送');
157
+ return;
158
+ }
159
+ const options = parsed.options;
160
+ const text = renderValue(result, { json: hasFlag(options, 'json'), raw: options.has('raw') });
161
+ if (isToolResult(result) && result.isError === true) {
162
+ console.error(text);
163
+ throw new CliError('MCP 返回 isError=true', 1);
164
+ }
165
+ console.log(text);
166
+ }
167
+ //# sourceMappingURL=mcp-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-command.js","sourceRoot":"","sources":["../../../src/commands/mcp-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import { CliError, hasFlag, optionCount, optionalOption, parseArgs } from '../lib/args.js';
2
+ import { bundledSkillDirectory, discoverInstalls, destinationFor, installSkill, parseAgents, SKILL_AGENTS, } from '../lib/skill-installer.js';
3
+ import { readFile, rm, stat } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ export async function runSkills(subcommand, argv) {
6
+ if (subcommand === 'list')
7
+ return list();
8
+ if (subcommand === 'paths')
9
+ return paths();
10
+ if (subcommand === 'info')
11
+ return info();
12
+ if (subcommand === 'install')
13
+ return install(argv);
14
+ if (subcommand === 'update')
15
+ return update(argv);
16
+ if (subcommand === 'uninstall')
17
+ return uninstall(argv);
18
+ throw new CliError('用法: eevee skills <install|update|list|paths|info|uninstall>', 64);
19
+ }
20
+ async function install(argv, forceDefault = false) {
21
+ const parsed = parseArgs(argv, [
22
+ { long: 'agent', value: true },
23
+ { long: 'global' },
24
+ { long: 'project', value: true },
25
+ { long: 'dir', value: true },
26
+ { long: 'force' },
27
+ { long: 'dry-run' },
28
+ { long: 'yes' },
29
+ ]);
30
+ const selections = [
31
+ ...parsed.positionals.filter((item) => !item.startsWith('-')),
32
+ ];
33
+ const agentValue = optionalOption(parsed.options, 'agent');
34
+ if (agentValue)
35
+ selections.push(...agentValue.split(','));
36
+ const agents = parseAgents(selections);
37
+ const projectValue = optionalOption(parsed.options, 'project');
38
+ const targetDirectory = optionalOption(parsed.options, 'dir');
39
+ const explicitModes = optionCount(parsed.options, ['global', 'project', 'dir']);
40
+ if (explicitModes === 0)
41
+ parsed.options.set('global', true);
42
+ if (explicitModes > 1)
43
+ throw new CliError('--global、--project 和 --dir 不能同时使用', 64);
44
+ const globalMode = hasFlag(parsed.options, 'global');
45
+ const results = await installSkill({
46
+ agents,
47
+ global: globalMode,
48
+ projectDirectory: projectValue,
49
+ targetDirectory,
50
+ force: forceDefault || hasFlag(parsed.options, 'force'),
51
+ dryRun: hasFlag(parsed.options, 'dry-run'),
52
+ });
53
+ for (const item of results)
54
+ console.log(`${item.action.padEnd(7)} ${item.agent.padEnd(20)} ${item.directory}`);
55
+ }
56
+ async function update(argv) {
57
+ await install(argv, true);
58
+ }
59
+ async function list() {
60
+ const installs = await discoverInstalls();
61
+ if (installs.length === 0)
62
+ console.log('未发现全局安装');
63
+ else
64
+ for (const item of installs)
65
+ console.log(`${item.agent}\t${item.path}`);
66
+ }
67
+ async function paths() {
68
+ const source = await bundledSkillDirectory();
69
+ console.log(`source\t${source}`);
70
+ for (const [agent, definition] of Object.entries(SKILL_AGENTS)) {
71
+ const result = destinationFor(agent, { agents: [], global: true });
72
+ console.log(`${definition.label}\t${result}`);
73
+ }
74
+ }
75
+ async function info() {
76
+ const source = path.join(await bundledSkillDirectory(), 'SKILL.md');
77
+ const content = await readFile(source, 'utf8');
78
+ console.log(content);
79
+ }
80
+ async function uninstall(argv) {
81
+ const parsed = parseArgs(argv, [
82
+ { long: 'agent', value: true },
83
+ { long: 'global' },
84
+ { long: 'project', value: true },
85
+ { long: 'dir', value: true },
86
+ { long: 'yes' },
87
+ ]);
88
+ if (!hasFlag(parsed.options, 'yes'))
89
+ throw new CliError('卸载需要 --yes 确认', 64);
90
+ const selections = parsed.positionals.filter((item) => !item.startsWith('-'));
91
+ const agentValue = optionalOption(parsed.options, 'agent');
92
+ if (agentValue)
93
+ selections.push(agentValue);
94
+ const agents = parseAgents(selections);
95
+ const projectValue = optionalOption(parsed.options, 'project');
96
+ const targetDirectory = optionalOption(parsed.options, 'dir');
97
+ if (optionCount(parsed.options, ['global', 'project', 'dir']) > 1)
98
+ throw new CliError('--global、--project 和 --dir 不能同时使用', 64);
99
+ const globalMode = !projectValue && !targetDirectory;
100
+ for (const agent of agents) {
101
+ const destination = destinationFor(agent, {
102
+ agents,
103
+ global: globalMode,
104
+ projectDirectory: projectValue,
105
+ targetDirectory,
106
+ });
107
+ try {
108
+ if ((await stat(path.join(destination, 'SKILL.md'))).isFile()) {
109
+ await rm(destination, { recursive: true });
110
+ console.log(`removed ${destination}`);
111
+ }
112
+ }
113
+ catch { /* 未安装则跳过 */ }
114
+ }
115
+ }
116
+ //# sourceMappingURL=skill-command.js.map