@mearl/setup 2.15.3 → 2.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -8
- package/dist/internalPlugins.d.ts +8 -3
- package/dist/internalPlugins.js +133 -34
- package/dist/lifecycle.js +51 -40
- package/dist/plugin.js +4 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -31,18 +31,22 @@ mearl yuque read "https://aliyuque.antfin.com/group/book/doc"
|
|
|
31
31
|
|
|
32
32
|
安装参数透传给 `npx -y ali-skills add`,末尾统一追加 `--global --install-mode symlink`;不接受会截断后置选项的 `--` 参数分隔符,
|
|
33
33
|
确保 skill 存放在 `~/.agents/skills` 并共享给所选 agent。安装日志实时显示,保留交互;
|
|
34
|
-
setup 从 `Installed … skill(s)` 成功区块提取路径,仅注册本次安装且包含 `scripts/main.mjs` 的 skill
|
|
34
|
+
setup 从 `Installed … skill(s)` 成功区块提取路径,仅注册本次安装且包含 `scripts/main.mjs` 或 `scripts/main.py` 的 skill;两者同时存在时使用 JavaScript 入口。
|
|
35
35
|
普通 skill 正常安装。输出格式无法识别时提示手动注册,不扫描其他 skill 或猜测安装结果。
|
|
36
36
|
|
|
37
|
-
默认 `install` 和 `update`
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
默认 `install` 和 `update` 会用最多 5 秒的 `npm ping` 检查阿里内网 registry。
|
|
38
|
+
registry 可访问时通过 Ali Skills 批量处理 `mearl`、`buc-request` 与 `tdbank-account`:安装使用一次
|
|
39
|
+
`add` 并注册两个插件,更新已跟踪项使用一次 `update`;卸载时使用一次 `remove` 批量移除 setup 管理的
|
|
40
|
+
三项 Skill。
|
|
41
|
+
更新发现某个官方插件缺少注册时,会在批量更新已跟踪项后通过一次 `add` 补装并恢复注册。
|
|
42
|
+
该 registry 不用于下载插件。
|
|
43
|
+
探测不可用时按普通外网流程只处理 Mearl Skill;内网批量命令失败时 setup 失败,不再逐项重试。
|
|
44
|
+
`--skip-skill` 和 `--target-line` 安装不执行自动插件步骤。
|
|
41
45
|
|
|
42
46
|
Mearl client 内置官方插件名称与安装来源目录。CLI、SDK、MCP 或另一个插件首次调用尚未注册的官方插件时,会通过内部幂等流程安装并重试一次;未知名称不会触发安装。
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
自动注册默认使用安装目录名;入口可声明 `name` 指定简短命令名。
|
|
49
|
+
重装会刷新同名绑定。JavaScript 入口必须默认导出 `register(app)`,Python 入口必须导出 `register(app)` 函数;完整协议见
|
|
46
50
|
[Skill 插件规范](../skills/mearl-skill-creator/references/cli-plugin.md)。
|
|
47
51
|
|
|
48
52
|
已通过其他渠道分发的 skill 或自定义入口,可以直接传入路径注册:
|
|
@@ -52,7 +56,7 @@ npx @mearl/setup plugin yuque /absolute/path/to/yuque-doc-fetch
|
|
|
52
56
|
npx @mearl/setup plugin custom ./skills/custom/entry.mjs
|
|
53
57
|
```
|
|
54
58
|
|
|
55
|
-
path 接受目录或具体文件;目录默认读取 `scripts/main.mjs`,相对路径基于调用工作目录解析。
|
|
59
|
+
path 接受目录或具体文件;目录默认读取 `scripts/main.mjs` 或 `scripts/main.py`,相对路径基于调用工作目录解析。Python 插件要求 `python3 >= 3.9`,可通过 `MEARL_PYTHON` 指定解释器路径;setup 只验证入口可加载,不安装 Python,也不执行 `pip install`。
|
|
56
60
|
命令检查入口注册函数,然后保存绝对入口路径,同名注册更新绑定。
|
|
57
61
|
两种注册流程都会检查本机 `@mearl/client` 和 `@mearl/native-host`:缺失或低于当前 setup 版本时,
|
|
58
62
|
复用已有包管理器安装 setup 的对应版本,更新后再次验证;更高版本保持不动。
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { findPluginRegistration } from '@mearl/client/plugin';
|
|
2
|
-
import {
|
|
1
|
+
import { findPluginRegistration, listPluginNames, unregisterPlugin } from '@mearl/client/plugin';
|
|
2
|
+
import { resolveAliSkillsInvocation } from './aliSkills.js';
|
|
3
|
+
import { installPlugins } from './plugin.js';
|
|
3
4
|
import { findExecutable, type CommandRunner } from './process.js';
|
|
4
5
|
export declare const ALIBABA_NPM_REGISTRY = "https://registry.anpm.alibaba-inc.com/";
|
|
5
6
|
export declare const ALIBABA_INTERNAL_PLUGIN_NAMES: string[];
|
|
6
7
|
export interface InternalPluginOptions {
|
|
7
8
|
env?: NodeJS.ProcessEnv;
|
|
9
|
+
includeMearlSkill?: boolean;
|
|
10
|
+
mearlSkillOperation?: 'install' | 'update';
|
|
8
11
|
runCommand?: CommandRunner;
|
|
9
12
|
writeLine?: (line: string) => void;
|
|
10
13
|
}
|
|
@@ -12,8 +15,10 @@ export interface InternalPluginDependencies {
|
|
|
12
15
|
findExecutable?: typeof findExecutable;
|
|
13
16
|
findPluginRegistration?: typeof findPluginRegistration;
|
|
14
17
|
installPlugins?: typeof installPlugins;
|
|
18
|
+
listPluginNames?: typeof listPluginNames;
|
|
15
19
|
probeAlibabaRegistry?: (options: InternalPluginOptions) => Promise<boolean>;
|
|
16
|
-
|
|
20
|
+
resolveAliSkillsInvocation?: typeof resolveAliSkillsInvocation;
|
|
21
|
+
unregisterPlugin?: typeof unregisterPlugin;
|
|
17
22
|
}
|
|
18
23
|
export declare function canAccessAlibabaNpmRegistry(options?: InternalPluginOptions, dependencies?: Pick<InternalPluginDependencies, 'findExecutable'>): Promise<boolean>;
|
|
19
24
|
/** Uses the internal registry only as an intranet probe; Ali Skills installs the plugins. */
|
package/dist/internalPlugins.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { dirname } from 'node:path';
|
|
2
|
-
import { findOfficialPlugin, findPluginRegistration, listOfficialPluginNames, OFFICIAL_PLUGIN_MANAGER, } from '@mearl/client/plugin';
|
|
3
|
-
import {
|
|
2
|
+
import { findOfficialPlugin, findPluginRegistration, listPluginNames, listOfficialPluginNames, OFFICIAL_PLUGIN_MANAGER, unregisterPlugin, } from '@mearl/client/plugin';
|
|
3
|
+
import { resolveAliSkillsInvocation } from './aliSkills.js';
|
|
4
|
+
import { installPlugins } from './plugin.js';
|
|
4
5
|
import { findExecutable, prependCommandPath, runCommand } from './process.js';
|
|
5
6
|
export const ALIBABA_NPM_REGISTRY = 'https://registry.anpm.alibaba-inc.com/';
|
|
6
7
|
export const ALIBABA_INTERNAL_PLUGIN_NAMES = listOfficialPluginNames('alibaba');
|
|
@@ -35,12 +36,15 @@ export async function canAccessAlibabaNpmRegistry(options = {}, dependencies = {
|
|
|
35
36
|
export async function installAlibabaInternalPlugins(options = {}, dependencies = {}) {
|
|
36
37
|
const writeLine = options.writeLine ?? (line => console.error(line));
|
|
37
38
|
const registrationFor = dependencies.findPluginRegistration ?? findPluginRegistration;
|
|
39
|
+
const missingRegistrations = new Set();
|
|
38
40
|
const candidates = ALIBABA_INTERNAL_PLUGIN_NAMES.filter(name => {
|
|
39
41
|
const registration = registrationFor(name);
|
|
40
42
|
if (registration && registration.managedBy !== OFFICIAL_PLUGIN_MANAGER) {
|
|
41
43
|
writeLine(`${name} plugin: existing user registration kept.`);
|
|
42
44
|
return false;
|
|
43
45
|
}
|
|
46
|
+
if (!registration)
|
|
47
|
+
missingRegistrations.add(name);
|
|
44
48
|
return true;
|
|
45
49
|
});
|
|
46
50
|
if (candidates.length === 0)
|
|
@@ -48,50 +52,145 @@ export async function installAlibabaInternalPlugins(options = {}, dependencies =
|
|
|
48
52
|
const probe = dependencies.probeAlibabaRegistry ?? (input => canAccessAlibabaNpmRegistry(input));
|
|
49
53
|
if (!(await probe(options)))
|
|
50
54
|
return 'skipped';
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
if (options.mearlSkillOperation === 'update') {
|
|
56
|
+
const registeredCandidates = candidates.filter(name => !missingRegistrations.has(name));
|
|
57
|
+
const missingCandidates = candidates.filter(name => missingRegistrations.has(name));
|
|
58
|
+
const updateSkillNames = [
|
|
59
|
+
...(options.includeMearlSkill ? ['mearl'] : []),
|
|
60
|
+
...registeredCandidates.map(name => findOfficialPlugin(name).skill),
|
|
61
|
+
];
|
|
62
|
+
if (updateSkillNames.length > 0) {
|
|
63
|
+
const invocation = (dependencies.resolveAliSkillsInvocation ?? resolveAliSkillsInvocation)({
|
|
64
|
+
env: options.env,
|
|
65
|
+
});
|
|
66
|
+
if (!invocation) {
|
|
67
|
+
writeLine('Internal skill batch: ali-skills and npx are both unavailable; update failed.');
|
|
68
|
+
return 'failed';
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const updated = await (options.runCommand ?? runCommand)(invocation.command, [...invocation.argsPrefix, 'update', ...updateSkillNames, '--global', '--yes'], { env: invocation.env, tee: true });
|
|
72
|
+
if (updated.code !== 0) {
|
|
73
|
+
writeLine(`Internal skill batch: update failed (exit ${updated.code}).`);
|
|
74
|
+
return 'failed';
|
|
75
|
+
}
|
|
76
|
+
if (options.includeMearlSkill)
|
|
77
|
+
writeLine('Skill: updated.');
|
|
78
|
+
for (const name of registeredCandidates)
|
|
79
|
+
writeLine(`${name} plugin: updated.`);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; update failed.`);
|
|
83
|
+
return 'failed';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (missingCandidates.length > 0) {
|
|
87
|
+
const repairArgs = [
|
|
88
|
+
'trip/mearl',
|
|
89
|
+
'--skill',
|
|
90
|
+
...missingCandidates.map(name => findOfficialPlugin(name).skill),
|
|
91
|
+
'--yes',
|
|
92
|
+
];
|
|
93
|
+
try {
|
|
94
|
+
const code = await (dependencies.installPlugins ?? installPlugins)(repairArgs, options.runCommand, { registrationManagedBy: OFFICIAL_PLUGIN_MANAGER });
|
|
95
|
+
if (code !== 0) {
|
|
96
|
+
writeLine(`Internal skill batch: registration repair failed (exit ${code}).`);
|
|
97
|
+
return 'failed';
|
|
98
|
+
}
|
|
99
|
+
for (const name of missingCandidates) {
|
|
100
|
+
writeLine(`${name} plugin: installed and registered.`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; registration repair failed.`);
|
|
105
|
+
return 'failed';
|
|
61
106
|
}
|
|
62
|
-
installed = true;
|
|
63
|
-
writeLine(`${name} plugin: installed and registered.`);
|
|
64
107
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
108
|
+
return 'installed';
|
|
109
|
+
}
|
|
110
|
+
const skillNames = [
|
|
111
|
+
...(options.includeMearlSkill ? ['mearl'] : []),
|
|
112
|
+
...candidates.map(name => findOfficialPlugin(name).skill),
|
|
113
|
+
];
|
|
114
|
+
const args = ['trip/mearl', '--skill', ...skillNames, '--yes'];
|
|
115
|
+
try {
|
|
116
|
+
const code = await (dependencies.installPlugins ?? installPlugins)(args, options.runCommand, {
|
|
117
|
+
registrationManagedBy: OFFICIAL_PLUGIN_MANAGER,
|
|
118
|
+
});
|
|
119
|
+
if (code !== 0) {
|
|
120
|
+
writeLine(`Internal skill batch: install failed (exit ${code}).`);
|
|
121
|
+
return 'failed';
|
|
68
122
|
}
|
|
123
|
+
if (options.includeMearlSkill)
|
|
124
|
+
writeLine('Skill: installed.');
|
|
125
|
+
for (const name of candidates)
|
|
126
|
+
writeLine(`${name} plugin: installed and registered.`);
|
|
127
|
+
return 'installed';
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; install failed.`);
|
|
131
|
+
return 'failed';
|
|
69
132
|
}
|
|
70
|
-
return failed ? 'failed' : installed ? 'installed' : 'skipped';
|
|
71
133
|
}
|
|
72
134
|
export async function uninstallAlibabaInternalPlugins(options = {}, dependencies = {}) {
|
|
73
135
|
const writeLine = options.writeLine ?? (line => console.error(line));
|
|
74
136
|
const registrationFor = dependencies.findPluginRegistration ?? findPluginRegistration;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
137
|
+
const removedSkillDirectories = new Set();
|
|
138
|
+
const candidates = ALIBABA_INTERNAL_PLUGIN_NAMES.filter(name => {
|
|
139
|
+
const registration = registrationFor(name);
|
|
140
|
+
if (!registration)
|
|
141
|
+
return false;
|
|
142
|
+
if (registration.managedBy !== OFFICIAL_PLUGIN_MANAGER) {
|
|
143
|
+
writeLine(`${name} plugin: existing user registration kept.`);
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
removedSkillDirectories.add(dirname(dirname(registration.entry)));
|
|
147
|
+
return true;
|
|
148
|
+
});
|
|
149
|
+
const skillNames = [
|
|
150
|
+
...(options.includeMearlSkill ? ['mearl'] : []),
|
|
151
|
+
...candidates.map(name => findOfficialPlugin(name).skill),
|
|
152
|
+
];
|
|
153
|
+
if (skillNames.length === 0)
|
|
154
|
+
return 'skipped';
|
|
155
|
+
const invocation = (dependencies.resolveAliSkillsInvocation ?? resolveAliSkillsInvocation)({
|
|
156
|
+
env: options.env,
|
|
157
|
+
});
|
|
158
|
+
if (!invocation) {
|
|
159
|
+
writeLine('Internal skill batch: ali-skills and npx are both unavailable; uninstall failed.');
|
|
160
|
+
return 'failed';
|
|
161
|
+
}
|
|
162
|
+
const runner = options.runCommand ?? runCommand;
|
|
163
|
+
let removed;
|
|
164
|
+
try {
|
|
165
|
+
removed = await runner(invocation.command, [...invocation.argsPrefix, 'remove', ...skillNames, '--global', '--yes'], { env: invocation.env, tee: true });
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; uninstall failed.`);
|
|
169
|
+
return 'failed';
|
|
170
|
+
}
|
|
171
|
+
if (removed.code !== 0) {
|
|
172
|
+
writeLine(`Internal skill batch: uninstall failed (exit ${removed.code}).`);
|
|
173
|
+
return 'failed';
|
|
174
|
+
}
|
|
175
|
+
const unregister = dependencies.unregisterPlugin ?? unregisterPlugin;
|
|
176
|
+
const registrationsToRemove = new Set(candidates);
|
|
177
|
+
for (const name of (dependencies.listPluginNames ?? listPluginNames)()) {
|
|
78
178
|
try {
|
|
79
179
|
const registration = registrationFor(name);
|
|
80
|
-
if (registration
|
|
81
|
-
|
|
82
|
-
writeLine(`${name} plugin: existing user registration kept.`);
|
|
83
|
-
continue;
|
|
180
|
+
if (registration && removedSkillDirectories.has(dirname(dirname(registration.entry)))) {
|
|
181
|
+
registrationsToRemove.add(name);
|
|
84
182
|
}
|
|
85
|
-
const result = await (dependencies.uninstallPlugin ?? uninstallPlugin)(name, options.runCommand);
|
|
86
|
-
if (!result.removed)
|
|
87
|
-
continue;
|
|
88
|
-
uninstalled = true;
|
|
89
|
-
writeLine(`${name} plugin: uninstalled.`);
|
|
90
183
|
}
|
|
91
|
-
catch
|
|
92
|
-
|
|
93
|
-
writeLine(`${name} plugin: ${error instanceof Error ? error.message : String(error)}; uninstall failed.`);
|
|
184
|
+
catch {
|
|
185
|
+
// 无法读取的注册不影响已确认 Skill 的卸载和其他有效注册清理。
|
|
94
186
|
}
|
|
95
187
|
}
|
|
96
|
-
|
|
188
|
+
for (const name of [...registrationsToRemove].sort())
|
|
189
|
+
unregister(name);
|
|
190
|
+
for (const name of candidates) {
|
|
191
|
+
writeLine(`${name} plugin: uninstalled.`);
|
|
192
|
+
}
|
|
193
|
+
if (options.includeMearlSkill)
|
|
194
|
+
writeLine('Skill: uninstalled.');
|
|
195
|
+
return 'uninstalled';
|
|
97
196
|
}
|
package/dist/lifecycle.js
CHANGED
|
@@ -277,16 +277,61 @@ export async function runMearlLifecycle(options, dependencies = {}) {
|
|
|
277
277
|
packagesOk = false;
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
|
-
let skillOk = true;
|
|
281
280
|
const selectedUsesSkill = selected.some(profile => MEARL_PROFILES[profile].usesSkill);
|
|
282
|
-
|
|
281
|
+
const remainingSkillProfiles = ['local', 'cloud'].filter(profile => detected.has(profile) && !selected.includes(profile));
|
|
282
|
+
let runStandaloneSkill = true;
|
|
283
|
+
let skillOk = true;
|
|
284
|
+
if (packagesOk &&
|
|
285
|
+
selectedUsesSkill &&
|
|
286
|
+
selectedUsesClient &&
|
|
287
|
+
options.skipSkill !== true &&
|
|
288
|
+
((options.operation === 'uninstall' && remainingSkillProfiles.length === 0) ||
|
|
289
|
+
(options.operation !== 'uninstall' && options.targetLine === undefined))) {
|
|
290
|
+
try {
|
|
291
|
+
if (options.operation === 'uninstall') {
|
|
292
|
+
const result = await (dependencies.uninstallInternalPlugins ?? uninstallAlibabaInternalPlugins)({
|
|
293
|
+
env,
|
|
294
|
+
includeMearlSkill: true,
|
|
295
|
+
runCommand: runner,
|
|
296
|
+
writeLine,
|
|
297
|
+
});
|
|
298
|
+
if (result === 'uninstalled')
|
|
299
|
+
runStandaloneSkill = false;
|
|
300
|
+
else if (result === 'failed') {
|
|
301
|
+
runStandaloneSkill = false;
|
|
302
|
+
skillOk = false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const result = await (dependencies.installInternalPlugins ?? installAlibabaInternalPlugins)({
|
|
307
|
+
env,
|
|
308
|
+
includeMearlSkill: true,
|
|
309
|
+
mearlSkillOperation: options.operation,
|
|
310
|
+
runCommand: runner,
|
|
311
|
+
writeLine,
|
|
312
|
+
});
|
|
313
|
+
if (result === 'installed')
|
|
314
|
+
runStandaloneSkill = false;
|
|
315
|
+
else if (result === 'failed') {
|
|
316
|
+
runStandaloneSkill = false;
|
|
317
|
+
skillOk = false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; failed.`);
|
|
323
|
+
runStandaloneSkill = false;
|
|
324
|
+
skillOk = false;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (packagesOk && skillOk && selectedUsesSkill && options.skipSkill !== true) {
|
|
283
328
|
try {
|
|
284
329
|
if (options.operation === 'uninstall') {
|
|
285
|
-
const remainingSkillProfiles = ['local', 'cloud'].filter(profile => detected.has(profile) && !selected.includes(profile));
|
|
286
330
|
if (remainingSkillProfiles.length > 0) {
|
|
287
331
|
writeLine(`Skill: kept for ${remainingSkillProfiles.join(', ')}.`);
|
|
332
|
+
writeLine(`Internal plugins: kept for ${remainingSkillProfiles.join(', ')}.`);
|
|
288
333
|
}
|
|
289
|
-
else {
|
|
334
|
+
else if (runStandaloneSkill) {
|
|
290
335
|
skillOk = await runSkill('uninstall', {
|
|
291
336
|
env,
|
|
292
337
|
yes: options.yes,
|
|
@@ -295,7 +340,7 @@ export async function runMearlLifecycle(options, dependencies = {}) {
|
|
|
295
340
|
});
|
|
296
341
|
}
|
|
297
342
|
}
|
|
298
|
-
else {
|
|
343
|
+
else if (runStandaloneSkill) {
|
|
299
344
|
skillOk = await runSkill(options.operation, {
|
|
300
345
|
env,
|
|
301
346
|
yes: options.yes,
|
|
@@ -309,41 +354,7 @@ export async function runMearlLifecycle(options, dependencies = {}) {
|
|
|
309
354
|
skillOk = false;
|
|
310
355
|
}
|
|
311
356
|
}
|
|
312
|
-
|
|
313
|
-
if (packagesOk && skillOk && selectedUsesClient && options.skipSkill !== true) {
|
|
314
|
-
if (options.operation === 'uninstall') {
|
|
315
|
-
if (remainingClientProfiles.length > 0) {
|
|
316
|
-
writeLine(`Internal plugins: kept for ${remainingClientProfiles.join(', ')}.`);
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
try {
|
|
320
|
-
internalPluginsOk =
|
|
321
|
-
(await (dependencies.uninstallInternalPlugins ?? uninstallAlibabaInternalPlugins)({
|
|
322
|
-
env,
|
|
323
|
-
runCommand: runner,
|
|
324
|
-
writeLine,
|
|
325
|
-
})) !== 'failed';
|
|
326
|
-
}
|
|
327
|
-
catch (error) {
|
|
328
|
-
writeLine(`Internal plugins: ${error instanceof Error ? error.message : String(error)}; uninstall failed.`);
|
|
329
|
-
internalPluginsOk = false;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
else if (options.targetLine === undefined) {
|
|
334
|
-
try {
|
|
335
|
-
await (dependencies.installInternalPlugins ?? installAlibabaInternalPlugins)({
|
|
336
|
-
env,
|
|
337
|
-
runCommand: runner,
|
|
338
|
-
writeLine,
|
|
339
|
-
});
|
|
340
|
-
}
|
|
341
|
-
catch (error) {
|
|
342
|
-
writeLine(`Internal plugins: ${error instanceof Error ? error.message : String(error)}; skipped.`);
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
if (packagesOk && skillOk && internalPluginsOk) {
|
|
357
|
+
if (packagesOk && skillOk) {
|
|
347
358
|
writeLine('Mearl setup complete.');
|
|
348
359
|
return true;
|
|
349
360
|
}
|
package/dist/plugin.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, rmdirSync, statSync } from 'node:fs';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
4
|
-
import { assertPluginName, findOfficialPlugin, findPluginEntry, findPluginRegistration, listPluginNames, loadPlugin, OFFICIAL_PLUGIN_MANAGER, registerPlugin, resolvePluginEntry, unregisterPlugin, } from '@mearl/client/plugin';
|
|
4
|
+
import { assertPluginName, findPluginDirectoryEntry, findOfficialPlugin, findPluginEntry, findPluginRegistration, listPluginNames, loadPlugin, OFFICIAL_PLUGIN_MANAGER, registerPlugin, resolvePluginEntry, unregisterPlugin, } from '@mearl/client/plugin';
|
|
5
5
|
import { ensurePluginRuntime } from './pluginRuntime.js';
|
|
6
6
|
import { resolveAliSkillsInvocation, stripAnsi } from './aliSkills.js';
|
|
7
7
|
import { findExecutable, prependNodePath, runCommand } from './process.js';
|
|
@@ -178,8 +178,8 @@ export async function installPlugins(args, runner = runCommand, options = {}) {
|
|
|
178
178
|
for (const skillPath of paths) {
|
|
179
179
|
if (!statSync(join(skillPath, 'SKILL.md')).isFile())
|
|
180
180
|
throw new Error(`安装结果缺少 SKILL.md: ${skillPath}`);
|
|
181
|
-
const entry =
|
|
182
|
-
if (!
|
|
181
|
+
const entry = findPluginDirectoryEntry(skillPath);
|
|
182
|
+
if (!entry)
|
|
183
183
|
continue;
|
|
184
184
|
const plugin = await loadPlugin(entry, registrationContext);
|
|
185
185
|
const name = plugin.name ?? basename(skillPath);
|
|
@@ -189,7 +189,7 @@ export async function installPlugins(args, runner = runCommand, options = {}) {
|
|
|
189
189
|
plugins.set(name, { entry, description: plugin.description });
|
|
190
190
|
}
|
|
191
191
|
if (plugins.size === 0) {
|
|
192
|
-
console.error('未找到 scripts/main.mjs 插件入口;自定义入口可用 setup plugin <name> <path> 注册。');
|
|
192
|
+
console.error('未找到 scripts/main.mjs 或 scripts/main.py 插件入口;自定义入口可用 setup plugin <name> <path> 注册。');
|
|
193
193
|
return 0;
|
|
194
194
|
}
|
|
195
195
|
await ensurePluginRuntime(runner);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/setup",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.16.1",
|
|
4
4
|
"description": "One-shot environment setup and configuration for Mearl",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"commander": "^15.0.0",
|
|
62
62
|
"extract-zip": "^2.0.1",
|
|
63
63
|
"ws": "^8.18.3",
|
|
64
|
-
"@mearl/client": "2.
|
|
65
|
-
"@mearl/provider": "2.
|
|
64
|
+
"@mearl/client": "2.16.1",
|
|
65
|
+
"@mearl/provider": "2.16.1"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/node": "^24.9.1",
|