pi-cloudflare 0.1.0 → 0.1.1
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/LICENSE +21 -674
- package/README.md +10 -0
- package/bin/setup.mjs +51 -51
- package/dist/auth-flow.d.ts +2 -2
- package/dist/auth-flow.d.ts.map +1 -1
- package/dist/auth-flow.js +20 -20
- package/dist/auth-flow.js.map +1 -1
- package/dist/client.d.ts +2 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -4
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts.map +1 -1
- package/dist/oauth.js +30 -30
- package/dist/oauth.js.map +1 -1
- package/dist/proxy.d.ts +2 -2
- package/dist/proxy.d.ts.map +1 -1
- package/dist/proxy.js +7 -7
- package/dist/proxy.js.map +1 -1
- package/dist/servers.d.ts +1 -1
- package/dist/servers.d.ts.map +1 -1
- package/dist/servers.js +20 -20
- package/dist/servers.js.map +1 -1
- package/dist/token-store.d.ts +3 -3
- package/dist/token-store.d.ts.map +1 -1
- package/dist/token-store.js +8 -8
- package/dist/token-store.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -29,6 +29,10 @@ pi install npm:pi-cloudflare # once published
|
|
|
29
29
|
pi install /path/to/pi-cloudflare # from source
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
+
Tools and skills register on the **next** session start. `web-perf` is
|
|
33
|
+
intentionally not vendored: keep your local customized copy (upstream would
|
|
34
|
+
clobber environment-specific rules).
|
|
35
|
+
|
|
32
36
|
Tools and skills register on the **next** session start.
|
|
33
37
|
|
|
34
38
|
## Authenticate (one-time browser OAuth)
|
|
@@ -65,3 +69,9 @@ In `~/.pi/agent/settings.json`:
|
|
|
65
69
|
npm install
|
|
66
70
|
npm test # typecheck + unit tests (mocked, no network)
|
|
67
71
|
```
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
MIT for this package's own code (see LICENSE). Vendored skill content
|
|
76
|
+
under `skills/` remains under its upstream Apache License, Version 2.0
|
|
77
|
+
(see NOTICE).
|
package/bin/setup.mjs
CHANGED
|
@@ -12,92 +12,92 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Nothing secret is ever logged or written anywhere else.
|
|
14
14
|
*/
|
|
15
|
-
import { connectAll } from
|
|
16
|
-
import { CLOUDFLARE_SERVERS } from
|
|
17
|
-
import { runOAuthFlow } from
|
|
18
|
-
import { partitionServers, readTokenFile, writeTokenFile } from
|
|
15
|
+
import { connectAll } from "../dist/client.js";
|
|
16
|
+
import { CLOUDFLARE_SERVERS } from "../dist/servers.js";
|
|
17
|
+
import { runOAuthFlow } from "../dist/auth-flow.js";
|
|
18
|
+
import { partitionServers, readTokenFile, writeTokenFile } from "../dist/token-store.js";
|
|
19
19
|
|
|
20
|
-
const AUTHED_IDS = [
|
|
20
|
+
const AUTHED_IDS = ["api", "bindings", "builds", "observability"];
|
|
21
21
|
|
|
22
22
|
function argValue(flag) {
|
|
23
|
-
const index = process.argv.indexOf(flag)
|
|
24
|
-
return index >= 0 && index + 1 < process.argv.length ? process.argv[index + 1] : undefined
|
|
23
|
+
const index = process.argv.indexOf(flag);
|
|
24
|
+
return index >= 0 && index + 1 < process.argv.length ? process.argv[index + 1] : undefined;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function parseOnly() {
|
|
28
|
-
const raw = argValue(
|
|
29
|
-
if (!raw) return undefined
|
|
28
|
+
const raw = argValue("--only");
|
|
29
|
+
if (!raw) return undefined;
|
|
30
30
|
const ids = raw
|
|
31
|
-
.split(
|
|
31
|
+
.split(",")
|
|
32
32
|
.map((id) => id.trim())
|
|
33
|
-
.filter(Boolean)
|
|
34
|
-
const unknown = ids.filter((id) => !AUTHED_IDS.includes(id))
|
|
33
|
+
.filter(Boolean);
|
|
34
|
+
const unknown = ids.filter((id) => !AUTHED_IDS.includes(id));
|
|
35
35
|
if (unknown.length > 0) {
|
|
36
|
-
console.log(`Unknown server(s): ${unknown.join(
|
|
37
|
-
process.exit(2)
|
|
36
|
+
console.log(`Unknown server(s): ${unknown.join(", ")}. Choose from: ${AUTHED_IDS.join(", ")}`);
|
|
37
|
+
process.exit(2);
|
|
38
38
|
}
|
|
39
|
-
return ids
|
|
39
|
+
return ids;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const only = parseOnly()
|
|
43
|
-
const wanted = only ?? AUTHED_IDS
|
|
44
|
-
const file = readTokenFile() ?? { version: 1, servers: {} }
|
|
45
|
-
const { fresh, needed } = partitionServers(wanted, file.servers)
|
|
42
|
+
const only = parseOnly();
|
|
43
|
+
const wanted = only ?? AUTHED_IDS;
|
|
44
|
+
const file = readTokenFile() ?? { version: 1, servers: {} };
|
|
45
|
+
const { fresh, needed } = partitionServers(wanted, file.servers);
|
|
46
46
|
|
|
47
47
|
if (fresh.length > 0) {
|
|
48
|
-
console.log(`Already authorized (skipping): ${fresh.join(
|
|
48
|
+
console.log(`Already authorized (skipping): ${fresh.join(", ")}\n`);
|
|
49
49
|
}
|
|
50
50
|
if (needed.length === 0) {
|
|
51
|
-
console.log(
|
|
51
|
+
console.log("All requested servers already authorized. Verifying...\n");
|
|
52
52
|
} else {
|
|
53
53
|
console.log(
|
|
54
|
-
`Browser OAuth: ${needed.length} approval tab${needed.length === 1 ?
|
|
55
|
-
`(${needed.join(
|
|
56
|
-
)
|
|
57
|
-
let index = 0
|
|
54
|
+
`Browser OAuth: ${needed.length} approval tab${needed.length === 1 ? "" : "s"} ` +
|
|
55
|
+
`(${needed.join(", ")}). Approve each; tokens stay on this machine.\n`
|
|
56
|
+
);
|
|
57
|
+
let index = 0;
|
|
58
58
|
for (const id of needed) {
|
|
59
|
-
index += 1
|
|
60
|
-
const definition = CLOUDFLARE_SERVERS.find((server) => server.id === id)
|
|
61
|
-
console.log(`[${index}/${needed.length}] Approving ${id} (${definition.url})...`)
|
|
59
|
+
index += 1;
|
|
60
|
+
const definition = CLOUDFLARE_SERVERS.find((server) => server.id === id);
|
|
61
|
+
console.log(`[${index}/${needed.length}] Approving ${id} (${definition.url})...`);
|
|
62
62
|
try {
|
|
63
|
-
const { tokens, clientId, tokenEndpoint } = await runOAuthFlow(definition)
|
|
64
|
-
file.servers[id] = { ...tokens, clientId, tokenEndpoint }
|
|
65
|
-
writeTokenFile(file.servers)
|
|
66
|
-
console.log(`[${index}/${needed.length}] ${id}: authorized and stored\n`)
|
|
63
|
+
const { tokens, clientId, tokenEndpoint } = await runOAuthFlow(definition);
|
|
64
|
+
file.servers[id] = { ...tokens, clientId, tokenEndpoint };
|
|
65
|
+
writeTokenFile(file.servers);
|
|
66
|
+
console.log(`[${index}/${needed.length}] ${id}: authorized and stored\n`);
|
|
67
67
|
} catch (error) {
|
|
68
68
|
console.log(
|
|
69
69
|
`[${index}/${needed.length}] ${id}: FAILED (${error instanceof Error ? error.message : String(error)})\n`
|
|
70
|
-
)
|
|
70
|
+
);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
console.log(
|
|
76
|
-
const stored = readTokenFile()
|
|
77
|
-
let okCount = 0
|
|
78
|
-
const failed = []
|
|
75
|
+
console.log("Verifying all servers...\n");
|
|
76
|
+
const stored = readTokenFile();
|
|
77
|
+
let okCount = 0;
|
|
78
|
+
const failed = [];
|
|
79
79
|
for (const definition of CLOUDFLARE_SERVERS) {
|
|
80
|
-
const token = stored?.servers[definition.id]?.accessToken
|
|
81
|
-
const [connection] = await connectAll([definition], { apiToken: token, timeoutMs: 20000 })
|
|
80
|
+
const token = stored?.servers[definition.id]?.accessToken;
|
|
81
|
+
const [connection] = await connectAll([definition], { apiToken: token, timeoutMs: 20000 });
|
|
82
82
|
if (!connection) {
|
|
83
|
-
console.log(`- ${definition.id}: unreachable`)
|
|
84
|
-
if (AUTHED_IDS.includes(definition.id)) failed.push(definition.id)
|
|
85
|
-
continue
|
|
83
|
+
console.log(`- ${definition.id}: unreachable`);
|
|
84
|
+
if (AUTHED_IDS.includes(definition.id)) failed.push(definition.id);
|
|
85
|
+
continue;
|
|
86
86
|
}
|
|
87
87
|
try {
|
|
88
|
-
const tools = await connection.listTools()
|
|
89
|
-
console.log(`- ${definition.id}: OK (${tools.length} tools)`)
|
|
90
|
-
okCount += 1
|
|
88
|
+
const tools = await connection.listTools();
|
|
89
|
+
console.log(`- ${definition.id}: OK (${tools.length} tools)`);
|
|
90
|
+
okCount += 1;
|
|
91
91
|
} catch {
|
|
92
|
-
console.log(`- ${definition.id}: connected but tool discovery failed`)
|
|
93
|
-
if (AUTHED_IDS.includes(definition.id)) failed.push(definition.id)
|
|
92
|
+
console.log(`- ${definition.id}: connected but tool discovery failed`);
|
|
93
|
+
if (AUTHED_IDS.includes(definition.id)) failed.push(definition.id);
|
|
94
94
|
} finally {
|
|
95
|
-
await connection.close()
|
|
95
|
+
await connection.close();
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
console.log(`\n${okCount}/5 servers working.`)
|
|
99
|
+
console.log(`\n${okCount}/5 servers working.`);
|
|
100
100
|
if (failed.length > 0) {
|
|
101
|
-
console.log(`Re-authenticate with: pi-cloudflare-setup --only ${failed.join(
|
|
102
|
-
process.exit(1)
|
|
101
|
+
console.log(`Re-authenticate with: pi-cloudflare-setup --only ${failed.join(",")}`);
|
|
102
|
+
process.exit(1);
|
|
103
103
|
}
|
package/dist/auth-flow.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type OAuthTokens } from
|
|
2
|
-
import type { CloudflareServerDefinition } from
|
|
1
|
+
import { type OAuthTokens } from "./oauth.js";
|
|
2
|
+
import type { CloudflareServerDefinition } from "./servers.js";
|
|
3
3
|
export interface OAuthFlowResult {
|
|
4
4
|
tokens: OAuthTokens;
|
|
5
5
|
clientId: string;
|
package/dist/auth-flow.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-flow.d.ts","sourceRoot":"","sources":["../src/auth-flow.ts"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"auth-flow.d.ts","sourceRoot":"","sources":["../src/auth-flow.ts"],"names":[],"mappings":"AAGA,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE/D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAkDD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,0BAA0B,EACtC,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,OAAO,CAAC,eAAe,CAAC,CA0C1B"}
|
package/dist/auth-flow.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
import { createServer } from
|
|
2
|
-
import { spawn } from
|
|
3
|
-
import { buildAuthorizeUrl, discoverAuthServer, exchangeCode, generatePkcePair, generateState, registerClient, } from
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { buildAuthorizeUrl, discoverAuthServer, exchangeCode, generatePkcePair, generateState, registerClient, } from "./oauth.js";
|
|
4
4
|
function waitForCallback(server, expectedState, timeoutMs) {
|
|
5
5
|
return new Promise((resolve, reject) => {
|
|
6
6
|
const timer = setTimeout(() => {
|
|
7
7
|
server.close();
|
|
8
|
-
reject(new Error(
|
|
8
|
+
reject(new Error("Timed out waiting for browser approval (5 minutes)"));
|
|
9
9
|
}, timeoutMs);
|
|
10
|
-
server.on(
|
|
11
|
-
const url = new URL(request.url ??
|
|
12
|
-
response.writeHead(200, {
|
|
13
|
-
response.end(
|
|
10
|
+
server.on("request", (request, response) => {
|
|
11
|
+
const url = new URL(request.url ?? "/", "http://127.0.0.1");
|
|
12
|
+
response.writeHead(200, { "Content-Type": "text/html" });
|
|
13
|
+
response.end("<html><body><h1>Signed in.</h1><p>Return to your terminal; this window can be closed.</p></body></html>");
|
|
14
14
|
clearTimeout(timer);
|
|
15
15
|
server.close();
|
|
16
|
-
if (url.pathname !==
|
|
16
|
+
if (url.pathname !== "/callback") {
|
|
17
17
|
reject(new Error(`Unexpected callback path: ${url.pathname}`));
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
if (url.searchParams.get(
|
|
21
|
-
reject(new Error(
|
|
20
|
+
if (url.searchParams.get("state") !== expectedState) {
|
|
21
|
+
reject(new Error("State mismatch: possible cross-site request, aborting"));
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
-
const error = url.searchParams.get(
|
|
24
|
+
const error = url.searchParams.get("error");
|
|
25
25
|
if (error) {
|
|
26
26
|
reject(new Error(`Authorization failed: ${error}`));
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
|
-
const code = url.searchParams.get(
|
|
29
|
+
const code = url.searchParams.get("code");
|
|
30
30
|
if (!code) {
|
|
31
|
-
reject(new Error(
|
|
31
|
+
reject(new Error("Authorization response had no code"));
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
resolve(code);
|
|
@@ -36,8 +36,8 @@ function waitForCallback(server, expectedState, timeoutMs) {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
function openBrowser(url) {
|
|
39
|
-
const opener = process.platform ===
|
|
40
|
-
const child = spawn(opener, [url], { detached: true, stdio:
|
|
39
|
+
const opener = process.platform === "darwin" ? "open" : "xdg-open";
|
|
40
|
+
const child = spawn(opener, [url], { detached: true, stdio: "ignore" });
|
|
41
41
|
child.unref();
|
|
42
42
|
console.log(`Opened browser for approval. If nothing opened, visit:\n ${url}\n`);
|
|
43
43
|
}
|
|
@@ -52,13 +52,13 @@ export async function runOAuthFlow(definition, options = {}) {
|
|
|
52
52
|
}
|
|
53
53
|
const server = createServer();
|
|
54
54
|
await new Promise((resolve, reject) => {
|
|
55
|
-
server.once(
|
|
56
|
-
server.listen(0,
|
|
55
|
+
server.once("error", reject);
|
|
56
|
+
server.listen(0, "127.0.0.1", () => resolve());
|
|
57
57
|
});
|
|
58
58
|
const address = server.address();
|
|
59
|
-
if (!address || typeof address ===
|
|
59
|
+
if (!address || typeof address === "string") {
|
|
60
60
|
server.close();
|
|
61
|
-
throw new Error(
|
|
61
|
+
throw new Error("Could not bind localhost callback");
|
|
62
62
|
}
|
|
63
63
|
const redirectUri = `http://127.0.0.1:${address.port}/callback`;
|
|
64
64
|
try {
|
package/dist/auth-flow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-flow.js","sourceRoot":"","sources":["../src/auth-flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA6C,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"auth-flow.js","sourceRoot":"","sources":["../src/auth-flow.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Tool } from
|
|
2
|
-
import type { CloudflareServerDefinition } from
|
|
1
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import type { CloudflareServerDefinition } from "./servers.js";
|
|
3
3
|
export interface ServerConnection {
|
|
4
4
|
definition: CloudflareServerDefinition;
|
|
5
5
|
listTools: () => Promise<Tool[]>;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE/D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,0BAA0B,CAAC;IACvC,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACjC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5E,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAUD,wBAAsB,aAAa,CACjC,UAAU,EAAE,0BAA0B,EACtC,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAC5D,OAAO,CAAC,gBAAgB,CAAC,CA0B3B;AAED,+EAA+E;AAC/E,wBAAsB,UAAU,CAC9B,WAAW,EAAE,SAAS,0BAA0B,EAAE,EAClD,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC7D,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,GAC7C,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAY7B"}
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Client } from
|
|
2
|
-
import { StreamableHTTPClientTransport } from
|
|
1
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
3
3
|
function withTimeout(promise, ms, label) {
|
|
4
4
|
let timer;
|
|
5
5
|
const timeout = new Promise((_, reject) => {
|
|
@@ -10,11 +10,11 @@ function withTimeout(promise, ms, label) {
|
|
|
10
10
|
export async function connectServer(definition, options) {
|
|
11
11
|
const headers = {};
|
|
12
12
|
if (options.apiToken)
|
|
13
|
-
headers[
|
|
13
|
+
headers["Authorization"] = `Bearer ${options.apiToken}`;
|
|
14
14
|
const transport = new StreamableHTTPClientTransport(new URL(definition.url), {
|
|
15
15
|
requestInit: { headers },
|
|
16
16
|
});
|
|
17
|
-
const client = new Client({ name:
|
|
17
|
+
const client = new Client({ name: "pi-cloudflare", version: "0.1.0" }, { capabilities: {} });
|
|
18
18
|
const timeoutMs = options.timeoutMs;
|
|
19
19
|
await withTimeout(client.connect(transport), timeoutMs, `connect ${definition.id}`);
|
|
20
20
|
return {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CloudflareServerId } from
|
|
1
|
+
import type { CloudflareServerId } from "./servers.js";
|
|
2
2
|
export interface PiCloudflareConfig {
|
|
3
3
|
/** Per-server enablement. Omitted servers default to enabled. */
|
|
4
4
|
servers?: Partial<Record<CloudflareServerId, boolean>>;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,WAAW,kBAAkB;IACjC,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,0BAA0B;IACzC,gBAAgB,EAAE,kBAAkB,EAAE,CAAC;IACvC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAID,wBAAgB,aAAa,CAAC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GAAG,0BAA0B,CAQhG"}
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CLOUDFLARE_SERVERS } from
|
|
1
|
+
import { CLOUDFLARE_SERVERS } from "./servers.js";
|
|
2
2
|
const DEFAULT_CONNECT_TIMEOUT_MS = 30_000;
|
|
3
3
|
export function resolveConfig(config) {
|
|
4
4
|
const enabledServerIds = CLOUDFLARE_SERVERS.map((server) => server.id).filter((id) => config?.servers?.[id] !== false);
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAclD,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAE1C,MAAM,UAAU,aAAa,CAAC,MAAsC;IAClE,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAC3E,CAAC,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,KAAK,KAAK,CACxC,CAAC;IACF,OAAO;QACL,gBAAgB;QAChB,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,IAAI,0BAA0B;KACzE,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ interface PiToolDefinition {
|
|
|
7
7
|
}
|
|
8
8
|
interface PiHost {
|
|
9
9
|
registerTool: (definition: PiToolDefinition) => void;
|
|
10
|
-
on: (event:
|
|
10
|
+
on: (event: "session_start" | "session_shutdown", handler: (...args: never[]) => unknown) => void;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* pi-coding-agent extension entry point.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgBA,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,CACP,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,CAAC,EAAE,WAAW,KACjB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED,UAAU,MAAM;IACd,YAAY,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACrD,EAAE,EAAE,CAAC,KAAK,EAAE,eAAe,GAAG,kBAAkB,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,KAAK,IAAI,CAAC;CACnG;AAgDD;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAwD9D"}
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { homedir } from
|
|
2
|
-
import { join } from
|
|
3
|
-
import { readFileSync } from
|
|
4
|
-
import { connectServer } from
|
|
5
|
-
import { refreshAccessToken } from
|
|
6
|
-
import { resolveConfig } from
|
|
7
|
-
import { buildAllRegistrations } from
|
|
8
|
-
import { CLOUDFLARE_SERVERS } from
|
|
9
|
-
import { isExpired, readTokenFile, writeTokenFile } from
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { connectServer } from "./client.js";
|
|
5
|
+
import { refreshAccessToken } from "./oauth.js";
|
|
6
|
+
import { resolveConfig } from "./config.js";
|
|
7
|
+
import { buildAllRegistrations } from "./proxy.js";
|
|
8
|
+
import { CLOUDFLARE_SERVERS } from "./servers.js";
|
|
9
|
+
import { isExpired, readTokenFile, writeTokenFile, } from "./token-store.js";
|
|
10
10
|
function loadUserConfig() {
|
|
11
11
|
try {
|
|
12
|
-
const raw = readFileSync(join(homedir(),
|
|
12
|
+
const raw = readFileSync(join(homedir(), ".pi", "agent", "settings.json"), "utf8");
|
|
13
13
|
const parsed = JSON.parse(raw);
|
|
14
|
-
return parsed[
|
|
14
|
+
return parsed["pi-cloudflare"];
|
|
15
15
|
}
|
|
16
16
|
catch {
|
|
17
17
|
return undefined;
|
|
@@ -55,7 +55,7 @@ async function ensureFreshToken(entry) {
|
|
|
55
55
|
*/
|
|
56
56
|
export default function piCloudflareExtension(pi) {
|
|
57
57
|
let entries = [];
|
|
58
|
-
pi.on(
|
|
58
|
+
pi.on("session_start", async () => {
|
|
59
59
|
for (const entry of entries) {
|
|
60
60
|
await entry.connection?.close().catch(() => undefined);
|
|
61
61
|
}
|
|
@@ -101,7 +101,7 @@ export default function piCloudflareExtension(pi) {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
});
|
|
104
|
-
pi.on(
|
|
104
|
+
pi.on("session_shutdown", async () => {
|
|
105
105
|
await Promise.all(entries.map((entry) => entry.connection?.close().catch(() => undefined)));
|
|
106
106
|
entries = [];
|
|
107
107
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/oauth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAUD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,gBAAgB,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAG1E;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAUD,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAmCrF;AAED,wBAAsB,cAAc,CAClC,oBAAoB,EAAE,MAAM,EAC5B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAiB3B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAWT;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,WAAW,CAAC,CAiBvB;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,WAAW,CAAC,CAmBvB"}
|
package/dist/oauth.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { randomBytes, createHash } from
|
|
1
|
+
import { randomBytes, createHash } from "node:crypto";
|
|
2
2
|
function base64Url(bytes) {
|
|
3
3
|
return Buffer.from(bytes)
|
|
4
|
-
.toString(
|
|
5
|
-
.replace(/\+/g,
|
|
6
|
-
.replace(/\//g,
|
|
7
|
-
.replace(/=+$/,
|
|
4
|
+
.toString("base64")
|
|
5
|
+
.replace(/\+/g, "-")
|
|
6
|
+
.replace(/\//g, "_")
|
|
7
|
+
.replace(/=+$/, "");
|
|
8
8
|
}
|
|
9
9
|
export function pkceChallengeFor(verifier) {
|
|
10
|
-
return base64Url(createHash(
|
|
10
|
+
return base64Url(createHash("sha256").update(verifier).digest());
|
|
11
11
|
}
|
|
12
12
|
export function generatePkcePair() {
|
|
13
13
|
const verifier = base64Url(randomBytes(32));
|
|
@@ -17,7 +17,7 @@ export function generateState() {
|
|
|
17
17
|
return base64Url(randomBytes(16));
|
|
18
18
|
}
|
|
19
19
|
async function fetchJson(url) {
|
|
20
|
-
const response = await fetch(url, { headers: { Accept:
|
|
20
|
+
const response = await fetch(url, { headers: { Accept: "application/json" } });
|
|
21
21
|
if (!response.ok) {
|
|
22
22
|
throw new Error(`GET ${url} failed with ${response.status}`);
|
|
23
23
|
}
|
|
@@ -25,14 +25,14 @@ async function fetchJson(url) {
|
|
|
25
25
|
}
|
|
26
26
|
export async function discoverAuthServer(mcpUrl) {
|
|
27
27
|
const challenge = await fetch(mcpUrl, {
|
|
28
|
-
method:
|
|
29
|
-
headers: {
|
|
30
|
-
body: JSON.stringify({ jsonrpc:
|
|
28
|
+
method: "POST",
|
|
29
|
+
headers: { "Content-Type": "application/json" },
|
|
30
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "ping" }),
|
|
31
31
|
});
|
|
32
32
|
if (challenge.status !== 401) {
|
|
33
33
|
throw new Error(`Expected 401 auth challenge from ${mcpUrl}, got ${challenge.status}`);
|
|
34
34
|
}
|
|
35
|
-
const wwwAuth = challenge.headers.get(
|
|
35
|
+
const wwwAuth = challenge.headers.get("www-authenticate") ?? "";
|
|
36
36
|
const metadataUrl = /resource_metadata="([^"]+)"/.exec(wwwAuth)?.[1];
|
|
37
37
|
if (!metadataUrl)
|
|
38
38
|
throw new Error(`No resource metadata advertised by ${mcpUrl}`);
|
|
@@ -40,7 +40,7 @@ export async function discoverAuthServer(mcpUrl) {
|
|
|
40
40
|
const issuer = resource.authorization_servers?.[0];
|
|
41
41
|
if (!issuer)
|
|
42
42
|
throw new Error(`No authorization server advertised by ${mcpUrl}`);
|
|
43
|
-
const metadata = (await fetchJson(`${issuer.replace(/\/$/,
|
|
43
|
+
const metadata = (await fetchJson(`${issuer.replace(/\/$/, "")}/.well-known/oauth-authorization-server`));
|
|
44
44
|
if (!metadata.authorization_endpoint || !metadata.token_endpoint) {
|
|
45
45
|
throw new Error(`Incomplete OAuth metadata from ${issuer}`);
|
|
46
46
|
}
|
|
@@ -53,13 +53,13 @@ export async function discoverAuthServer(mcpUrl) {
|
|
|
53
53
|
}
|
|
54
54
|
export async function registerClient(registrationEndpoint, redirectUri) {
|
|
55
55
|
const response = await fetch(registrationEndpoint, {
|
|
56
|
-
method:
|
|
57
|
-
headers: {
|
|
56
|
+
method: "POST",
|
|
57
|
+
headers: { "Content-Type": "application/json" },
|
|
58
58
|
body: JSON.stringify({
|
|
59
59
|
redirect_uris: [redirectUri],
|
|
60
|
-
grant_types: [
|
|
61
|
-
token_endpoint_auth_method:
|
|
62
|
-
client_name:
|
|
60
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
61
|
+
token_endpoint_auth_method: "none",
|
|
62
|
+
client_name: "pi-cloudflare",
|
|
63
63
|
}),
|
|
64
64
|
});
|
|
65
65
|
if (!response.ok) {
|
|
@@ -67,16 +67,16 @@ export async function registerClient(registrationEndpoint, redirectUri) {
|
|
|
67
67
|
}
|
|
68
68
|
const body = (await response.json());
|
|
69
69
|
if (!body.client_id)
|
|
70
|
-
throw new Error(
|
|
70
|
+
throw new Error("Registration response had no client_id");
|
|
71
71
|
return { clientId: body.client_id, tokenEndpoint: registrationEndpoint };
|
|
72
72
|
}
|
|
73
73
|
export function buildAuthorizeUrl(options) {
|
|
74
74
|
const params = new URLSearchParams({
|
|
75
|
-
response_type:
|
|
75
|
+
response_type: "code",
|
|
76
76
|
client_id: options.clientId,
|
|
77
77
|
redirect_uri: options.redirectUri,
|
|
78
78
|
code_challenge: options.challenge,
|
|
79
|
-
code_challenge_method:
|
|
79
|
+
code_challenge_method: "S256",
|
|
80
80
|
state: options.state,
|
|
81
81
|
resource: options.resource,
|
|
82
82
|
});
|
|
@@ -84,15 +84,15 @@ export function buildAuthorizeUrl(options) {
|
|
|
84
84
|
}
|
|
85
85
|
export async function exchangeCode(options) {
|
|
86
86
|
const body = new URLSearchParams({
|
|
87
|
-
grant_type:
|
|
87
|
+
grant_type: "authorization_code",
|
|
88
88
|
client_id: options.clientId,
|
|
89
89
|
code: options.code,
|
|
90
90
|
redirect_uri: options.redirectUri,
|
|
91
91
|
code_verifier: options.verifier,
|
|
92
92
|
});
|
|
93
93
|
const response = await fetch(options.tokenEndpoint, {
|
|
94
|
-
method:
|
|
95
|
-
headers: {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
96
96
|
body: body.toString(),
|
|
97
97
|
});
|
|
98
98
|
if (!response.ok) {
|
|
@@ -102,13 +102,13 @@ export async function exchangeCode(options) {
|
|
|
102
102
|
}
|
|
103
103
|
export async function refreshAccessToken(options) {
|
|
104
104
|
const body = new URLSearchParams({
|
|
105
|
-
grant_type:
|
|
105
|
+
grant_type: "refresh_token",
|
|
106
106
|
client_id: options.clientId,
|
|
107
107
|
refresh_token: options.refreshToken,
|
|
108
108
|
});
|
|
109
109
|
const response = await fetch(options.tokenEndpoint, {
|
|
110
|
-
method:
|
|
111
|
-
headers: {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
112
112
|
body: body.toString(),
|
|
113
113
|
});
|
|
114
114
|
if (!response.ok) {
|
|
@@ -122,13 +122,13 @@ export async function refreshAccessToken(options) {
|
|
|
122
122
|
}
|
|
123
123
|
function readTokens(body) {
|
|
124
124
|
const record = body;
|
|
125
|
-
if (typeof record.access_token !==
|
|
126
|
-
throw new Error(
|
|
125
|
+
if (typeof record.access_token !== "string" || !record.access_token) {
|
|
126
|
+
throw new Error("Token response had no access_token");
|
|
127
127
|
}
|
|
128
|
-
const lifetime = typeof record.expires_in ===
|
|
128
|
+
const lifetime = typeof record.expires_in === "number" ? record.expires_in : 3600;
|
|
129
129
|
return {
|
|
130
130
|
accessToken: record.access_token,
|
|
131
|
-
refreshToken: typeof record.refresh_token ===
|
|
131
|
+
refreshToken: typeof record.refresh_token === "string" ? record.refresh_token : undefined,
|
|
132
132
|
expiresAt: Date.now() + Math.max(lifetime - 60, 0) * 1000,
|
|
133
133
|
};
|
|
134
134
|
}
|