@mearl/setup 3.0.0-beta.0 → 3.0.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.
- package/README.md +2 -2
- package/dist/plugin.js +1 -1
- package/dist/preset.js +1 -1
- package/dist/skillSources.d.ts +3 -0
- package/dist/skillSources.js +32 -3
- package/package.json +11 -6
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ npx @mearl/setup@beta provider <install|update|uninstall> <package|id>
|
|
|
28
28
|
一个命令安装 skill 并注册它的 CLI、SDK 和 MCP 能力:
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
|
-
npx @mearl/setup@beta plugin install https://github.com/F-loat/mearl/tree/v3.0.0-beta.
|
|
31
|
+
npx @mearl/setup@beta plugin install https://github.com/F-loat/mearl/tree/v3.0.0-beta.1 --skill browser-tab-manager --yes
|
|
32
32
|
mearl tabs summary
|
|
33
33
|
```
|
|
34
34
|
|
|
@@ -121,7 +121,7 @@ npx @mearl/setup@beta provider uninstall example-device
|
|
|
121
121
|
CDP 标签 ID 计数也保留,防止旧请求命中新标签。
|
|
122
122
|
- `--mcp` 的客户端配置和清理由 `@mearl/mcp-server` 自己的命令完成。
|
|
123
123
|
- 默认的 `install` / `update` 不处理浏览器扩展。`extension` 是独立命令:从
|
|
124
|
-
`https://github.com/F-loat/mearl/releases/download/v3.0.0-beta.
|
|
124
|
+
`https://github.com/F-loat/mearl/releases/download/v3.0.0-beta.1/` 读取同版本 beta 扩展发行元数据(正式 setup 使用 `releases/latest/download/`)并下载对应的 `mearl-chrome-v*.zip`,原子解压到
|
|
125
125
|
`~/.mearl/chrome-extension`。首次安装通过浏览器级 CDP 的 `Extensions.loadUnpacked`
|
|
126
126
|
加载;后续更新由 `mearl check --local --json` 确认当前扩展仍来自 setup 管理目录后,直接替换
|
|
127
127
|
文件并通过 Native Host 触发扩展 reload。固定目录和 manifest 中的 `key` 保证扩展 ID
|
package/dist/plugin.js
CHANGED
|
@@ -111,7 +111,7 @@ function globalSkill(entry) {
|
|
|
111
111
|
return undefined;
|
|
112
112
|
}
|
|
113
113
|
function projectSkill(entry, managedBy) {
|
|
114
|
-
if (managedBy
|
|
114
|
+
if (!managedBy)
|
|
115
115
|
return undefined;
|
|
116
116
|
const absolute = resolve(entry);
|
|
117
117
|
const marker = `${sep}.agents${sep}skills${sep}`;
|
package/dist/preset.js
CHANGED
|
@@ -95,7 +95,7 @@ export class PresetInstaller {
|
|
|
95
95
|
const result = await this.invokeHost(reload ? 'preset_browser_sync' : 'preset_browser_status', reload ? { installationRevision } : {}, target, reload ? 130 : 15, reload);
|
|
96
96
|
if (result?.accepted === false)
|
|
97
97
|
return { id: target.id, state: 'rejected', settingsReady: false, error: typeof result.error === 'string' ? result.error : 'Browser preset activation rejected' };
|
|
98
|
-
return { id: target.id, state: result?.ready === true && result?.browserRevision === browserRevision && result?.installationRevision === installationRevision ? 'active' : 'pending', settingsReady: result?.settingsReady === true };
|
|
98
|
+
return { id: target.id, state: result?.ready === true && result?.browserRevision === browserRevision && result?.installationRevision === installationRevision ? 'active' : 'pending', settingsReady: result?.settingsReady === true, ...(Array.isArray(result?.permissionPending) && result.permissionPending.length ? { error: 'PRESET_DOMAIN_PERMISSION_REQUIRED: Open extension settings and authorize preset domains' } : {}) };
|
|
99
99
|
}
|
|
100
100
|
catch {
|
|
101
101
|
return { id: target.id, state: 'pending', settingsReady: false, error: 'BROWSER_UNAVAILABLE' };
|
package/dist/skillSources.d.ts
CHANGED
|
@@ -34,8 +34,11 @@ export interface SkillInstallationStatus {
|
|
|
34
34
|
state: 'ready' | 'missing' | 'version' | 'registration' | 'conflict';
|
|
35
35
|
reason?: string;
|
|
36
36
|
}
|
|
37
|
+
/** Developer links keep their Git checkout as the source receipt without changing a manager's lock. */
|
|
38
|
+
export declare function readLinkedSkillSource(directory: string, name: string): TrackedSkillSource | undefined;
|
|
37
39
|
/** CLI and Agent readiness use the same source, manifest and registration evidence. */
|
|
38
40
|
export declare function inspectGlobalSkill(source: string, name: string, version?: string, options?: {
|
|
41
|
+
homeDirectory?: string;
|
|
39
42
|
readSources?: typeof readTrackedSkillSources;
|
|
40
43
|
externalManager?: boolean;
|
|
41
44
|
normalizeSource?: (source: string, sourceType?: string) => string;
|
package/dist/skillSources.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { mkdtemp, readFile, readdir, realpath, rm, stat } from 'node:fs/promises';
|
|
3
|
-
import { readFileSync, statSync } from 'node:fs';
|
|
3
|
+
import { readFileSync, statSync, lstatSync, realpathSync } from 'node:fs';
|
|
4
|
+
import { execFileSync } from 'node:child_process';
|
|
4
5
|
import { homedir, tmpdir } from 'node:os';
|
|
5
6
|
import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
6
7
|
import { fileURLToPath } from 'node:url';
|
|
@@ -209,14 +210,42 @@ export async function checkTrackedSkillUpdates(options = {}) {
|
|
|
209
210
|
await rm(temporary, { recursive: true, force: true });
|
|
210
211
|
}
|
|
211
212
|
}
|
|
213
|
+
/** Developer links keep their Git checkout as the source receipt without changing a manager's lock. */
|
|
214
|
+
export function readLinkedSkillSource(directory, name) {
|
|
215
|
+
try {
|
|
216
|
+
if (!lstatSync(directory).isSymbolicLink())
|
|
217
|
+
return undefined;
|
|
218
|
+
const actual = realpathSync(directory);
|
|
219
|
+
const git = (...args) => execFileSync('git', ['--no-optional-locks', '-c', 'core.fsmonitor=false', '-C', actual, ...args], {
|
|
220
|
+
encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], timeout: 2_000, maxBuffer: 16_384,
|
|
221
|
+
}).trim();
|
|
222
|
+
const root = git('rev-parse', '--show-toplevel');
|
|
223
|
+
const folder = relative(root, actual);
|
|
224
|
+
if (folder === '..' || folder.startsWith('..' + sep) || isAbsolute(folder))
|
|
225
|
+
return undefined;
|
|
226
|
+
const skillPath = (folder ? folder.split(sep).join('/') + '/' : '') + 'SKILL.md';
|
|
227
|
+
if (git('ls-files', '--full-name', '--error-unmatch', '--', 'SKILL.md') !== skillPath)
|
|
228
|
+
return undefined;
|
|
229
|
+
const source = git('config', '--get', 'remote.origin.url');
|
|
230
|
+
if (!source || source.length > 4096 || /[\0\r\n]/.test(source))
|
|
231
|
+
return undefined;
|
|
232
|
+
if (!isAbsolute(source))
|
|
233
|
+
gitSource(source);
|
|
234
|
+
return { name, source, scope: 'global', skillPath, sourceType: 'git', hashKind: 'folder' };
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
212
240
|
/** CLI and Agent readiness use the same source, manifest and registration evidence. */
|
|
213
241
|
export function inspectGlobalSkill(source, name, version, options = {}) {
|
|
214
242
|
if (!source.trim() || !name || name === '.' || name === '..' || /[\\/\0\r\n]/.test(name))
|
|
215
243
|
throw new Error('Invalid Skill identity');
|
|
216
|
-
const directory = join(homedir(), '.agents', 'skills', name);
|
|
244
|
+
const directory = join(options.homeDirectory ?? homedir(), '.agents', 'skills', name);
|
|
217
245
|
if (existsSync(join(directory, 'SKILL.md')) && existsSync(join(directory, DISABLED_SKILL_MANIFEST)))
|
|
218
246
|
return { state: 'conflict', reason: 'SKILL_MANIFEST_CONFLICT' };
|
|
219
|
-
const tracked = (options.readSources ?? readTrackedSkillSources)('global').find(entry => entry.name === name)
|
|
247
|
+
const tracked = (options.readSources ?? readTrackedSkillSources)('global', undefined, { homeDirectory: options.homeDirectory }).find(entry => entry.name === name)
|
|
248
|
+
?? (!/(?:#|\/(?:tree|blob)\/)/.test(source) ? readLinkedSkillSource(directory, name) : undefined);
|
|
220
249
|
if (tracked && ((!options.externalManager && !isPublicSkillSource(tracked)) || !matchesTrackedSkillSource(source, tracked, options.normalizeSource)))
|
|
221
250
|
return { state: 'conflict', reason: 'SKILL_SOURCE_CONFLICT' };
|
|
222
251
|
const metadata = readInstalledSkillMetadata(directory);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/setup",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.1",
|
|
4
4
|
"description": "One-shot environment setup and configuration for Mearl",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
"extract-zip": "^2.0.1",
|
|
75
75
|
"ws": "^8.18.3",
|
|
76
76
|
"semver": "^7.8.5",
|
|
77
|
-
"@mearl/
|
|
78
|
-
"@mearl/
|
|
79
|
-
"@mearl/
|
|
80
|
-
"@mearl/
|
|
81
|
-
"@mearl/browser-core": "3.0.0-beta.
|
|
77
|
+
"@mearl/preset": "3.0.0-beta.1",
|
|
78
|
+
"@mearl/daemon-core": "3.0.0-beta.1",
|
|
79
|
+
"@mearl/client": "3.0.0-beta.1",
|
|
80
|
+
"@mearl/provider": "3.0.0-beta.1",
|
|
81
|
+
"@mearl/browser-core": "3.0.0-beta.1"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@types/node": "^24.9.1",
|
|
@@ -86,6 +86,11 @@
|
|
|
86
86
|
"typescript": "^5.8.3",
|
|
87
87
|
"@types/semver": "^7.7.1"
|
|
88
88
|
},
|
|
89
|
+
"repository": {
|
|
90
|
+
"type": "git",
|
|
91
|
+
"url": "git+https://github.com/F-loat/mearl.git",
|
|
92
|
+
"directory": "packages/setup"
|
|
93
|
+
},
|
|
89
94
|
"scripts": {
|
|
90
95
|
"build": "rm -rf dist/ && tsc && chmod +x dist/bin.js",
|
|
91
96
|
"dev": "tsc --watch",
|