@mearl/setup 2.22.0 → 3.0.0-beta.0
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/LICENSE +201 -0
- package/README.md +59 -59
- package/dist/browserExtension.d.ts +2 -2
- package/dist/browserExtension.js +25 -19
- package/dist/cli.d.ts +8 -3
- package/dist/cli.js +74 -17
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/lifecycle.d.ts +11 -4
- package/dist/lifecycle.js +48 -15
- package/dist/managedPlugins.d.ts +21 -0
- package/dist/managedPlugins.js +76 -0
- package/dist/npmRegistry.d.ts +1 -1
- package/dist/npmRegistry.js +4 -16
- package/dist/plugin.d.ts +13 -3
- package/dist/plugin.js +106 -44
- package/dist/preset.d.ts +94 -0
- package/dist/preset.js +275 -0
- package/dist/presetBrowserTransfer.d.ts +11 -0
- package/dist/presetBrowserTransfer.js +72 -0
- package/dist/presetInstallationLease.d.ts +6 -0
- package/dist/presetInstallationLease.js +66 -0
- package/dist/presetStore.d.ts +48 -0
- package/dist/presetStore.js +252 -0
- package/dist/presetUpgrade.d.ts +13 -0
- package/dist/presetUpgrade.js +42 -0
- package/dist/provider.d.ts +2 -0
- package/dist/provider.js +24 -2
- package/dist/runtimeCleanup.js +1 -8
- package/dist/setupVersion.d.ts +2 -0
- package/dist/setupVersion.js +4 -0
- package/dist/skillSources.d.ts +43 -0
- package/dist/skillSources.js +247 -0
- package/dist/skills.d.ts +45 -0
- package/dist/skills.js +213 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +6 -0
- package/package.json +22 -10
- package/dist/aliSkills.d.ts +0 -32
- package/dist/aliSkills.js +0 -212
- package/dist/internalPlugins.d.ts +0 -26
- package/dist/internalPlugins.js +0 -197
package/dist/aliSkills.js
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import os from 'node:os';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { spawn } from 'node:child_process';
|
|
5
|
-
import { executableNames, findExecutable, isExecutable, prependCommandPath, prependNodePath, resolveSpawnCommand, runCommand, versionManagerExecutableCandidates, } from '@mearl/daemon-core';
|
|
6
|
-
const COMMAND_TIMEOUT_MS = 120_000;
|
|
7
|
-
const MAX_OUTPUT_LENGTH = 1_000_000;
|
|
8
|
-
const ANSI_ESCAPE_PATTERN = new RegExp(String.raw `\u001B\[[0-?]*[ -/]*[@-~]`, 'g');
|
|
9
|
-
function existingExecutable(candidates, existsSync) {
|
|
10
|
-
return candidates.find(candidate => candidate && existsSync(candidate)) ?? null;
|
|
11
|
-
}
|
|
12
|
-
export function stripAnsi(value) {
|
|
13
|
-
return value.replace(ANSI_ESCAPE_PATTERN, '');
|
|
14
|
-
}
|
|
15
|
-
export function resolveAliSkillsExecutable(options = {}) {
|
|
16
|
-
const env = options.env ?? process.env;
|
|
17
|
-
const home = (options.homedir ?? os.homedir)();
|
|
18
|
-
const platform = options.platform ?? process.platform;
|
|
19
|
-
const existsSync = options.existsSync ?? (candidate => isExecutable(candidate, platform));
|
|
20
|
-
const processExecPath = options.processExecPath ?? process.execPath;
|
|
21
|
-
const readdirSync = options.readdirSync ?? fs.readdirSync;
|
|
22
|
-
const names = executableNames('ali-skills', platform);
|
|
23
|
-
const pathKey = Object.keys(env).find(key => key.toLowerCase() === 'path') || 'PATH';
|
|
24
|
-
const pathCandidates = (env[pathKey] || '')
|
|
25
|
-
.split(path.delimiter)
|
|
26
|
-
.filter(Boolean)
|
|
27
|
-
.flatMap(directory => names.map(name => path.join(directory, name)));
|
|
28
|
-
const candidates = [
|
|
29
|
-
env.MEARL_ALI_SKILLS_PATH,
|
|
30
|
-
...names.map(name => path.join(path.dirname(processExecPath), name)),
|
|
31
|
-
...names.map(name => path.join(home, '.local', 'bin', name)),
|
|
32
|
-
...names.map(name => path.join(home, '.npm-global', 'bin', name)),
|
|
33
|
-
...names.map(name => path.join(home, '.volta', 'bin', name)),
|
|
34
|
-
...names.map(name => path.join(home, '.local', 'share', 'pnpm', name)),
|
|
35
|
-
...names.map(name => path.join(home, 'Library', 'pnpm', name)),
|
|
36
|
-
...versionManagerExecutableCandidates(home, names, {
|
|
37
|
-
env,
|
|
38
|
-
platform,
|
|
39
|
-
readdirSync,
|
|
40
|
-
}),
|
|
41
|
-
...(platform === 'win32'
|
|
42
|
-
? []
|
|
43
|
-
: ['/opt/homebrew/bin/ali-skills', '/usr/local/bin/ali-skills', '/usr/bin/ali-skills']),
|
|
44
|
-
...pathCandidates,
|
|
45
|
-
];
|
|
46
|
-
return existingExecutable(candidates, existsSync);
|
|
47
|
-
}
|
|
48
|
-
export const runAliSkillsCli = (executable, args, cwd) => new Promise((resolve, reject) => {
|
|
49
|
-
const launch = resolveSpawnCommand(executable, args);
|
|
50
|
-
const child = spawn(launch.command, launch.args, {
|
|
51
|
-
cwd,
|
|
52
|
-
env: prependNodePath(prependCommandPath(executable)),
|
|
53
|
-
stdio: ['ignore', 'pipe', 'pipe'],
|
|
54
|
-
windowsHide: true,
|
|
55
|
-
});
|
|
56
|
-
let stdout = '';
|
|
57
|
-
let stderr = '';
|
|
58
|
-
let settled = false;
|
|
59
|
-
const append = (current, chunk) => current.length >= MAX_OUTPUT_LENGTH
|
|
60
|
-
? current
|
|
61
|
-
: (current + chunk.toString('utf8')).slice(0, MAX_OUTPUT_LENGTH);
|
|
62
|
-
const finish = (error) => {
|
|
63
|
-
if (settled)
|
|
64
|
-
return;
|
|
65
|
-
settled = true;
|
|
66
|
-
clearTimeout(timer);
|
|
67
|
-
if (error)
|
|
68
|
-
reject(error);
|
|
69
|
-
else
|
|
70
|
-
resolve({ stdout, stderr });
|
|
71
|
-
};
|
|
72
|
-
const timer = setTimeout(() => {
|
|
73
|
-
child.kill('SIGTERM');
|
|
74
|
-
finish(new Error(`Ali Skills command timed out after ${COMMAND_TIMEOUT_MS / 1000}s`));
|
|
75
|
-
}, COMMAND_TIMEOUT_MS);
|
|
76
|
-
child.stdout.on('data', chunk => (stdout = append(stdout, chunk)));
|
|
77
|
-
child.stderr.on('data', chunk => (stderr = append(stderr, chunk)));
|
|
78
|
-
child.once('error', error => finish(error));
|
|
79
|
-
child.once('exit', code => {
|
|
80
|
-
if (code === 0) {
|
|
81
|
-
finish();
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const detail = stripAnsi(stderr || stdout).trim();
|
|
85
|
-
finish(new Error(detail || `Ali Skills command exited with code ${String(code)}`));
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
export function resolveAliSkillsInvocation(options = {}) {
|
|
89
|
-
const env = options.env ?? process.env;
|
|
90
|
-
const executable = resolveAliSkillsExecutable(options);
|
|
91
|
-
if (executable) {
|
|
92
|
-
return {
|
|
93
|
-
command: executable,
|
|
94
|
-
argsPrefix: [],
|
|
95
|
-
env: prependNodePath(prependCommandPath(executable, env)),
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
const processExecPath = options.processExecPath ?? process.execPath;
|
|
99
|
-
const npx = findExecutable('npx', {
|
|
100
|
-
env,
|
|
101
|
-
existsSync: options.existsSync,
|
|
102
|
-
platform: options.platform,
|
|
103
|
-
extraDirectories: [path.dirname(processExecPath)],
|
|
104
|
-
});
|
|
105
|
-
if (!npx)
|
|
106
|
-
return null;
|
|
107
|
-
return {
|
|
108
|
-
command: npx,
|
|
109
|
-
argsPrefix: ['-y', 'ali-skills'],
|
|
110
|
-
env: prependNodePath(prependCommandPath(npx, env), processExecPath),
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
export function parseGlobalMearlSkillPaths(output) {
|
|
114
|
-
const parsed = JSON.parse(stripAnsi(output).trim());
|
|
115
|
-
if (!Array.isArray(parsed))
|
|
116
|
-
throw new Error('Ali Skills returned an invalid skill list');
|
|
117
|
-
return [
|
|
118
|
-
...new Set(parsed.flatMap((skill) => skill.name === 'mearl' &&
|
|
119
|
-
skill.scope === 'global' &&
|
|
120
|
-
typeof skill.path === 'string' &&
|
|
121
|
-
skill.path.trim()
|
|
122
|
-
? [skill.path.trim()]
|
|
123
|
-
: [])),
|
|
124
|
-
];
|
|
125
|
-
}
|
|
126
|
-
export async function runGlobalMearlSkillOperation(operation, options = {}) {
|
|
127
|
-
const runner = options.runCommand ?? runCommand;
|
|
128
|
-
const writeLine = options.writeLine ?? (line => console.error(line));
|
|
129
|
-
const invocation = resolveAliSkillsInvocation(options);
|
|
130
|
-
if (!invocation) {
|
|
131
|
-
writeLine('Skill: ali-skills and npx are both unavailable.');
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
const run = async (args, capture) => {
|
|
135
|
-
try {
|
|
136
|
-
return await runner(invocation.command, [...invocation.argsPrefix, ...args], {
|
|
137
|
-
capture,
|
|
138
|
-
env: invocation.env,
|
|
139
|
-
timeoutMs: COMMAND_TIMEOUT_MS,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
writeLine(`Skill: ${error instanceof Error ? error.message : String(error)}`);
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
const listMearlPaths = async () => {
|
|
148
|
-
const listed = await run(['list', '--global', '--json'], true);
|
|
149
|
-
if (!listed)
|
|
150
|
-
return null;
|
|
151
|
-
if (listed.code !== 0) {
|
|
152
|
-
writeLine(`Skill: unable to list global skills (exit ${listed.code}).`);
|
|
153
|
-
const detail = stripAnsi(listed.stderr || listed.stdout).trim();
|
|
154
|
-
if (detail)
|
|
155
|
-
writeLine(detail);
|
|
156
|
-
return null;
|
|
157
|
-
}
|
|
158
|
-
try {
|
|
159
|
-
return parseGlobalMearlSkillPaths(listed.stdout);
|
|
160
|
-
}
|
|
161
|
-
catch (error) {
|
|
162
|
-
writeLine(`Skill: ${error instanceof Error ? error.message : String(error)}.`);
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
if (operation === 'install') {
|
|
167
|
-
const installed = await run([
|
|
168
|
-
'add',
|
|
169
|
-
'trip/mearl',
|
|
170
|
-
'--skill',
|
|
171
|
-
'mearl',
|
|
172
|
-
'--global',
|
|
173
|
-
'--install-mode',
|
|
174
|
-
'symlink',
|
|
175
|
-
...(options.yes ? ['--yes'] : []),
|
|
176
|
-
], false);
|
|
177
|
-
if (!installed)
|
|
178
|
-
return false;
|
|
179
|
-
if (installed.code !== 0) {
|
|
180
|
-
writeLine(`Skill: install failed (exit ${installed.code}).`);
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
const installedPaths = await listMearlPaths();
|
|
184
|
-
if (!installedPaths || installedPaths.length === 0) {
|
|
185
|
-
writeLine('Skill: installation finished without a tracked global mearl skill.');
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
writeLine('Skill: installed.');
|
|
189
|
-
return true;
|
|
190
|
-
}
|
|
191
|
-
const paths = await listMearlPaths();
|
|
192
|
-
if (!paths)
|
|
193
|
-
return false;
|
|
194
|
-
if (paths.length === 0) {
|
|
195
|
-
writeLine('Skill: no tracked global mearl skill found; skipped.');
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
writeLine('Skill installation:');
|
|
199
|
-
paths.forEach(skillPath => writeLine(` ${skillPath}`));
|
|
200
|
-
const args = operation === 'update'
|
|
201
|
-
? ['update', 'mearl', '--global', '--yes']
|
|
202
|
-
: ['remove', 'mearl', '--global', '--yes'];
|
|
203
|
-
const result = await run(args, false);
|
|
204
|
-
if (!result)
|
|
205
|
-
return false;
|
|
206
|
-
if (result.code !== 0) {
|
|
207
|
-
writeLine(`Skill: ${operation} failed (exit ${result.code}).`);
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
writeLine(`Skill: ${operation === 'update' ? 'updated' : 'uninstalled'}.`);
|
|
211
|
-
return true;
|
|
212
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { findPluginRegistration, listPluginNames, unregisterPlugin } from '@mearl/client/plugin';
|
|
2
|
-
import { resolveAliSkillsInvocation } from './aliSkills.js';
|
|
3
|
-
import { installPlugins } from './plugin.js';
|
|
4
|
-
import { findExecutable, type CommandRunner } from '@mearl/daemon-core';
|
|
5
|
-
export { ALIBABA_NPM_REGISTRY } from './npmRegistry.js';
|
|
6
|
-
export declare const ALIBABA_INTERNAL_PLUGIN_NAMES: string[];
|
|
7
|
-
export interface InternalPluginOptions {
|
|
8
|
-
env?: NodeJS.ProcessEnv;
|
|
9
|
-
includeMearlSkill?: boolean;
|
|
10
|
-
mearlSkillOperation?: 'install' | 'update';
|
|
11
|
-
runCommand?: CommandRunner;
|
|
12
|
-
writeLine?: (line: string) => void;
|
|
13
|
-
}
|
|
14
|
-
export interface InternalPluginDependencies {
|
|
15
|
-
findExecutable?: typeof findExecutable;
|
|
16
|
-
findPluginRegistration?: typeof findPluginRegistration;
|
|
17
|
-
installPlugins?: typeof installPlugins;
|
|
18
|
-
listPluginNames?: typeof listPluginNames;
|
|
19
|
-
probeAlibabaRegistry?: (options: InternalPluginOptions) => Promise<boolean>;
|
|
20
|
-
resolveAliSkillsInvocation?: typeof resolveAliSkillsInvocation;
|
|
21
|
-
unregisterPlugin?: typeof unregisterPlugin;
|
|
22
|
-
}
|
|
23
|
-
export declare function canAccessAlibabaNpmRegistry(options?: InternalPluginOptions, dependencies?: Pick<InternalPluginDependencies, 'findExecutable'>): Promise<boolean>;
|
|
24
|
-
/** Uses the internal registry only as an intranet probe; Ali Skills installs the plugins. */
|
|
25
|
-
export declare function installAlibabaInternalPlugins(options?: InternalPluginOptions, dependencies?: InternalPluginDependencies): Promise<'installed' | 'skipped' | 'failed'>;
|
|
26
|
-
export declare function uninstallAlibabaInternalPlugins(options?: InternalPluginOptions, dependencies?: InternalPluginDependencies): Promise<'uninstalled' | 'skipped' | 'failed'>;
|
package/dist/internalPlugins.js
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { dirname } from 'node:path';
|
|
2
|
-
import { findOfficialPlugin, findPluginRegistration, listPluginNames, listOfficialPluginNames, OFFICIAL_PLUGIN_MANAGER, unregisterPlugin, } from '@mearl/client/plugin';
|
|
3
|
-
import { resolveAliSkillsInvocation } from './aliSkills.js';
|
|
4
|
-
import { ALIBABA_NPM_REGISTRY } from './npmRegistry.js';
|
|
5
|
-
import { installPlugins } from './plugin.js';
|
|
6
|
-
import { findExecutable, prependCommandPath, runCommand, } from '@mearl/daemon-core';
|
|
7
|
-
export { ALIBABA_NPM_REGISTRY } from './npmRegistry.js';
|
|
8
|
-
export const ALIBABA_INTERNAL_PLUGIN_NAMES = listOfficialPluginNames('alibaba');
|
|
9
|
-
export async function canAccessAlibabaNpmRegistry(options = {}, dependencies = {}) {
|
|
10
|
-
const env = options.env ?? process.env;
|
|
11
|
-
const runner = options.runCommand ?? runCommand;
|
|
12
|
-
const npm = (dependencies.findExecutable ?? findExecutable)('npm', {
|
|
13
|
-
env,
|
|
14
|
-
extraDirectories: [dirname(process.execPath)],
|
|
15
|
-
});
|
|
16
|
-
if (!npm)
|
|
17
|
-
return false;
|
|
18
|
-
try {
|
|
19
|
-
const result = await runner(npm, [
|
|
20
|
-
'ping',
|
|
21
|
-
`--registry=${ALIBABA_NPM_REGISTRY}`,
|
|
22
|
-
'--fetch-retries=0',
|
|
23
|
-
'--fetch-timeout=3000',
|
|
24
|
-
'--loglevel=silent',
|
|
25
|
-
], {
|
|
26
|
-
capture: true,
|
|
27
|
-
env: prependCommandPath(npm, env),
|
|
28
|
-
timeoutMs: 5_000,
|
|
29
|
-
});
|
|
30
|
-
return result.code === 0;
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/** Uses the internal registry only as an intranet probe; Ali Skills installs the plugins. */
|
|
37
|
-
export async function installAlibabaInternalPlugins(options = {}, dependencies = {}) {
|
|
38
|
-
const writeLine = options.writeLine ?? (line => console.error(line));
|
|
39
|
-
const registrationFor = dependencies.findPluginRegistration ?? findPluginRegistration;
|
|
40
|
-
const missingRegistrations = new Set();
|
|
41
|
-
const candidates = ALIBABA_INTERNAL_PLUGIN_NAMES.filter(name => {
|
|
42
|
-
const registration = registrationFor(name);
|
|
43
|
-
if (registration && registration.managedBy !== OFFICIAL_PLUGIN_MANAGER) {
|
|
44
|
-
writeLine(`${name} plugin: existing user registration kept.`);
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
if (!registration)
|
|
48
|
-
missingRegistrations.add(name);
|
|
49
|
-
return true;
|
|
50
|
-
});
|
|
51
|
-
if (candidates.length === 0)
|
|
52
|
-
return 'skipped';
|
|
53
|
-
const probe = dependencies.probeAlibabaRegistry ?? (input => canAccessAlibabaNpmRegistry(input));
|
|
54
|
-
if (!(await probe(options)))
|
|
55
|
-
return 'skipped';
|
|
56
|
-
if (options.mearlSkillOperation === 'update') {
|
|
57
|
-
const registeredCandidates = candidates.filter(name => !missingRegistrations.has(name));
|
|
58
|
-
const missingCandidates = candidates.filter(name => missingRegistrations.has(name));
|
|
59
|
-
const updateSkillNames = [
|
|
60
|
-
...(options.includeMearlSkill ? ['mearl'] : []),
|
|
61
|
-
...registeredCandidates.map(name => findOfficialPlugin(name).skill),
|
|
62
|
-
];
|
|
63
|
-
if (updateSkillNames.length > 0) {
|
|
64
|
-
const invocation = (dependencies.resolveAliSkillsInvocation ?? resolveAliSkillsInvocation)({
|
|
65
|
-
env: options.env,
|
|
66
|
-
});
|
|
67
|
-
if (!invocation) {
|
|
68
|
-
writeLine('Internal skill batch: ali-skills and npx are both unavailable; update failed.');
|
|
69
|
-
return 'failed';
|
|
70
|
-
}
|
|
71
|
-
try {
|
|
72
|
-
const updated = await (options.runCommand ?? runCommand)(invocation.command, [...invocation.argsPrefix, 'update', ...updateSkillNames, '--global', '--yes'], { env: invocation.env, tee: true });
|
|
73
|
-
if (updated.code !== 0) {
|
|
74
|
-
writeLine(`Internal skill batch: update failed (exit ${updated.code}).`);
|
|
75
|
-
return 'failed';
|
|
76
|
-
}
|
|
77
|
-
if (options.includeMearlSkill)
|
|
78
|
-
writeLine('Skill: updated.');
|
|
79
|
-
for (const name of registeredCandidates)
|
|
80
|
-
writeLine(`${name} plugin: updated.`);
|
|
81
|
-
}
|
|
82
|
-
catch (error) {
|
|
83
|
-
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; update failed.`);
|
|
84
|
-
return 'failed';
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (missingCandidates.length > 0) {
|
|
88
|
-
const repairArgs = [
|
|
89
|
-
'trip/mearl',
|
|
90
|
-
'--skill',
|
|
91
|
-
...missingCandidates.map(name => findOfficialPlugin(name).skill),
|
|
92
|
-
'--yes',
|
|
93
|
-
];
|
|
94
|
-
try {
|
|
95
|
-
const code = await (dependencies.installPlugins ?? installPlugins)(repairArgs, options.runCommand, { registrationManagedBy: OFFICIAL_PLUGIN_MANAGER });
|
|
96
|
-
if (code !== 0) {
|
|
97
|
-
writeLine(`Internal skill batch: registration repair failed (exit ${code}).`);
|
|
98
|
-
return 'failed';
|
|
99
|
-
}
|
|
100
|
-
for (const name of missingCandidates) {
|
|
101
|
-
writeLine(`${name} plugin: installed and registered.`);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; registration repair failed.`);
|
|
106
|
-
return 'failed';
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return 'installed';
|
|
110
|
-
}
|
|
111
|
-
const skillNames = [
|
|
112
|
-
...(options.includeMearlSkill ? ['mearl'] : []),
|
|
113
|
-
...candidates.map(name => findOfficialPlugin(name).skill),
|
|
114
|
-
];
|
|
115
|
-
const args = ['trip/mearl', '--skill', ...skillNames, '--yes'];
|
|
116
|
-
try {
|
|
117
|
-
const code = await (dependencies.installPlugins ?? installPlugins)(args, options.runCommand, {
|
|
118
|
-
registrationManagedBy: OFFICIAL_PLUGIN_MANAGER,
|
|
119
|
-
});
|
|
120
|
-
if (code !== 0) {
|
|
121
|
-
writeLine(`Internal skill batch: install failed (exit ${code}).`);
|
|
122
|
-
return 'failed';
|
|
123
|
-
}
|
|
124
|
-
if (options.includeMearlSkill)
|
|
125
|
-
writeLine('Skill: installed.');
|
|
126
|
-
for (const name of candidates)
|
|
127
|
-
writeLine(`${name} plugin: installed and registered.`);
|
|
128
|
-
return 'installed';
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; install failed.`);
|
|
132
|
-
return 'failed';
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
export async function uninstallAlibabaInternalPlugins(options = {}, dependencies = {}) {
|
|
136
|
-
const writeLine = options.writeLine ?? (line => console.error(line));
|
|
137
|
-
const registrationFor = dependencies.findPluginRegistration ?? findPluginRegistration;
|
|
138
|
-
const removedSkillDirectories = new Set();
|
|
139
|
-
const candidates = listOfficialPluginNames().filter(name => {
|
|
140
|
-
const registration = registrationFor(name);
|
|
141
|
-
if (!registration)
|
|
142
|
-
return false;
|
|
143
|
-
if (registration.managedBy !== OFFICIAL_PLUGIN_MANAGER) {
|
|
144
|
-
writeLine(`${name} plugin: existing user registration kept.`);
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
removedSkillDirectories.add(dirname(dirname(registration.entry)));
|
|
148
|
-
return true;
|
|
149
|
-
});
|
|
150
|
-
const skillNames = [
|
|
151
|
-
...(options.includeMearlSkill ? ['mearl'] : []),
|
|
152
|
-
...candidates.map(name => findOfficialPlugin(name).skill),
|
|
153
|
-
];
|
|
154
|
-
if (skillNames.length === 0)
|
|
155
|
-
return 'skipped';
|
|
156
|
-
const invocation = (dependencies.resolveAliSkillsInvocation ?? resolveAliSkillsInvocation)({
|
|
157
|
-
env: options.env,
|
|
158
|
-
});
|
|
159
|
-
if (!invocation) {
|
|
160
|
-
writeLine('Internal skill batch: ali-skills and npx are both unavailable; uninstall failed.');
|
|
161
|
-
return 'failed';
|
|
162
|
-
}
|
|
163
|
-
const runner = options.runCommand ?? runCommand;
|
|
164
|
-
let removed;
|
|
165
|
-
try {
|
|
166
|
-
removed = await runner(invocation.command, [...invocation.argsPrefix, 'remove', ...skillNames, '--global', '--yes'], { env: invocation.env, tee: true });
|
|
167
|
-
}
|
|
168
|
-
catch (error) {
|
|
169
|
-
writeLine(`Internal skill batch: ${error instanceof Error ? error.message : String(error)}; uninstall failed.`);
|
|
170
|
-
return 'failed';
|
|
171
|
-
}
|
|
172
|
-
if (removed.code !== 0) {
|
|
173
|
-
writeLine(`Internal skill batch: uninstall failed (exit ${removed.code}).`);
|
|
174
|
-
return 'failed';
|
|
175
|
-
}
|
|
176
|
-
const unregister = dependencies.unregisterPlugin ?? unregisterPlugin;
|
|
177
|
-
const registrationsToRemove = new Set(candidates);
|
|
178
|
-
for (const name of (dependencies.listPluginNames ?? listPluginNames)()) {
|
|
179
|
-
try {
|
|
180
|
-
const registration = registrationFor(name);
|
|
181
|
-
if (registration && removedSkillDirectories.has(dirname(dirname(registration.entry)))) {
|
|
182
|
-
registrationsToRemove.add(name);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
catch {
|
|
186
|
-
// 无法读取的注册不影响已确认 Skill 的卸载和其他有效注册清理。
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
for (const name of [...registrationsToRemove].sort())
|
|
190
|
-
unregister(name);
|
|
191
|
-
for (const name of candidates) {
|
|
192
|
-
writeLine(`${name} plugin: uninstalled.`);
|
|
193
|
-
}
|
|
194
|
-
if (options.includeMearlSkill)
|
|
195
|
-
writeLine('Skill: uninstalled.');
|
|
196
|
-
return 'uninstalled';
|
|
197
|
-
}
|