@paigy/mcp 0.40.9 → 0.40.10
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/dist/{chunk-LYPZ5QO2.js → chunk-AK5AVPF6.js} +1 -1
- package/dist/{chunk-5OY6ED2Q.js → chunk-HCCUK3ZL.js} +49 -16
- package/dist/{chunk-UOROFXDI.js → chunk-QAQET3PZ.js} +4 -4
- package/dist/enable.js +2 -2
- package/dist/index.js +7 -7
- package/dist/listen.js +1 -1
- package/dist/onboard.js +5 -5
- package/dist/slot.js +3 -3
- package/dist/statusline.js +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// ../../packages/sdk/dist/index.js
|
|
2
2
|
import { createRequire as __sdkCreateRequire } from "module";
|
|
3
|
+
import { execFileSync } from "child_process";
|
|
3
4
|
import { createHash, randomUUID } from "crypto";
|
|
5
|
+
import { readFileSync } from "fs";
|
|
6
|
+
import { homedir } from "os";
|
|
7
|
+
import { join } from "path";
|
|
4
8
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
5
9
|
import { setTimeout as sleep2 } from "timers/promises";
|
|
6
10
|
import { z as z3 } from "zod";
|
|
@@ -10,9 +14,9 @@ import { ZodFirstPartyTypeKind } from "zod/v3";
|
|
|
10
14
|
import { ZodFirstPartyTypeKind as ZodFirstPartyTypeKind2 } from "zod/v3";
|
|
11
15
|
import { z } from "zod";
|
|
12
16
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
13
|
-
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, rmSync, statSync, writeFileSync } from "fs";
|
|
14
|
-
import { homedir } from "os";
|
|
15
|
-
import { join } from "path";
|
|
17
|
+
import { closeSync, existsSync, mkdirSync, openSync, readFileSync as readFileSync2, rmSync, statSync, writeFileSync } from "fs";
|
|
18
|
+
import { homedir as homedir2 } from "os";
|
|
19
|
+
import { join as join2 } from "path";
|
|
16
20
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
17
21
|
import { WebSocket } from "undici";
|
|
18
22
|
var require2 = __sdkCreateRequire(import.meta.url);
|
|
@@ -36,15 +40,42 @@ var envSession = (key) => {
|
|
|
36
40
|
const v = process.env[key];
|
|
37
41
|
return v && v.trim() ? v : void 0;
|
|
38
42
|
};
|
|
39
|
-
|
|
43
|
+
function parentOf(pid) {
|
|
44
|
+
try {
|
|
45
|
+
if (process.platform === "win32") return void 0;
|
|
46
|
+
const ppid = process.platform === "linux" ? readFileSync(`/proc/${pid}/stat`, "utf8").split(") ")[1]?.split(" ")[1] : execFileSync("ps", ["-o", "ppid=", "-p", String(pid)], { encoding: "utf8", timeout: 1e3 });
|
|
47
|
+
return Number(ppid?.trim()) || void 0;
|
|
48
|
+
} catch {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
var lineage;
|
|
53
|
+
function ancestors() {
|
|
54
|
+
if (lineage) return lineage;
|
|
55
|
+
lineage = [];
|
|
56
|
+
for (let pid = process.ppid; pid && pid > 1 && lineage.length < 5; pid = parentOf(pid)) lineage.push(pid);
|
|
57
|
+
return lineage;
|
|
58
|
+
}
|
|
59
|
+
function claudeConversation() {
|
|
60
|
+
if (!envSession("CLAUDE_CODE_SESSION_ID") || process.env.CLAUDE_CODE_CHILD_SESSION) return void 0;
|
|
61
|
+
const dir = envSession("CLAUDE_CONFIG_DIR") ?? join(homedir(), ".claude");
|
|
62
|
+
for (const pid of ancestors()) {
|
|
63
|
+
try {
|
|
64
|
+
const { sessionId: sessionId2 } = JSON.parse(readFileSync(join(dir, "sessions", `${pid}.json`), "utf8"));
|
|
65
|
+
return typeof sessionId2 === "string" && sessionId2.trim() ? sessionId2 : void 0;
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return void 0;
|
|
70
|
+
}
|
|
40
71
|
function sessionId() {
|
|
41
|
-
return
|
|
72
|
+
return envSession("PAIGY_SESSION_ID") ?? claudeConversation() ?? envSession("CLAUDE_CODE_SESSION_ID") ?? envSession("CODEX_THREAD_ID") ?? envSession("CODEX_SESSION_ID") ?? WORKSPACE_ID;
|
|
42
73
|
}
|
|
43
74
|
function isNetworkError(e) {
|
|
44
75
|
return e instanceof Error && e.message.startsWith(NETWORK_MSG);
|
|
45
76
|
}
|
|
46
77
|
async function reach(url, init) {
|
|
47
|
-
return send(url, init,
|
|
78
|
+
return send(url, init, sessionId());
|
|
48
79
|
}
|
|
49
80
|
async function send(url, init, session) {
|
|
50
81
|
try {
|
|
@@ -2352,13 +2383,15 @@ function sessionSlot(sessionId2) {
|
|
|
2352
2383
|
const id = sessionId2 ?? sessionId();
|
|
2353
2384
|
return `session:${id.slice(0, 8)}`;
|
|
2354
2385
|
}
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2386
|
+
function agentName() {
|
|
2387
|
+
return process.env.PAIGY_AGENT || sessionSlot();
|
|
2388
|
+
}
|
|
2389
|
+
var TOKEN_PATH = join2(homedir2(), ".paigy", "token.json");
|
|
2390
|
+
var KEY_PATH = join2(homedir2(), ".paigy", "key.json");
|
|
2358
2391
|
function readTokenFile() {
|
|
2359
2392
|
if (!existsSync(TOKEN_PATH)) return {};
|
|
2360
2393
|
try {
|
|
2361
|
-
const parsed = JSON.parse(
|
|
2394
|
+
const parsed = JSON.parse(readFileSync2(TOKEN_PATH, "utf8"));
|
|
2362
2395
|
if (typeof parsed.access_token === "string") return {};
|
|
2363
2396
|
const slots = parsed;
|
|
2364
2397
|
delete slots["*"];
|
|
@@ -2370,7 +2403,7 @@ function readTokenFile() {
|
|
|
2370
2403
|
function withTokenLock(mutate) {
|
|
2371
2404
|
const lock = TOKEN_PATH + ".lock";
|
|
2372
2405
|
const spin = new Int32Array(new SharedArrayBuffer(4));
|
|
2373
|
-
mkdirSync(
|
|
2406
|
+
mkdirSync(join2(homedir2(), ".paigy"), { recursive: true });
|
|
2374
2407
|
for (const deadline = Date.now() + 5e3; Date.now() < deadline; ) {
|
|
2375
2408
|
try {
|
|
2376
2409
|
closeSync(openSync(lock, "wx"));
|
|
@@ -2387,14 +2420,14 @@ function withTokenLock(mutate) {
|
|
|
2387
2420
|
rmSync(lock, { force: true });
|
|
2388
2421
|
}
|
|
2389
2422
|
}
|
|
2390
|
-
function saveToken(token, agent2 =
|
|
2423
|
+
function saveToken(token, agent2 = agentName()) {
|
|
2391
2424
|
withTokenLock(() => {
|
|
2392
2425
|
const slots = { ...readTokenFile(), [agent2]: token };
|
|
2393
2426
|
writeFileSync(TOKEN_PATH, JSON.stringify(slots, null, 2) + "\n", { mode: 384 });
|
|
2394
2427
|
});
|
|
2395
2428
|
}
|
|
2396
2429
|
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
2397
|
-
function readToken(agent2 =
|
|
2430
|
+
function readToken(agent2 = agentName()) {
|
|
2398
2431
|
if (process.env.PAIGY_TOKEN) return process.env.PAIGY_TOKEN;
|
|
2399
2432
|
return readTokenFile()[agent2]?.access_token ?? "";
|
|
2400
2433
|
}
|
|
@@ -2404,7 +2437,7 @@ function listSlots() {
|
|
|
2404
2437
|
function slotName(agent2) {
|
|
2405
2438
|
return readTokenFile()[agent2]?.name ?? null;
|
|
2406
2439
|
}
|
|
2407
|
-
function deleteToken(agent2 =
|
|
2440
|
+
function deleteToken(agent2 = agentName()) {
|
|
2408
2441
|
return withTokenLock(() => {
|
|
2409
2442
|
const slots = readTokenFile();
|
|
2410
2443
|
if (!(agent2 in slots)) return false;
|
|
@@ -2421,7 +2454,7 @@ async function revokeToken(token) {
|
|
|
2421
2454
|
});
|
|
2422
2455
|
return res.ok;
|
|
2423
2456
|
}
|
|
2424
|
-
async function requestCode(suggestedName =
|
|
2457
|
+
async function requestCode(suggestedName = agentName(), device) {
|
|
2425
2458
|
const res = await reach(`${BACKEND_URL}/api/device/code`, {
|
|
2426
2459
|
method: "POST",
|
|
2427
2460
|
headers: { "content-type": "application/json" },
|
|
@@ -2876,7 +2909,7 @@ async function subscribeWake(onNudge, opts = {}) {
|
|
|
2876
2909
|
export {
|
|
2877
2910
|
isNetworkError,
|
|
2878
2911
|
sessionSlot,
|
|
2879
|
-
|
|
2912
|
+
agentName,
|
|
2880
2913
|
TOKEN_PATH,
|
|
2881
2914
|
saveToken,
|
|
2882
2915
|
sleep,
|
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
serverInstructions
|
|
5
5
|
} from "./chunk-UFOR2QEP.js";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
} from "./chunk-
|
|
7
|
+
agentName
|
|
8
|
+
} from "./chunk-HCCUK3ZL.js";
|
|
9
9
|
|
|
10
10
|
// src/toolset.ts
|
|
11
11
|
var ONBOARD_DESCRIPTION = "Get this agent talking to Paigy \u2014 call it FIRST, before contact, and any time you're unsure who you are. One call, and it does whatever the situation needs: NOT SET UP \u2192 hatches an identity instantly if this machine holds a device credential (the user ran the Paigy desktop app or harness), otherwise starts the code ceremony; ALREADY SET UP \u2192 returns your current identity and offers the two things left to decide, renaming it or unpairing; TOKEN NO LONGER VALID \u2192 says so, then re-pairs. Pass { name, voice } to choose who you are when hatching, or to RENAME yourself when already set up (voices: rachel, george, jessica, brian, lily). Safe to call any time: idempotent, and it never writes settings \u2014 the tool-allowlist state it reports is read-only. If it returns a `user_code`, print it to the user immediately and call onboard again with the `device_code`. If it returns `enable_command`, PRINT that command for the user to run \u2014 you cannot apply it yourself (it writes your own permission allowlist, which hosts block as privilege escalation), so print it, don't wait for it, and carry on.";
|
|
@@ -88,7 +88,7 @@ function withPaigyMcpToml(existing, agent) {
|
|
|
88
88
|
].join("\n");
|
|
89
89
|
return existing + entry;
|
|
90
90
|
}
|
|
91
|
-
function autoConfigureClients(skip =
|
|
91
|
+
function autoConfigureClients(skip = agentName()) {
|
|
92
92
|
const home = homedir();
|
|
93
93
|
const registered = [];
|
|
94
94
|
if (skip !== "antigravity") {
|
|
@@ -124,7 +124,7 @@ function autoConfigureClients(skip = AGENT_NAME) {
|
|
|
124
124
|
}
|
|
125
125
|
return registered;
|
|
126
126
|
}
|
|
127
|
-
function claudeInstallHint(skip =
|
|
127
|
+
function claudeInstallHint(skip = agentName()) {
|
|
128
128
|
if (skip.startsWith("claude")) return null;
|
|
129
129
|
const claudeDir = join(homedir(), ".claude");
|
|
130
130
|
if (!existsSync(claudeDir)) return null;
|
package/dist/enable.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
resolvePairing,
|
|
6
6
|
startPairing,
|
|
7
7
|
suggestedAgentName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AK5AVPF6.js";
|
|
9
9
|
import {
|
|
10
10
|
ENABLE_COMMAND,
|
|
11
11
|
OnboardSchema,
|
|
@@ -14,15 +14,15 @@ import {
|
|
|
14
14
|
SERVER_INSTRUCTIONS,
|
|
15
15
|
TOOLS,
|
|
16
16
|
paigyToolsAllowlisted
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-QAQET3PZ.js";
|
|
18
18
|
import "./chunk-UFOR2QEP.js";
|
|
19
19
|
import {
|
|
20
20
|
clearSurface,
|
|
21
21
|
writeSurface
|
|
22
22
|
} from "./chunk-3SVNPJPN.js";
|
|
23
23
|
import {
|
|
24
|
-
AGENT_NAME,
|
|
25
24
|
UnpairedError,
|
|
25
|
+
agentName,
|
|
26
26
|
deleteToken,
|
|
27
27
|
hatch,
|
|
28
28
|
heartbeat,
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
setIdentity,
|
|
36
36
|
slotName,
|
|
37
37
|
whoAmI
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-HCCUK3ZL.js";
|
|
39
39
|
|
|
40
40
|
// src/index.ts
|
|
41
41
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -108,7 +108,7 @@ function renderPairOutcome(outcome, device_code) {
|
|
|
108
108
|
function unidentifiedResult() {
|
|
109
109
|
return { isError: true, content: [{ type: "text", text: JSON.stringify({
|
|
110
110
|
error: "no_identity",
|
|
111
|
-
slot:
|
|
111
|
+
slot: agentName(),
|
|
112
112
|
message: `This session has no Paigy identity yet, so nothing was sent \u2014 it will not speak as another session. This machine holds a device credential but hatching under it just failed (it may have been revoked), so call \`pair\` (no arguments) to set this session up, then retry \u2014 it re-hatches if the credential recovered and runs the code ceremony if it didn't. To reuse an existing identity instead, start the session with PAIGY_AGENT set to its slot (${listSlots().filter((s) => s !== "Desktop").join(", ") || "none yet"}).`
|
|
113
113
|
}) }] };
|
|
114
114
|
}
|
|
@@ -238,7 +238,7 @@ async function handleTool(request, signal) {
|
|
|
238
238
|
case "onboard": {
|
|
239
239
|
const { name, voice, device_code, scope } = OnboardSchema.parse(request.params.arguments ?? {});
|
|
240
240
|
if (device_code) return runPair(device_code, name, voice);
|
|
241
|
-
const slot =
|
|
241
|
+
const slot = agentName();
|
|
242
242
|
const secret = readToken();
|
|
243
243
|
if (secret) {
|
|
244
244
|
let who = await whoAmI().catch(() => null);
|
|
@@ -307,7 +307,7 @@ async function handleTool(request, signal) {
|
|
|
307
307
|
default: {
|
|
308
308
|
const name = request.params.name;
|
|
309
309
|
const result = await runTool(name, request.params.arguments ?? {}, { waits: true, signal });
|
|
310
|
-
const sentAs = name === "contact" ? slotName(
|
|
310
|
+
const sentAs = name === "contact" ? slotName(agentName()) : null;
|
|
311
311
|
const shaped = sentAs && result && typeof result === "object" ? { ...result, sentAs } : result;
|
|
312
312
|
return { content: [{ type: "text", text: JSON.stringify(shaped) }] };
|
|
313
313
|
}
|
package/dist/listen.js
CHANGED
package/dist/onboard.js
CHANGED
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
resolvePairing,
|
|
4
4
|
startPairing,
|
|
5
5
|
suggestedAgentName
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-AK5AVPF6.js";
|
|
7
7
|
import {
|
|
8
8
|
autoConfigureClients,
|
|
9
9
|
claudeInstallHint,
|
|
10
10
|
openBrowser
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-QAQET3PZ.js";
|
|
12
12
|
import "./chunk-UFOR2QEP.js";
|
|
13
13
|
import {
|
|
14
|
-
AGENT_NAME,
|
|
15
14
|
TOKEN_PATH,
|
|
15
|
+
agentName,
|
|
16
16
|
hatch,
|
|
17
17
|
listSlots,
|
|
18
18
|
overrideToken,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
saveToken,
|
|
21
21
|
setIdentity,
|
|
22
22
|
whoAmI
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-HCCUK3ZL.js";
|
|
24
24
|
|
|
25
25
|
// src/onboard.ts
|
|
26
26
|
function reportRegistered() {
|
|
@@ -36,7 +36,7 @@ function reportRegistered() {
|
|
|
36
36
|
}
|
|
37
37
|
async function main() {
|
|
38
38
|
console.log(`
|
|
39
|
-
Paigy MCP onboarding (agent: "${
|
|
39
|
+
Paigy MCP onboarding (agent: "${agentName()}")
|
|
40
40
|
`);
|
|
41
41
|
const chosen = process.env.PAIGY_NAME ?? suggestedAgentName();
|
|
42
42
|
if (readToken()) {
|
package/dist/slot.js
CHANGED
package/dist/statusline.js
CHANGED
package/package.json
CHANGED