@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 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.0 --skill browser-tab-manager --yes
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.0/` 读取同版本 beta 扩展发行元数据(正式 setup 使用 `releases/latest/download/`)并下载对应的 `mearl-chrome-v*.zip`,原子解压到
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 !== 'skills' && managedBy !== 'ali-skills')
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' };
@@ -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;
@@ -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.0",
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/client": "3.0.0-beta.0",
78
- "@mearl/provider": "3.0.0-beta.0",
79
- "@mearl/daemon-core": "3.0.0-beta.0",
80
- "@mearl/preset": "3.0.0-beta.0",
81
- "@mearl/browser-core": "3.0.0-beta.0"
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",