patchxnote-agent 0.2.7 → 0.2.8
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 +24 -2
- package/bin/patchxnote-agent.js +44 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,23 @@ PatchXNote Agent is the local AI assistant connector for PatchXNote. It lets an
|
|
|
9
9
|
Give this one-line prompt to a local-command-capable AI assistant:
|
|
10
10
|
|
|
11
11
|
```text
|
|
12
|
-
Connect PatchXNote Agent by following the public guide at https://patchx2025.feishu.cn/wiki/PnVRwYT7IirFPckairGcWPnHnCd: run npx -y patchxnote-agent@latest
|
|
12
|
+
Connect PatchXNote Agent by following the public guide at https://patchx2025.feishu.cn/wiki/PnVRwYT7IirFPckairGcWPnHnCd: run npx -y patchxnote-agent@latest setup --client <my-client>, keep MCP config secret-free, and guide me through login in the same runtime that will launch the MCP server. Do not ask me to paste OTP codes, access tokens, or refresh tokens into chat. GitHub repository: https://github.com/ZsTs119/patchxnote-agent
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Run setup for a supported local client:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npx -y patchxnote-agent@latest setup --client cursor
|
|
19
|
+
npx -y patchxnote-agent@latest setup --client vscode
|
|
20
|
+
npx -y patchxnote-agent@latest setup --client codex
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Log in with browser OAuth, then check or clear the MCP login state:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npx -y patchxnote-agent@latest mcp login
|
|
27
|
+
npx -y patchxnote-agent@latest mcp status
|
|
28
|
+
npx -y patchxnote-agent@latest mcp logout --local-only
|
|
13
29
|
```
|
|
14
30
|
|
|
15
31
|
Print the generic MCP config manually:
|
|
@@ -24,12 +40,18 @@ The generated config uses this universal local stdio MCP command:
|
|
|
24
40
|
npx -y patchxnote-agent@latest mcp serve
|
|
25
41
|
```
|
|
26
42
|
|
|
27
|
-
|
|
43
|
+
The older terminal Agent login remains available for legacy local CLI/MCP fallback:
|
|
28
44
|
|
|
29
45
|
```sh
|
|
30
46
|
npx -y patchxnote-agent@latest login
|
|
31
47
|
```
|
|
32
48
|
|
|
49
|
+
`setup` reuses the same `mcp login` browser OAuth flow. The GoServer website owns phone OTP input; the local Agent owns the loopback callback, token exchange, secure storage, and stdio bridge. `mcp serve` never opens a browser during editor startup. It stores credentials in the OS-native keychain and keeps MCP config free of phone numbers, OTP codes, access tokens, and refresh tokens.
|
|
50
|
+
|
|
51
|
+
P0 local client IDs: `vscode`, `cursor`, `codex`, `claude-code`, `claude-desktop`, `windsurf`, `trae`, `qoder`, `workbuddy`.
|
|
52
|
+
|
|
53
|
+
Platform clients such as Feishu Aily, Doubao Work Partner, Tencent Agent Development Platform, and enterprise WorkBuddy need the hosted remote MCP gateway plus platform-console acceptance; local `npx` setup is for desktop and terminal clients.
|
|
54
|
+
|
|
33
55
|
If a client rejects `npx` or times out during first binary download, run the stable absolute-path fallback:
|
|
34
56
|
|
|
35
57
|
```sh
|
package/bin/patchxnote-agent.js
CHANGED
|
@@ -29,10 +29,18 @@ async function main(argv) {
|
|
|
29
29
|
await runLogin(parsed);
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
+
if (parsed.command === "setup") {
|
|
33
|
+
await runSetup(parsed);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
32
36
|
if (parsed.command === "mcp" && parsed.subcommand === "config") {
|
|
33
37
|
printUniversalMCPConfig();
|
|
34
38
|
return;
|
|
35
39
|
}
|
|
40
|
+
if (parsed.command === "mcp" && ["login", "status", "logout"].includes(parsed.subcommand)) {
|
|
41
|
+
await runMCPSubcommand(parsed);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
36
44
|
if (parsed.command === "mcp" && parsed.subcommand === "serve") {
|
|
37
45
|
await runMCPServe(parsed);
|
|
38
46
|
return;
|
|
@@ -74,6 +82,14 @@ async function runLogin(parsed) {
|
|
|
74
82
|
process.exitCode = code;
|
|
75
83
|
}
|
|
76
84
|
|
|
85
|
+
async function runSetup(parsed) {
|
|
86
|
+
const plan = await ensureBinary(parsed.options, { stderr: process.stderr });
|
|
87
|
+
const code = await spawnAndWait(plan.install_path, ["setup", ...parsed.passthroughArgs], {
|
|
88
|
+
stdio: "inherit"
|
|
89
|
+
});
|
|
90
|
+
process.exitCode = code;
|
|
91
|
+
}
|
|
92
|
+
|
|
77
93
|
async function runMCPServe(parsed) {
|
|
78
94
|
const plan = await ensureBinary(parsed.options, { stderr: process.stderr });
|
|
79
95
|
const code = await spawnAndWait(plan.install_path, ["mcp", "serve", ...parsed.passthroughArgs], {
|
|
@@ -83,6 +99,14 @@ async function runMCPServe(parsed) {
|
|
|
83
99
|
process.exitCode = code;
|
|
84
100
|
}
|
|
85
101
|
|
|
102
|
+
async function runMCPSubcommand(parsed) {
|
|
103
|
+
const plan = await ensureBinary(parsed.options, { stderr: process.stderr });
|
|
104
|
+
const code = await spawnAndWait(plan.install_path, ["mcp", parsed.subcommand, ...parsed.passthroughArgs], {
|
|
105
|
+
stdio: "inherit"
|
|
106
|
+
});
|
|
107
|
+
process.exitCode = code;
|
|
108
|
+
}
|
|
109
|
+
|
|
86
110
|
function createInstallPlan(command, options = {}) {
|
|
87
111
|
const target = resolveTarget(options.platform || process.platform, options.arch || process.arch);
|
|
88
112
|
const installDir = options.installDir || defaultInstallDir(process.platform);
|
|
@@ -371,13 +395,21 @@ function parseArgs(argv) {
|
|
|
371
395
|
const launcher = parseLauncherOptions(rest, { allowPassthrough: true, rejectPrintConfig: true });
|
|
372
396
|
return { command, options: launcher.options, passthroughArgs: launcher.passthroughArgs };
|
|
373
397
|
}
|
|
398
|
+
if (command === "setup") {
|
|
399
|
+
const launcher = parseLauncherOptions(rest, {
|
|
400
|
+
allowPassthrough: true,
|
|
401
|
+
passThroughDryRun: true,
|
|
402
|
+
passThroughPrintConfig: true
|
|
403
|
+
});
|
|
404
|
+
return { command, options: launcher.options, passthroughArgs: launcher.passthroughArgs };
|
|
405
|
+
}
|
|
374
406
|
if (command === "mcp") {
|
|
375
407
|
const [subcommand, ...subcommandArgs] = rest;
|
|
376
|
-
if (!["serve", "config"].includes(subcommand)) {
|
|
408
|
+
if (!["serve", "config", "login", "status", "logout"].includes(subcommand)) {
|
|
377
409
|
throw new Error(mcpUsage());
|
|
378
410
|
}
|
|
379
411
|
const launcher = parseLauncherOptions(subcommandArgs, {
|
|
380
|
-
allowPassthrough: subcommand
|
|
412
|
+
allowPassthrough: subcommand !== "config",
|
|
381
413
|
rejectPrintConfig: true
|
|
382
414
|
});
|
|
383
415
|
return { command, subcommand, options: launcher.options, passthroughArgs: launcher.passthroughArgs };
|
|
@@ -432,8 +464,16 @@ function parseLauncherOptions(rest, settings = {}) {
|
|
|
432
464
|
}
|
|
433
465
|
throw new Error(`unknown option ${arg}`);
|
|
434
466
|
case "--dry-run":
|
|
467
|
+
if (settings.passThroughDryRun) {
|
|
468
|
+
passthroughArgs.push(arg);
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
435
471
|
throw new Error("--dry-run is only valid for install/update/uninstall");
|
|
436
472
|
case "--print-config":
|
|
473
|
+
if (settings.passThroughPrintConfig) {
|
|
474
|
+
passthroughArgs.push(arg);
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
437
477
|
if (settings.rejectPrintConfig) {
|
|
438
478
|
throw new Error("--print-config is not valid for this command");
|
|
439
479
|
}
|
|
@@ -629,11 +669,11 @@ function verifyChecksum(binary, assetName, checksumsText) {
|
|
|
629
669
|
}
|
|
630
670
|
|
|
631
671
|
function usage() {
|
|
632
|
-
return "usage: patchxnote-agent <install|update|uninstall|login|mcp> [options]";
|
|
672
|
+
return "usage: patchxnote-agent <install|update|uninstall|login|setup|mcp> [options]";
|
|
633
673
|
}
|
|
634
674
|
|
|
635
675
|
function mcpUsage() {
|
|
636
|
-
return "usage: patchxnote-agent mcp <serve|config> [options]";
|
|
676
|
+
return "usage: patchxnote-agent mcp <serve|config|login|status|logout> [options]";
|
|
637
677
|
}
|
|
638
678
|
|
|
639
679
|
if (require.main === module) {
|