postgresai 0.11.0-alpha.12 → 0.11.0-alpha.13
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/README.md +39 -0
- package/bin/postgres-ai.ts +107 -18
- package/dist/bin/postgres-ai.js +97 -19
- package/dist/bin/postgres-ai.js.map +1 -1
- package/dist/lib/auth-server.js +8 -8
- package/dist/lib/issues.d.ts +7 -0
- package/dist/lib/issues.d.ts.map +1 -0
- package/dist/lib/issues.js +105 -0
- package/dist/lib/issues.js.map +1 -0
- package/dist/lib/mcp-server.d.ts +9 -0
- package/dist/lib/mcp-server.d.ts.map +1 -0
- package/dist/lib/mcp-server.js +114 -0
- package/dist/lib/mcp-server.js.map +1 -0
- package/dist/lib/util.d.ts +27 -0
- package/dist/lib/util.d.ts.map +1 -0
- package/dist/lib/util.js +46 -0
- package/dist/lib/util.js.map +1 -0
- package/dist/package.json +3 -2
- package/lib/auth-server.ts +8 -8
- package/lib/issues.ts +83 -0
- package/lib/mcp-server.ts +98 -0
- package/lib/util.ts +60 -0
- package/package.json +3 -2
- package/tsconfig.json +2 -2
package/dist/lib/auth-server.js
CHANGED
|
@@ -105,7 +105,7 @@ function createCallbackServer(port = 0, expectedState = null, timeoutMs = 300000
|
|
|
105
105
|
<!DOCTYPE html>
|
|
106
106
|
<html>
|
|
107
107
|
<head>
|
|
108
|
-
<title>Authentication
|
|
108
|
+
<title>Authentication failed</title>
|
|
109
109
|
<style>
|
|
110
110
|
body { font-family: system-ui, -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
|
|
111
111
|
.error { background: #fee; border: 1px solid #fcc; padding: 20px; border-radius: 8px; }
|
|
@@ -115,7 +115,7 @@ function createCallbackServer(port = 0, expectedState = null, timeoutMs = 300000
|
|
|
115
115
|
</head>
|
|
116
116
|
<body>
|
|
117
117
|
<div class="error">
|
|
118
|
-
<h1>Authentication
|
|
118
|
+
<h1>Authentication failed</h1>
|
|
119
119
|
<p><strong>Error:</strong> ${escapeHtml(error)}</p>
|
|
120
120
|
${errorDescription ? `<p><strong>Description:</strong> ${escapeHtml(errorDescription)}</p>` : ""}
|
|
121
121
|
<p>You can close this window and return to your terminal.</p>
|
|
@@ -136,7 +136,7 @@ function createCallbackServer(port = 0, expectedState = null, timeoutMs = 300000
|
|
|
136
136
|
<!DOCTYPE html>
|
|
137
137
|
<html>
|
|
138
138
|
<head>
|
|
139
|
-
<title>Authentication
|
|
139
|
+
<title>Authentication failed</title>
|
|
140
140
|
<style>
|
|
141
141
|
body { font-family: system-ui, -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
|
|
142
142
|
.error { background: #fee; border: 1px solid #fcc; padding: 20px; border-radius: 8px; }
|
|
@@ -145,7 +145,7 @@ function createCallbackServer(port = 0, expectedState = null, timeoutMs = 300000
|
|
|
145
145
|
</head>
|
|
146
146
|
<body>
|
|
147
147
|
<div class="error">
|
|
148
|
-
<h1>Authentication
|
|
148
|
+
<h1>Authentication failed</h1>
|
|
149
149
|
<p>Missing required parameters (code or state).</p>
|
|
150
150
|
<p>You can close this window and return to your terminal.</p>
|
|
151
151
|
</div>
|
|
@@ -163,7 +163,7 @@ function createCallbackServer(port = 0, expectedState = null, timeoutMs = 300000
|
|
|
163
163
|
<!DOCTYPE html>
|
|
164
164
|
<html>
|
|
165
165
|
<head>
|
|
166
|
-
<title>Authentication
|
|
166
|
+
<title>Authentication failed</title>
|
|
167
167
|
<style>
|
|
168
168
|
body { font-family: system-ui, -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
|
|
169
169
|
.error { background: #fee; border: 1px solid #fcc; padding: 20px; border-radius: 8px; }
|
|
@@ -172,7 +172,7 @@ function createCallbackServer(port = 0, expectedState = null, timeoutMs = 300000
|
|
|
172
172
|
</head>
|
|
173
173
|
<body>
|
|
174
174
|
<div class="error">
|
|
175
|
-
<h1>Authentication
|
|
175
|
+
<h1>Authentication failed</h1>
|
|
176
176
|
<p>Invalid state parameter (possible CSRF attack).</p>
|
|
177
177
|
<p>You can close this window and return to your terminal.</p>
|
|
178
178
|
</div>
|
|
@@ -193,7 +193,7 @@ function createCallbackServer(port = 0, expectedState = null, timeoutMs = 300000
|
|
|
193
193
|
<!DOCTYPE html>
|
|
194
194
|
<html>
|
|
195
195
|
<head>
|
|
196
|
-
<title>Authentication
|
|
196
|
+
<title>Authentication successful</title>
|
|
197
197
|
<style>
|
|
198
198
|
body { font-family: system-ui, -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
|
|
199
199
|
.success { background: #efe; border: 1px solid #cfc; padding: 20px; border-radius: 8px; }
|
|
@@ -202,7 +202,7 @@ function createCallbackServer(port = 0, expectedState = null, timeoutMs = 300000
|
|
|
202
202
|
</head>
|
|
203
203
|
<body>
|
|
204
204
|
<div class="success">
|
|
205
|
-
<h1>Authentication
|
|
205
|
+
<h1>Authentication successful</h1>
|
|
206
206
|
<p>You have successfully authenticated the PostgresAI CLI.</p>
|
|
207
207
|
<p>You can close this window and return to your terminal.</p>
|
|
208
208
|
</div>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issues.d.ts","sourceRoot":"","sources":["../../lib/issues.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAsE7E"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.fetchIssues = fetchIssues;
|
|
37
|
+
const https = __importStar(require("https"));
|
|
38
|
+
const url_1 = require("url");
|
|
39
|
+
const util_1 = require("./util");
|
|
40
|
+
async function fetchIssues(params) {
|
|
41
|
+
const { apiKey, apiBaseUrl, debug } = params;
|
|
42
|
+
if (!apiKey) {
|
|
43
|
+
throw new Error("API key is required");
|
|
44
|
+
}
|
|
45
|
+
const base = (0, util_1.normalizeBaseUrl)(apiBaseUrl);
|
|
46
|
+
const url = new url_1.URL(`${base}/issues`);
|
|
47
|
+
const headers = {
|
|
48
|
+
"access-token": apiKey,
|
|
49
|
+
"Prefer": "return=representation",
|
|
50
|
+
"Content-Type": "application/json",
|
|
51
|
+
};
|
|
52
|
+
if (debug) {
|
|
53
|
+
const debugHeaders = { ...headers, "access-token": (0, util_1.maskSecret)(apiKey) };
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
56
|
+
// eslint-disable-next-line no-console
|
|
57
|
+
console.log(`Debug: GET URL: ${url.toString()}`);
|
|
58
|
+
// eslint-disable-next-line no-console
|
|
59
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
62
|
+
}
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
const req = https.request(url, {
|
|
65
|
+
method: "GET",
|
|
66
|
+
headers,
|
|
67
|
+
}, (res) => {
|
|
68
|
+
let data = "";
|
|
69
|
+
res.on("data", (chunk) => (data += chunk));
|
|
70
|
+
res.on("end", () => {
|
|
71
|
+
if (debug) {
|
|
72
|
+
// eslint-disable-next-line no-console
|
|
73
|
+
console.log(`Debug: Response status: ${res.statusCode}`);
|
|
74
|
+
// eslint-disable-next-line no-console
|
|
75
|
+
console.log(`Debug: Response headers: ${JSON.stringify(res.headers)}`);
|
|
76
|
+
}
|
|
77
|
+
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
78
|
+
try {
|
|
79
|
+
const parsed = JSON.parse(data);
|
|
80
|
+
resolve(parsed);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
resolve(data);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
let errMsg = `Failed to fetch issues: HTTP ${res.statusCode}`;
|
|
88
|
+
if (data) {
|
|
89
|
+
try {
|
|
90
|
+
const errObj = JSON.parse(data);
|
|
91
|
+
errMsg += `\n${JSON.stringify(errObj, null, 2)}`;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
errMsg += `\n${data}`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
reject(new Error(errMsg));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
req.on("error", (err) => reject(err));
|
|
102
|
+
req.end();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=issues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issues.js","sourceRoot":"","sources":["../../lib/issues.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../lib/mcp-server.ts"],"names":[],"mappings":"AAUA,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,cAAc,CAAC,QAAQ,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFxG"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.startMcpServer = startMcpServer;
|
|
37
|
+
const pkg = __importStar(require("../package.json"));
|
|
38
|
+
const config = __importStar(require("./config"));
|
|
39
|
+
const issues_1 = require("./issues");
|
|
40
|
+
const util_1 = require("./util");
|
|
41
|
+
// MCP SDK imports
|
|
42
|
+
const server_1 = require("@modelcontextprotocol/sdk/server");
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
async function startMcpServer(rootOpts, extra) {
|
|
45
|
+
// Resolve stdio transport at runtime to avoid subpath export resolution issues
|
|
46
|
+
const serverEntry = require.resolve("@modelcontextprotocol/sdk/server");
|
|
47
|
+
const stdioPath = path.join(path.dirname(serverEntry), "stdio.js");
|
|
48
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
49
|
+
const { StdioServerTransport } = require(stdioPath);
|
|
50
|
+
// Load schemas dynamically to avoid subpath export resolution issues
|
|
51
|
+
const typesPath = path.resolve(path.dirname(serverEntry), "../types.js");
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
53
|
+
const { CallToolRequestSchema, ListToolsRequestSchema } = require(typesPath);
|
|
54
|
+
const server = new server_1.Server({ name: "postgresai-mcp", version: pkg.version }, { capabilities: { tools: {} } });
|
|
55
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
56
|
+
return {
|
|
57
|
+
tools: [
|
|
58
|
+
{
|
|
59
|
+
name: "list_issues",
|
|
60
|
+
description: "List issues from PostgresAI API (same as CLI 'issues list')",
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {
|
|
64
|
+
debug: { type: "boolean", description: "Enable verbose debug logs" },
|
|
65
|
+
},
|
|
66
|
+
additionalProperties: false,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
73
|
+
const toolName = req.params.name;
|
|
74
|
+
const args = req.params.arguments || {};
|
|
75
|
+
if (toolName !== "list_issues") {
|
|
76
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
77
|
+
}
|
|
78
|
+
const cfg = config.readConfig();
|
|
79
|
+
const apiKey = (rootOpts?.apiKey || process.env.PGAI_API_KEY || cfg.apiKey || "").toString();
|
|
80
|
+
const { apiBaseUrl } = (0, util_1.resolveBaseUrls)(rootOpts, cfg);
|
|
81
|
+
const debug = Boolean(args.debug ?? extra?.debug);
|
|
82
|
+
if (!apiKey) {
|
|
83
|
+
return {
|
|
84
|
+
content: [
|
|
85
|
+
{
|
|
86
|
+
type: "text",
|
|
87
|
+
text: "API key is required. Run 'pgai auth' or set PGAI_API_KEY.",
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
isError: true,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const result = await (0, issues_1.fetchIssues)({ apiKey, apiBaseUrl, debug });
|
|
95
|
+
return {
|
|
96
|
+
content: [
|
|
97
|
+
{ type: "text", text: JSON.stringify(result, null, 2) },
|
|
98
|
+
],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
103
|
+
return {
|
|
104
|
+
content: [
|
|
105
|
+
{ type: "text", text: message },
|
|
106
|
+
],
|
|
107
|
+
isError: true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
const transport = new StdioServerTransport();
|
|
112
|
+
await server.connect(transport);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../lib/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare function maskSecret(secret: string): string;
|
|
2
|
+
export interface RootOptsLike {
|
|
3
|
+
apiBaseUrl?: string;
|
|
4
|
+
uiBaseUrl?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ConfigLike {
|
|
7
|
+
baseUrl?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface ResolvedBaseUrls {
|
|
10
|
+
apiBaseUrl: string;
|
|
11
|
+
uiBaseUrl: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Normalize a base URL by trimming a single trailing slash and validating.
|
|
15
|
+
* @throws Error if the URL is invalid
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeBaseUrl(value: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Resolve API and UI base URLs using precedence and normalize them.
|
|
20
|
+
* Precedence (API): opts.apiBaseUrl → env.PGAI_API_BASE_URL → cfg.baseUrl → default
|
|
21
|
+
* Precedence (UI): opts.uiBaseUrl → env.PGAI_UI_BASE_URL → default
|
|
22
|
+
*/
|
|
23
|
+
export declare function resolveBaseUrls(opts?: RootOptsLike, cfg?: ConfigLike, defaults?: {
|
|
24
|
+
apiBaseUrl?: string;
|
|
25
|
+
uiBaseUrl?: string;
|
|
26
|
+
}): ResolvedBaseUrls;
|
|
27
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../lib/util.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKjD;AAGD,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,CAAC,EAAE,YAAY,EACnB,GAAG,CAAC,EAAE,UAAU,EAChB,QAAQ,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACzD,gBAAgB,CAWlB"}
|
package/dist/lib/util.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.maskSecret = maskSecret;
|
|
4
|
+
exports.normalizeBaseUrl = normalizeBaseUrl;
|
|
5
|
+
exports.resolveBaseUrls = resolveBaseUrls;
|
|
6
|
+
function maskSecret(secret) {
|
|
7
|
+
if (!secret)
|
|
8
|
+
return "";
|
|
9
|
+
if (secret.length <= 8)
|
|
10
|
+
return "****";
|
|
11
|
+
if (secret.length <= 16)
|
|
12
|
+
return `${secret.slice(0, 4)}${"*".repeat(secret.length - 8)}${secret.slice(-4)}`;
|
|
13
|
+
return `${secret.slice(0, Math.min(12, secret.length - 8))}${"*".repeat(Math.max(4, secret.length - 16))}${secret.slice(-4)}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Normalize a base URL by trimming a single trailing slash and validating.
|
|
17
|
+
* @throws Error if the URL is invalid
|
|
18
|
+
*/
|
|
19
|
+
function normalizeBaseUrl(value) {
|
|
20
|
+
const trimmed = (value || "").replace(/\/$/, "");
|
|
21
|
+
try {
|
|
22
|
+
// Validate
|
|
23
|
+
// eslint-disable-next-line no-new
|
|
24
|
+
new URL(trimmed);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
throw new Error(`Invalid base URL: ${value}`);
|
|
28
|
+
}
|
|
29
|
+
return trimmed;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Resolve API and UI base URLs using precedence and normalize them.
|
|
33
|
+
* Precedence (API): opts.apiBaseUrl → env.PGAI_API_BASE_URL → cfg.baseUrl → default
|
|
34
|
+
* Precedence (UI): opts.uiBaseUrl → env.PGAI_UI_BASE_URL → default
|
|
35
|
+
*/
|
|
36
|
+
function resolveBaseUrls(opts, cfg, defaults = {}) {
|
|
37
|
+
const defApi = defaults.apiBaseUrl || "https://postgres.ai/api/general/";
|
|
38
|
+
const defUi = defaults.uiBaseUrl || "https://console.postgres.ai";
|
|
39
|
+
const apiCandidate = (opts?.apiBaseUrl || process.env.PGAI_API_BASE_URL || cfg?.baseUrl || defApi);
|
|
40
|
+
const uiCandidate = (opts?.uiBaseUrl || process.env.PGAI_UI_BASE_URL || defUi);
|
|
41
|
+
return {
|
|
42
|
+
apiBaseUrl: normalizeBaseUrl(apiCandidate),
|
|
43
|
+
uiBaseUrl: normalizeBaseUrl(uiCandidate),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../lib/util.ts"],"names":[],"mappings":";;AAAA,gCAKC;AAqBD,4CAUC;AAOD,0CAeC;AA1DD,SAAgB,UAAU,CAAC,MAAc;IACvC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IACtC,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE;QAAE,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3G,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAChI,CAAC;AAiBD;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,WAAW;QACX,kCAAkC;QAClC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAC7B,IAAmB,EACnB,GAAgB,EAChB,WAAwD,EAAE;IAE1D,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,IAAI,kCAAkC,CAAC;IACzE,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,IAAI,6BAA6B,CAAC;IAElE,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,GAAG,EAAE,OAAO,IAAI,MAAM,CAAW,CAAC;IAC7G,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,KAAK,CAAW,CAAC;IAEzF,OAAO;QACL,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC;QAC1C,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC;KACzC,CAAC;AACJ,CAAC"}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "postgresai",
|
|
3
|
-
"version": "0.11.0-alpha.
|
|
3
|
+
"version": "0.11.0-alpha.13",
|
|
4
4
|
"description": "postgres_ai CLI (Node.js)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"private": false,
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"commander": "^12.1.0",
|
|
32
|
-
"js-yaml": "^4.1.0"
|
|
32
|
+
"js-yaml": "^4.1.0",
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.20.2"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@types/js-yaml": "^4.0.9",
|
package/lib/auth-server.ts
CHANGED
|
@@ -97,7 +97,7 @@ export function createCallbackServer(
|
|
|
97
97
|
<!DOCTYPE html>
|
|
98
98
|
<html>
|
|
99
99
|
<head>
|
|
100
|
-
<title>Authentication
|
|
100
|
+
<title>Authentication failed</title>
|
|
101
101
|
<style>
|
|
102
102
|
body { font-family: system-ui, -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
|
|
103
103
|
.error { background: #fee; border: 1px solid #fcc; padding: 20px; border-radius: 8px; }
|
|
@@ -107,7 +107,7 @@ export function createCallbackServer(
|
|
|
107
107
|
</head>
|
|
108
108
|
<body>
|
|
109
109
|
<div class="error">
|
|
110
|
-
<h1>Authentication
|
|
110
|
+
<h1>Authentication failed</h1>
|
|
111
111
|
<p><strong>Error:</strong> ${escapeHtml(error)}</p>
|
|
112
112
|
${errorDescription ? `<p><strong>Description:</strong> ${escapeHtml(errorDescription)}</p>` : ""}
|
|
113
113
|
<p>You can close this window and return to your terminal.</p>
|
|
@@ -130,7 +130,7 @@ export function createCallbackServer(
|
|
|
130
130
|
<!DOCTYPE html>
|
|
131
131
|
<html>
|
|
132
132
|
<head>
|
|
133
|
-
<title>Authentication
|
|
133
|
+
<title>Authentication failed</title>
|
|
134
134
|
<style>
|
|
135
135
|
body { font-family: system-ui, -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
|
|
136
136
|
.error { background: #fee; border: 1px solid #fcc; padding: 20px; border-radius: 8px; }
|
|
@@ -139,7 +139,7 @@ export function createCallbackServer(
|
|
|
139
139
|
</head>
|
|
140
140
|
<body>
|
|
141
141
|
<div class="error">
|
|
142
|
-
<h1>Authentication
|
|
142
|
+
<h1>Authentication failed</h1>
|
|
143
143
|
<p>Missing required parameters (code or state).</p>
|
|
144
144
|
<p>You can close this window and return to your terminal.</p>
|
|
145
145
|
</div>
|
|
@@ -159,7 +159,7 @@ export function createCallbackServer(
|
|
|
159
159
|
<!DOCTYPE html>
|
|
160
160
|
<html>
|
|
161
161
|
<head>
|
|
162
|
-
<title>Authentication
|
|
162
|
+
<title>Authentication failed</title>
|
|
163
163
|
<style>
|
|
164
164
|
body { font-family: system-ui, -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
|
|
165
165
|
.error { background: #fee; border: 1px solid #fcc; padding: 20px; border-radius: 8px; }
|
|
@@ -168,7 +168,7 @@ export function createCallbackServer(
|
|
|
168
168
|
</head>
|
|
169
169
|
<body>
|
|
170
170
|
<div class="error">
|
|
171
|
-
<h1>Authentication
|
|
171
|
+
<h1>Authentication failed</h1>
|
|
172
172
|
<p>Invalid state parameter (possible CSRF attack).</p>
|
|
173
173
|
<p>You can close this window and return to your terminal.</p>
|
|
174
174
|
</div>
|
|
@@ -192,7 +192,7 @@ export function createCallbackServer(
|
|
|
192
192
|
<!DOCTYPE html>
|
|
193
193
|
<html>
|
|
194
194
|
<head>
|
|
195
|
-
<title>Authentication
|
|
195
|
+
<title>Authentication successful</title>
|
|
196
196
|
<style>
|
|
197
197
|
body { font-family: system-ui, -apple-system, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
|
|
198
198
|
.success { background: #efe; border: 1px solid #cfc; padding: 20px; border-radius: 8px; }
|
|
@@ -201,7 +201,7 @@ export function createCallbackServer(
|
|
|
201
201
|
</head>
|
|
202
202
|
<body>
|
|
203
203
|
<div class="success">
|
|
204
|
-
<h1>Authentication
|
|
204
|
+
<h1>Authentication successful</h1>
|
|
205
205
|
<p>You have successfully authenticated the PostgresAI CLI.</p>
|
|
206
206
|
<p>You can close this window and return to your terminal.</p>
|
|
207
207
|
</div>
|
package/lib/issues.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as https from "https";
|
|
2
|
+
import { URL } from "url";
|
|
3
|
+
import { maskSecret, normalizeBaseUrl } from "./util";
|
|
4
|
+
|
|
5
|
+
export interface FetchIssuesParams {
|
|
6
|
+
apiKey: string;
|
|
7
|
+
apiBaseUrl: string;
|
|
8
|
+
debug?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function fetchIssues(params: FetchIssuesParams): Promise<unknown> {
|
|
12
|
+
const { apiKey, apiBaseUrl, debug } = params;
|
|
13
|
+
if (!apiKey) {
|
|
14
|
+
throw new Error("API key is required");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
18
|
+
const url = new URL(`${base}/issues`);
|
|
19
|
+
|
|
20
|
+
const headers: Record<string, string> = {
|
|
21
|
+
"access-token": apiKey,
|
|
22
|
+
"Prefer": "return=representation",
|
|
23
|
+
"Content-Type": "application/json",
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (debug) {
|
|
27
|
+
const debugHeaders: Record<string, string> = { ...headers, "access-token": maskSecret(apiKey) };
|
|
28
|
+
// eslint-disable-next-line no-console
|
|
29
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
console.log(`Debug: GET URL: ${url.toString()}`);
|
|
32
|
+
// eslint-disable-next-line no-console
|
|
33
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
const req = https.request(
|
|
40
|
+
url,
|
|
41
|
+
{
|
|
42
|
+
method: "GET",
|
|
43
|
+
headers,
|
|
44
|
+
},
|
|
45
|
+
(res) => {
|
|
46
|
+
let data = "";
|
|
47
|
+
res.on("data", (chunk) => (data += chunk));
|
|
48
|
+
res.on("end", () => {
|
|
49
|
+
if (debug) {
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.log(`Debug: Response status: ${res.statusCode}`);
|
|
52
|
+
// eslint-disable-next-line no-console
|
|
53
|
+
console.log(`Debug: Response headers: ${JSON.stringify(res.headers)}`);
|
|
54
|
+
}
|
|
55
|
+
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
56
|
+
try {
|
|
57
|
+
const parsed = JSON.parse(data);
|
|
58
|
+
resolve(parsed);
|
|
59
|
+
} catch {
|
|
60
|
+
resolve(data);
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
let errMsg = `Failed to fetch issues: HTTP ${res.statusCode}`;
|
|
64
|
+
if (data) {
|
|
65
|
+
try {
|
|
66
|
+
const errObj = JSON.parse(data);
|
|
67
|
+
errMsg += `\n${JSON.stringify(errObj, null, 2)}`;
|
|
68
|
+
} catch {
|
|
69
|
+
errMsg += `\n${data}`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
reject(new Error(errMsg));
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
req.on("error", (err: Error) => reject(err));
|
|
79
|
+
req.end();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|