phistruct-mcp 0.1.1 → 0.1.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/cli.mjs +41 -19
- package/package.json +2 -2
package/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, realpathSync, renameSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { createConnection } from "node:net";
|
|
5
5
|
import { homedir } from "node:os";
|
|
@@ -71,8 +71,24 @@ function runMdfind() {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/** A visible PhiStruct window, including a different copy than `bin`. Ignores the hidden --mcp helper. */
|
|
75
|
+
export function isGuiCommand(command, bin) {
|
|
76
|
+
if (!command || isStdioMcpCommand(command)) return false;
|
|
77
|
+
if (bin && command.includes(bin)) return true;
|
|
78
|
+
return /\/MacOS\/PhiStruct(?:\s|$)/.test(command);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function runningGuiBinary(listCommands = psCommands) {
|
|
82
|
+
for (const command of listCommands()) {
|
|
83
|
+
if (!isGuiCommand(command)) continue;
|
|
84
|
+
const match = command.match(/(\/\S+\/MacOS\/PhiStruct)(?:\s|$)/);
|
|
85
|
+
if (match) return match[1];
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
74
90
|
export function guiIsRunning(bin, listCommands = psCommands) {
|
|
75
|
-
return listCommands().some((command) => command
|
|
91
|
+
return listCommands().some((command) => isGuiCommand(command, bin));
|
|
76
92
|
}
|
|
77
93
|
|
|
78
94
|
function psCommands() {
|
|
@@ -193,11 +209,32 @@ export function setupConfigs({
|
|
|
193
209
|
return written;
|
|
194
210
|
}
|
|
195
211
|
|
|
212
|
+
export const WINDOW_CLOSED_MESSAGE = "PhiStruct 窗口没开。请先自己打开 PhiStruct。";
|
|
213
|
+
|
|
196
214
|
function fail(message) {
|
|
197
215
|
process.stderr.write(`${message}\n`);
|
|
198
216
|
process.exit(1);
|
|
199
217
|
}
|
|
200
218
|
|
|
219
|
+
/** Use the app's own helper so sandboxed UserDefaults stay inside the app container. */
|
|
220
|
+
export function runStdioBridge({
|
|
221
|
+
bin = runningGuiBinary(),
|
|
222
|
+
spawnProcess = spawn,
|
|
223
|
+
onExit = (code) => process.exit(code ?? 1),
|
|
224
|
+
} = {}) {
|
|
225
|
+
if (!bin) throw new Error(WINDOW_CLOSED_MESSAGE);
|
|
226
|
+
const child = spawnProcess(bin, ["--mcp"], { stdio: "inherit" });
|
|
227
|
+
child.once("error", (err) => {
|
|
228
|
+
process.stderr.write(`Could not connect to PhiStruct MCP: ${err.message}\n`);
|
|
229
|
+
onExit(1);
|
|
230
|
+
});
|
|
231
|
+
child.once("exit", (code, signal) => {
|
|
232
|
+
if (signal) process.kill(process.pid, signal);
|
|
233
|
+
else onExit(code);
|
|
234
|
+
});
|
|
235
|
+
return child;
|
|
236
|
+
}
|
|
237
|
+
|
|
201
238
|
async function main() {
|
|
202
239
|
const argv = process.argv.slice(2).filter((a) => a !== "--");
|
|
203
240
|
if (argv[0] === "setup" || argv[0] === "install") {
|
|
@@ -206,24 +243,9 @@ async function main() {
|
|
|
206
243
|
return;
|
|
207
244
|
}
|
|
208
245
|
if (process.platform !== "darwin") {
|
|
209
|
-
fail("PhiStruct MCP
|
|
210
|
-
}
|
|
211
|
-
const bin = findApp();
|
|
212
|
-
if (!bin) {
|
|
213
|
-
fail("PhiStruct.app not found. Install PhiStruct, then try again.");
|
|
246
|
+
fail("PhiStruct MCP only runs on macOS.");
|
|
214
247
|
}
|
|
215
|
-
|
|
216
|
-
spawn(bin, [], { detached: true, stdio: "ignore" }).unref();
|
|
217
|
-
}
|
|
218
|
-
const port = await waitForLiveMcp();
|
|
219
|
-
if (port == null) {
|
|
220
|
-
fail("PhiStruct opened but MCP did not listen on 127.0.0.1:17321–17340.");
|
|
221
|
-
}
|
|
222
|
-
const child = spawn(bin, ["--mcp"], { stdio: "inherit" });
|
|
223
|
-
child.on("exit", (code, signal) => {
|
|
224
|
-
if (signal) process.kill(process.pid, signal);
|
|
225
|
-
process.exit(code ?? 1);
|
|
226
|
-
});
|
|
248
|
+
runStdioBridge();
|
|
227
249
|
}
|
|
228
250
|
|
|
229
251
|
function isDirectRun() {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "phistruct-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "MCP stdio bridge
|
|
5
|
+
"description": "MCP stdio bridge for an already-open PhiStruct window. Does not launch the app.",
|
|
6
6
|
"bin": {
|
|
7
7
|
"phistruct-mcp": "./cli.mjs"
|
|
8
8
|
},
|