persnally 2.0.1 → 2.0.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/build/src/config.js +3 -1
- package/build/src/connect.js +21 -4
- package/build/src/lifecycle.js +11 -5
- package/package.json +1 -1
package/build/src/config.js
CHANGED
|
@@ -22,7 +22,9 @@ export function saveConfig(updates) {
|
|
|
22
22
|
const file = configFile();
|
|
23
23
|
mkdirSync(dirname(file), { recursive: true });
|
|
24
24
|
const merged = { ...loadConfig(), ...updates };
|
|
25
|
-
|
|
25
|
+
// mode on create closes the world-readable window before chmod; chmod also
|
|
26
|
+
// corrects perms on a pre-existing file. The config holds the API key.
|
|
27
|
+
writeFileSync(file, JSON.stringify(merged, null, 2) + "\n", { mode: 0o600 });
|
|
26
28
|
chmodSync(file, 0o600);
|
|
27
29
|
}
|
|
28
30
|
/** Env wins over config; sets process.env so the Anthropic SDK picks it up. */
|
package/build/src/connect.js
CHANGED
|
@@ -37,9 +37,17 @@ export function connectClient(client) {
|
|
|
37
37
|
const { file, installed } = configPathFor(client);
|
|
38
38
|
if (!installed)
|
|
39
39
|
return null;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
let cfg = {};
|
|
41
|
+
if (existsSync(file)) {
|
|
42
|
+
try {
|
|
43
|
+
cfg = JSON.parse(readFileSync(file, "utf-8"));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// Never overwrite a config we couldn't parse — that would wipe the user's
|
|
47
|
+
// other MCP servers. Surface it instead.
|
|
48
|
+
throw new Error(`${file} is not valid JSON — fix it, then run \`persnallyd connect ${client}\` again`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
43
51
|
const servers = (cfg.mcpServers ??= {});
|
|
44
52
|
servers.persnally = { command: "node", args: [mcpServerPath()] };
|
|
45
53
|
mkdirSync(dirname(file), { recursive: true });
|
|
@@ -47,5 +55,14 @@ export function connectClient(client) {
|
|
|
47
55
|
return file;
|
|
48
56
|
}
|
|
49
57
|
export function connectAll() {
|
|
50
|
-
|
|
58
|
+
// One client with a malformed existing config must not abort onboarding for
|
|
59
|
+
// the others; connectClient throws rather than clobber a file it can't parse.
|
|
60
|
+
return CLIENTS.map((client) => {
|
|
61
|
+
try {
|
|
62
|
+
return { client, file: connectClient(client) };
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return { client, file: null };
|
|
66
|
+
}
|
|
67
|
+
});
|
|
51
68
|
}
|
package/build/src/lifecycle.js
CHANGED
|
@@ -79,6 +79,9 @@ export function autostartInstalled() {
|
|
|
79
79
|
export function installAutostart(cliPath, port) {
|
|
80
80
|
if (process.platform !== "darwin")
|
|
81
81
|
throw new Error("autostart is macOS-only for now (launchd)");
|
|
82
|
+
// Paths carry the username/home dir; escape so an "&" or "<" in a path can't
|
|
83
|
+
// produce a malformed plist that silently breaks autostart.
|
|
84
|
+
const x = xmlEscape;
|
|
82
85
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
83
86
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
84
87
|
<plist version="1.0">
|
|
@@ -86,16 +89,16 @@ export function installAutostart(cliPath, port) {
|
|
|
86
89
|
<key>Label</key><string>${PLIST_LABEL}</string>
|
|
87
90
|
<key>ProgramArguments</key>
|
|
88
91
|
<array>
|
|
89
|
-
<string>${process.execPath}</string>
|
|
90
|
-
<string>${cliPath}</string>
|
|
92
|
+
<string>${x(process.execPath)}</string>
|
|
93
|
+
<string>${x(cliPath)}</string>
|
|
91
94
|
<string>serve</string>
|
|
92
95
|
<string>--port</string>
|
|
93
|
-
<string>${port}</string>
|
|
96
|
+
<string>${x(String(port))}</string>
|
|
94
97
|
</array>
|
|
95
98
|
<key>RunAtLoad</key><true/>
|
|
96
99
|
<key>KeepAlive</key><true/>
|
|
97
|
-
<key>StandardOutPath</key><string>${LOG_FILE}</string>
|
|
98
|
-
<key>StandardErrorPath</key><string>${LOG_FILE}</string>
|
|
100
|
+
<key>StandardOutPath</key><string>${x(LOG_FILE)}</string>
|
|
101
|
+
<key>StandardErrorPath</key><string>${x(LOG_FILE)}</string>
|
|
99
102
|
</dict>
|
|
100
103
|
</plist>
|
|
101
104
|
`;
|
|
@@ -117,3 +120,6 @@ export function removeAutostart() {
|
|
|
117
120
|
function sleep(ms) {
|
|
118
121
|
return new Promise((r) => setTimeout(r, ms));
|
|
119
122
|
}
|
|
123
|
+
function xmlEscape(s) {
|
|
124
|
+
return s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c]));
|
|
125
|
+
}
|