@mearl/setup 2.6.0 → 2.7.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/README.md +9 -3
- package/dist/aliSkills.js +3 -8
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +3 -0
- package/dist/cli.d.ts +3 -1
- package/dist/cli.js +31 -9
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/lifecycle.js +1 -1
- package/dist/qoder.d.ts +18 -0
- package/dist/qoder.js +32 -0
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -17,6 +17,10 @@ npx @mearl/setup agentbay
|
|
|
17
17
|
无交互环境可使用 `--stdin` 或 `--key-file <path>`。为避免 Key 进入 shell history 和
|
|
18
18
|
进程参数,不接受把 Key 直接写在命令行中。
|
|
19
19
|
|
|
20
|
+
Qoder Cloud Agent 仅在常规云连接失败、Mearl Skill 进入 Qoder 异常接管分支时使用
|
|
21
|
+
`npx @mearl/setup qoder --yes` 生成一次性配对指令。它不安装额外隧道,也不会把 Qoder
|
|
22
|
+
PAT 写入配对 URL;正常安装和连接流程无需执行该命令。
|
|
23
|
+
|
|
20
24
|
## 行为
|
|
21
25
|
|
|
22
26
|
- `install` 可以省略;直接执行 `npx @mearl/setup` 等同于 `npx @mearl/setup install`。
|
|
@@ -33,6 +37,8 @@ npx @mearl/setup agentbay
|
|
|
33
37
|
- local/cloud 共用一份 `@mearl/client`;组合安装只处理一次,卸载单个环境时若另一个环境仍在使用则保留。
|
|
34
38
|
- 从 2.5.x 更新 cloud 环境时会先卸载旧 `@mearl/cloud-client`,避免它遗留的 `mearl` bin 与统一 client 冲突。
|
|
35
39
|
- local/cloud 共用的全局 mearl skill 通过 `ali-skills` 的 JSON 清单定位,只处理一次。
|
|
40
|
+
- 安装始终通过 `ali-skills add` 写入最新的全局 mearl skill,并关联当前检测到的 Agent;
|
|
41
|
+
可用 `--skip-skill` 跳过。
|
|
36
42
|
- 卸载一个环境但另一个仍依赖全局 mearl skill 时会保留 skill。
|
|
37
43
|
- `--mcp` 的客户端配置和清理由 `@mearl/mcp-server` 自己的命令完成。
|
|
38
44
|
|
|
@@ -67,13 +73,13 @@ npx @mearl/setup
|
|
|
67
73
|
npx @mearl/setup install
|
|
68
74
|
|
|
69
75
|
# Agent / CI 无交互安装
|
|
70
|
-
npx @mearl/setup
|
|
76
|
+
npx @mearl/setup --yes
|
|
71
77
|
|
|
72
78
|
# 安装云端 Agent 环境
|
|
73
|
-
npx @mearl/setup
|
|
79
|
+
npx @mearl/setup --cloud
|
|
74
80
|
|
|
75
81
|
# 同一台机器同时作为本地浏览器宿主和云端 Agent
|
|
76
|
-
npx @mearl/setup
|
|
82
|
+
npx @mearl/setup --local --cloud
|
|
77
83
|
|
|
78
84
|
# 自动更新当前 PATH 中检测到的全部 Mearl 环境
|
|
79
85
|
npx @mearl/setup update
|
package/dist/aliSkills.js
CHANGED
|
@@ -163,15 +163,7 @@ export async function runGlobalMearlSkillOperation(operation, options = {}) {
|
|
|
163
163
|
return null;
|
|
164
164
|
}
|
|
165
165
|
};
|
|
166
|
-
const paths = await listMearlPaths();
|
|
167
|
-
if (!paths)
|
|
168
|
-
return false;
|
|
169
166
|
if (operation === 'install') {
|
|
170
|
-
if (paths.length > 0) {
|
|
171
|
-
writeLine('Skill: already installed:');
|
|
172
|
-
paths.forEach(skillPath => writeLine(` ${skillPath}`));
|
|
173
|
-
return true;
|
|
174
|
-
}
|
|
175
167
|
const installed = await run(['add', 'trip/mearl', '--skill', 'mearl', '--global', ...(options.yes ? ['--yes'] : [])], false);
|
|
176
168
|
if (!installed)
|
|
177
169
|
return false;
|
|
@@ -187,6 +179,9 @@ export async function runGlobalMearlSkillOperation(operation, options = {}) {
|
|
|
187
179
|
writeLine('Skill: installed.');
|
|
188
180
|
return true;
|
|
189
181
|
}
|
|
182
|
+
const paths = await listMearlPaths();
|
|
183
|
+
if (!paths)
|
|
184
|
+
return false;
|
|
190
185
|
if (paths.length === 0) {
|
|
191
186
|
writeLine('Skill: no tracked global mearl skill found; skipped.');
|
|
192
187
|
return true;
|
package/dist/bin.d.ts
ADDED
package/dist/bin.js
ADDED
package/dist/cli.d.ts
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
import { configureAgentBayApiKey, promptAgentBayApiKey, readAgentBayApiKeyFile, readAgentBayApiKeyStdin } from './agentBay.js';
|
|
3
3
|
import { type MearlLifecycleOperation } from './lifecycle.js';
|
|
4
4
|
import type { MearlProfile } from './profiles.js';
|
|
5
|
+
import { createQoderPairingInfo } from './qoder.js';
|
|
5
6
|
export declare const SETUP_VERSION: string;
|
|
6
7
|
interface ParsedArgs {
|
|
7
8
|
agentBayKeyFile?: string;
|
|
8
9
|
agentBayReadStdin: boolean;
|
|
9
10
|
help: boolean;
|
|
10
|
-
operation?: MearlLifecycleOperation | 'agentbay';
|
|
11
|
+
operation?: MearlLifecycleOperation | 'agentbay' | 'qoder';
|
|
11
12
|
profiles?: MearlProfile[];
|
|
12
13
|
skipSkill: boolean;
|
|
13
14
|
targetLine?: string;
|
|
@@ -19,6 +20,7 @@ export interface SetupCliDependencies {
|
|
|
19
20
|
promptAgentBayKey?: typeof promptAgentBayApiKey;
|
|
20
21
|
readAgentBayKeyFile?: typeof readAgentBayApiKeyFile;
|
|
21
22
|
readAgentBayKeyStdin?: typeof readAgentBayApiKeyStdin;
|
|
23
|
+
createQoderPairing?: typeof createQoderPairingInfo;
|
|
22
24
|
}
|
|
23
25
|
export declare function parseSetupArgs(argv: string[]): ParsedArgs;
|
|
24
26
|
export declare function main(argv?: string[], interactiveTerminal?: boolean, dependencies?: SetupCliDependencies): Promise<number>;
|
package/dist/cli.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import path from 'node:path';
|
|
3
2
|
import { createRequire } from 'node:module';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
3
|
import { configureAgentBayApiKey, promptAgentBayApiKey, readAgentBayApiKeyFile, readAgentBayApiKeyStdin, } from './agentBay.js';
|
|
6
4
|
import { runMearlLifecycle } from './lifecycle.js';
|
|
5
|
+
import { createQoderPairingInfo, formatQoderPairingOutput } from './qoder.js';
|
|
7
6
|
import { isMearlReleaseLine } from './version.js';
|
|
8
7
|
const require = createRequire(import.meta.url);
|
|
9
8
|
export const SETUP_VERSION = require('../package.json').version;
|
|
@@ -54,6 +53,20 @@ export function parseSetupArgs(argv) {
|
|
|
54
53
|
}
|
|
55
54
|
throw new Error('Usage: npx @mearl/setup agentbay [--stdin | --key-file <path>]. API keys are not accepted as command-line arguments.');
|
|
56
55
|
}
|
|
56
|
+
if (operation === 'qoder') {
|
|
57
|
+
const options = argv.slice(1);
|
|
58
|
+
const allowed = new Set(['--yes', '-y', '--non-interactive']);
|
|
59
|
+
if (options.some(option => !allowed.has(option))) {
|
|
60
|
+
throw new Error('Usage: npx @mearl/setup qoder [--yes]');
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
agentBayReadStdin: false,
|
|
64
|
+
help: false,
|
|
65
|
+
operation,
|
|
66
|
+
skipSkill: false,
|
|
67
|
+
yes: options.length > 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
57
70
|
if (operation !== 'install' && operation !== 'update' && operation !== 'uninstall') {
|
|
58
71
|
throw new Error(`Unknown operation: ${operation}`);
|
|
59
72
|
}
|
|
@@ -112,12 +125,14 @@ Usage:
|
|
|
112
125
|
npx @mearl/setup [install] [--local] [--cloud] [--mcp] [--yes]
|
|
113
126
|
npx @mearl/setup <update|uninstall> [--local] [--cloud] [--mcp] [--yes]
|
|
114
127
|
npx @mearl/setup agentbay [--stdin | --key-file <path>]
|
|
128
|
+
npx @mearl/setup qoder [--yes]
|
|
115
129
|
|
|
116
130
|
Behavior:
|
|
117
131
|
install Default command; defaults to --local when no environment is specified
|
|
118
132
|
update Auto-detects installed environments from the current PATH
|
|
119
133
|
uninstall Auto-detects installed environments and asks for confirmation
|
|
120
134
|
agentbay Save or update AGENTBAY_KEY without changing other Mearl settings
|
|
135
|
+
qoder Create a Qoder client-side tool pairing request for troubleshooting
|
|
121
136
|
|
|
122
137
|
Options:
|
|
123
138
|
--local Manage @mearl/native-host and @mearl/client
|
|
@@ -139,11 +154,11 @@ Examples:
|
|
|
139
154
|
npx @mearl/setup
|
|
140
155
|
npx @mearl/setup --yes
|
|
141
156
|
npx @mearl/setup install
|
|
142
|
-
npx @mearl/setup
|
|
143
|
-
npx @mearl/setup
|
|
144
|
-
npx @mearl/setup install --local --cloud
|
|
157
|
+
npx @mearl/setup --cloud
|
|
158
|
+
npx @mearl/setup --local --cloud
|
|
145
159
|
npx @mearl/setup update
|
|
146
160
|
npx @mearl/setup agentbay
|
|
161
|
+
npx @mearl/setup qoder --yes
|
|
147
162
|
npx @mearl/setup update --local --target-line 2.3.x --skip-skill
|
|
148
163
|
npx @mearl/setup uninstall --local`;
|
|
149
164
|
if (toError)
|
|
@@ -194,6 +209,17 @@ export async function main(argv = process.argv.slice(2), interactiveTerminal = p
|
|
|
194
209
|
return 1;
|
|
195
210
|
}
|
|
196
211
|
}
|
|
212
|
+
if (parsed.operation === 'qoder') {
|
|
213
|
+
try {
|
|
214
|
+
const pairing = (dependencies.createQoderPairing ?? createQoderPairingInfo)();
|
|
215
|
+
console.log(formatQoderPairingOutput(pairing));
|
|
216
|
+
return 0;
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
220
|
+
return 1;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
197
223
|
if (!interactiveTerminal && !parsed.yes && parsed.operation !== 'update') {
|
|
198
224
|
console.error('Non-interactive input detected. Re-run with --yes or --non-interactive.');
|
|
199
225
|
return 2;
|
|
@@ -213,7 +239,3 @@ export async function main(argv = process.argv.slice(2), interactiveTerminal = p
|
|
|
213
239
|
return 1;
|
|
214
240
|
}
|
|
215
241
|
}
|
|
216
|
-
const currentFile = fileURLToPath(import.meta.url);
|
|
217
|
-
if (process.argv[1] && path.resolve(process.argv[1]) === currentFile) {
|
|
218
|
-
process.exitCode = await main();
|
|
219
|
-
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { buildGlobalPackageCommand, detectGlobalPackage, resolveInvokingPackageManager, resolvePackageManagerInstallation, } from './packageManager.js';
|
|
2
2
|
export { configureAgentBayApiKey, promptAgentBayApiKey, readAgentBayApiKeyFile, readAgentBayApiKeyStdin, } from './agentBay.js';
|
|
3
3
|
export type { AgentBayConfigurationOptions, AgentBayConfigurationResult, AgentBaySecretInput, AgentBaySecretOutput, } from './agentBay.js';
|
|
4
|
+
export { createQoderPairingInfo, formatQoderPairingOutput } from './qoder.js';
|
|
5
|
+
export type { QoderPairingInfo, QoderPairingOptions } from './qoder.js';
|
|
4
6
|
export type { DetectedGlobalPackage, GlobalPackageCommand, GlobalPackageManager, PackageManagerInstallation, PackageOperation, PackageDetectionOptions, } from './packageManager.js';
|
|
5
7
|
export { runMearlLifecycle } from './lifecycle.js';
|
|
6
8
|
export type { MearlLifecycleDependencies, MearlLifecycleOperation, MearlLifecycleOptions, } from './lifecycle.js';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { buildGlobalPackageCommand, detectGlobalPackage, resolveInvokingPackageManager, resolvePackageManagerInstallation, } from './packageManager.js';
|
|
2
2
|
export { configureAgentBayApiKey, promptAgentBayApiKey, readAgentBayApiKeyFile, readAgentBayApiKeyStdin, } from './agentBay.js';
|
|
3
|
+
export { createQoderPairingInfo, formatQoderPairingOutput } from './qoder.js';
|
|
3
4
|
export { runMearlLifecycle } from './lifecycle.js';
|
|
4
5
|
export { MEARL_PROFILES, detectMearlProfiles } from './profiles.js';
|
|
5
6
|
export { MEARL_NATIVE_HOST_NAMES, resolveNativeHostDirectory, uninstallNativeHostArtifacts, } from './nativeHost.js';
|
package/dist/lifecycle.js
CHANGED
|
@@ -150,7 +150,7 @@ export async function runMearlLifecycle(options, dependencies = {}) {
|
|
|
150
150
|
writeLine('No installed Mearl environment was detected on the current PATH.');
|
|
151
151
|
if (options.operation === 'uninstall')
|
|
152
152
|
return true;
|
|
153
|
-
writeLine('Run: npx @mearl/setup
|
|
153
|
+
writeLine('Run: npx @mearl/setup');
|
|
154
154
|
return false;
|
|
155
155
|
}
|
|
156
156
|
if (options.operation === 'update') {
|
package/dist/qoder.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface QoderPairingInfo {
|
|
2
|
+
pairingCode: string;
|
|
3
|
+
createdAt: number;
|
|
4
|
+
connectorUrl: string;
|
|
5
|
+
toolInput: {
|
|
6
|
+
action: 'pair';
|
|
7
|
+
payload: {
|
|
8
|
+
code: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export interface QoderPairingOptions {
|
|
13
|
+
now?: () => number;
|
|
14
|
+
createCode?: () => string;
|
|
15
|
+
}
|
|
16
|
+
/** Create a short-lived correlation handle without embedding Qoder credentials in the URL. */
|
|
17
|
+
export declare function createQoderPairingInfo(options?: QoderPairingOptions): QoderPairingInfo;
|
|
18
|
+
export declare function formatQoderPairingOutput(info: QoderPairingInfo): string;
|
package/dist/qoder.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
/** Create a short-lived correlation handle without embedding Qoder credentials in the URL. */
|
|
3
|
+
export function createQoderPairingInfo(options = {}) {
|
|
4
|
+
const pairingCode = (options.createCode ?? (() => randomBytes(24).toString('base64url')))();
|
|
5
|
+
if (!/^[A-Za-z0-9_-]{16,128}$/.test(pairingCode)) {
|
|
6
|
+
throw new Error('Qoder pairing code must be 16-128 URL-safe characters');
|
|
7
|
+
}
|
|
8
|
+
const createdAt = (options.now ?? Date.now)();
|
|
9
|
+
if (!Number.isSafeInteger(createdAt) ||
|
|
10
|
+
createdAt < 1_000_000_000_000 ||
|
|
11
|
+
createdAt > 9_999_999_999_999) {
|
|
12
|
+
throw new Error('Qoder pairing timestamp must be a 13-digit epoch millisecond value');
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
pairingCode,
|
|
16
|
+
createdAt,
|
|
17
|
+
connectorUrl: `qoder://pair/${pairingCode}?created=${createdAt}`,
|
|
18
|
+
toolInput: { action: 'pair', payload: { code: pairingCode } },
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function formatQoderPairingOutput(info) {
|
|
22
|
+
const connectorCommand = `npx @mearl/cloud-connector "${info.connectorUrl}"`;
|
|
23
|
+
return `[Qoder] Mearl local-browser pairing is ready.
|
|
24
|
+
|
|
25
|
+
Show the user this command and ask them to run it on the computer that owns the browser:
|
|
26
|
+
${connectorCommand}
|
|
27
|
+
|
|
28
|
+
Then immediately invoke the Qoder client-side custom tool named "mearl" with this input:
|
|
29
|
+
${JSON.stringify(info.toolInput)}
|
|
30
|
+
|
|
31
|
+
The connector reads QODER_PERSONAL_ACCESS_TOKEN from the local environment. Never add the PAT to the pairing URL.`;
|
|
32
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mearl/setup",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "One-shot environment setup and configuration for Mearl",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,13 +30,17 @@
|
|
|
30
30
|
"types": "./dist/agentBay.d.ts",
|
|
31
31
|
"import": "./dist/agentBay.js"
|
|
32
32
|
},
|
|
33
|
+
"./qoder": {
|
|
34
|
+
"types": "./dist/qoder.d.ts",
|
|
35
|
+
"import": "./dist/qoder.js"
|
|
36
|
+
},
|
|
33
37
|
"./version": {
|
|
34
38
|
"types": "./dist/version.d.ts",
|
|
35
39
|
"import": "./dist/version.js"
|
|
36
40
|
}
|
|
37
41
|
},
|
|
38
42
|
"bin": {
|
|
39
|
-
"mearl-setup": "./dist/
|
|
43
|
+
"mearl-setup": "./dist/bin.js"
|
|
40
44
|
},
|
|
41
45
|
"files": [
|
|
42
46
|
"dist",
|
|
@@ -58,7 +62,7 @@
|
|
|
58
62
|
"typescript": "^5.8.3"
|
|
59
63
|
},
|
|
60
64
|
"scripts": {
|
|
61
|
-
"build": "rm -rf dist/ && tsc && chmod +x dist/
|
|
65
|
+
"build": "rm -rf dist/ && tsc && chmod +x dist/bin.js",
|
|
62
66
|
"dev": "tsc --watch",
|
|
63
67
|
"typecheck": "tsc --noEmit",
|
|
64
68
|
"test": "vitest run"
|