@mearl/setup 2.6.1 → 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 +6 -0
- 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 +29 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- 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
|
|
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
|
|
@@ -143,6 +158,7 @@ Examples:
|
|
|
143
158
|
npx @mearl/setup --local --cloud
|
|
144
159
|
npx @mearl/setup update
|
|
145
160
|
npx @mearl/setup agentbay
|
|
161
|
+
npx @mearl/setup qoder --yes
|
|
146
162
|
npx @mearl/setup update --local --target-line 2.3.x --skip-skill
|
|
147
163
|
npx @mearl/setup uninstall --local`;
|
|
148
164
|
if (toError)
|
|
@@ -193,6 +209,17 @@ export async function main(argv = process.argv.slice(2), interactiveTerminal = p
|
|
|
193
209
|
return 1;
|
|
194
210
|
}
|
|
195
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
|
+
}
|
|
196
223
|
if (!interactiveTerminal && !parsed.yes && parsed.operation !== 'update') {
|
|
197
224
|
console.error('Non-interactive input detected. Re-run with --yes or --non-interactive.');
|
|
198
225
|
return 2;
|
|
@@ -212,7 +239,3 @@ export async function main(argv = process.argv.slice(2), interactiveTerminal = p
|
|
|
212
239
|
return 1;
|
|
213
240
|
}
|
|
214
241
|
}
|
|
215
|
-
const currentFile = fileURLToPath(import.meta.url);
|
|
216
|
-
if (process.argv[1] && path.resolve(process.argv[1]) === currentFile) {
|
|
217
|
-
process.exitCode = await main();
|
|
218
|
-
}
|
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/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"
|