pi-mcp-adapter 2.4.0 → 2.4.2
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/CHANGELOG.md +23 -0
- package/README.md +53 -7
- package/cli.js +152 -86
- package/commands.ts +116 -9
- package/config.ts +566 -126
- package/index.ts +15 -3
- package/mcp-panel.ts +11 -1
- package/mcp-setup-panel.ts +576 -0
- package/onboarding-state.ts +68 -0
- package/package.json +4 -2
- package/utils.ts +18 -9
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
|
|
5
|
+
export interface McpOnboardingState {
|
|
6
|
+
version: 1;
|
|
7
|
+
sharedConfigHintShown: boolean;
|
|
8
|
+
setupCompleted: boolean;
|
|
9
|
+
lastDiscoveryFingerprint?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const DEFAULT_STATE: McpOnboardingState = {
|
|
13
|
+
version: 1,
|
|
14
|
+
sharedConfigHintShown: false,
|
|
15
|
+
setupCompleted: false,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function getOnboardingStatePath(): string {
|
|
19
|
+
return join(homedir(), ".pi", "agent", "mcp-onboarding.json");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function loadOnboardingState(): McpOnboardingState {
|
|
23
|
+
const path = getOnboardingStatePath();
|
|
24
|
+
if (!existsSync(path)) return { ...DEFAULT_STATE };
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const raw = JSON.parse(readFileSync(path, "utf-8")) as Partial<McpOnboardingState>;
|
|
28
|
+
if (!raw || typeof raw !== "object") return { ...DEFAULT_STATE };
|
|
29
|
+
return {
|
|
30
|
+
version: 1,
|
|
31
|
+
sharedConfigHintShown: raw.sharedConfigHintShown === true,
|
|
32
|
+
setupCompleted: raw.setupCompleted === true,
|
|
33
|
+
lastDiscoveryFingerprint: typeof raw.lastDiscoveryFingerprint === "string" ? raw.lastDiscoveryFingerprint : undefined,
|
|
34
|
+
};
|
|
35
|
+
} catch {
|
|
36
|
+
return { ...DEFAULT_STATE };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function saveOnboardingState(state: McpOnboardingState): void {
|
|
41
|
+
const path = getOnboardingStatePath();
|
|
42
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
43
|
+
const tmpPath = `${path}.${process.pid}.tmp`;
|
|
44
|
+
writeFileSync(tmpPath, `${JSON.stringify(state, null, 2)}\n`, "utf-8");
|
|
45
|
+
renameSync(tmpPath, path);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function updateOnboardingState(updater: (state: McpOnboardingState) => McpOnboardingState): McpOnboardingState {
|
|
49
|
+
const next = updater(loadOnboardingState());
|
|
50
|
+
saveOnboardingState(next);
|
|
51
|
+
return next;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function markSharedConfigHintShown(fingerprint?: string): McpOnboardingState {
|
|
55
|
+
return updateOnboardingState((state) => ({
|
|
56
|
+
...state,
|
|
57
|
+
sharedConfigHintShown: true,
|
|
58
|
+
lastDiscoveryFingerprint: fingerprint ?? state.lastDiscoveryFingerprint,
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function markSetupCompleted(fingerprint?: string): McpOnboardingState {
|
|
63
|
+
return updateOnboardingState((state) => ({
|
|
64
|
+
...state,
|
|
65
|
+
setupCompleted: true,
|
|
66
|
+
lastDiscoveryFingerprint: fingerprint ?? state.lastDiscoveryFingerprint,
|
|
67
|
+
}));
|
|
68
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mcp-adapter",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "MCP (Model Context Protocol) adapter extension for Pi coding agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,6 +45,8 @@
|
|
|
45
45
|
"proxy-modes.ts",
|
|
46
46
|
"direct-tools.ts",
|
|
47
47
|
"commands.ts",
|
|
48
|
+
"onboarding-state.ts",
|
|
49
|
+
"mcp-setup-panel.ts",
|
|
48
50
|
"types.ts",
|
|
49
51
|
"ui-stream-types.ts",
|
|
50
52
|
"config.ts",
|
|
@@ -75,7 +77,7 @@
|
|
|
75
77
|
"dependencies": {
|
|
76
78
|
"@modelcontextprotocol/ext-apps": "^1.2.2",
|
|
77
79
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
78
|
-
"
|
|
80
|
+
"typebox": "^1.1.24",
|
|
79
81
|
"open": "^10.2.0",
|
|
80
82
|
"zod": "^3.25.0 || ^4.0.0"
|
|
81
83
|
},
|
package/utils.ts
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { platform } from "node:os";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
async function execOpen(pi: ExtensionAPI, target: string, browser?: string) {
|
|
5
5
|
const os = platform();
|
|
6
|
-
let result;
|
|
7
6
|
|
|
8
7
|
if (os === "darwin") {
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
result = browser ? await pi.exec(browser, [url]) : await pi.exec("xdg-open", [url]);
|
|
8
|
+
return browser ? pi.exec("open", ["-a", browser, target]) : pi.exec("open", [target]);
|
|
9
|
+
}
|
|
10
|
+
if (os === "win32") {
|
|
11
|
+
return browser
|
|
12
|
+
? pi.exec("cmd", ["/c", "start", "", browser, target])
|
|
13
|
+
: pi.exec("cmd", ["/c", "start", "", target]);
|
|
16
14
|
}
|
|
15
|
+
return browser ? pi.exec(browser, [target]) : pi.exec("xdg-open", [target]);
|
|
16
|
+
}
|
|
17
17
|
|
|
18
|
+
export async function openUrl(pi: ExtensionAPI, url: string, browser?: string): Promise<void> {
|
|
19
|
+
const result = await execOpen(pi, url, browser);
|
|
18
20
|
if (result.code !== 0) {
|
|
19
21
|
throw new Error(result.stderr || `Failed to open browser (exit code ${result.code})`);
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
export async function openPath(pi: ExtensionAPI, targetPath: string): Promise<void> {
|
|
26
|
+
const result = await execOpen(pi, targetPath);
|
|
27
|
+
if (result.code !== 0) {
|
|
28
|
+
throw new Error(result.stderr || `Failed to open path (exit code ${result.code})`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
23
32
|
export async function parallelLimit<T, R>(
|
|
24
33
|
items: T[],
|
|
25
34
|
limit: number,
|