premanmcp 0.9.0 → 0.10.0
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 +45 -11
- package/bin/cli.js +5 -1
- package/bin/connect.js +645 -67
- package/bin/integrations.js +5 -5
- package/bin/runner.js +880 -0
- package/bin/shared.js +13 -1
- package/dist/server.js +29 -9
- package/package.json +1 -1
package/bin/shared.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { spawn, spawnSync } from "node:child_process";
|
|
11
|
-
import { chmodSync, existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
11
|
+
import { chmodSync, existsSync, readFileSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
|
|
12
12
|
import os from "node:os";
|
|
13
13
|
import path from "node:path";
|
|
14
14
|
import { createInterface } from "node:readline/promises";
|
|
@@ -93,6 +93,18 @@ export function saveStoredCredentials(creds) {
|
|
|
93
93
|
writeFileSync(CREDENTIALS_FILE, `${JSON.stringify(creds, null, 2)}\n`, { mode: 0o600 });
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
/** Forget the stored key. Returns whether there was one. */
|
|
97
|
+
export function clearStoredCredentials() {
|
|
98
|
+
if (!existsSync(CREDENTIALS_FILE)) return false;
|
|
99
|
+
rmSync(CREDENTIALS_FILE, { force: true });
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** True when the key in play came from a flag or the environment, not our store. */
|
|
104
|
+
export function apiKeyIsExplicit(args) {
|
|
105
|
+
return Boolean(args.value("--api-key", "") || process.env.PREMAN_API_KEY);
|
|
106
|
+
}
|
|
107
|
+
|
|
96
108
|
export function backendUrl(args) {
|
|
97
109
|
return args.value("--backend", process.env.PREMAN_BACKEND || DEFAULT_BACKEND).replace(/\/+$/, "");
|
|
98
110
|
}
|
package/dist/server.js
CHANGED
|
@@ -9,11 +9,7 @@ import path from "node:path";
|
|
|
9
9
|
import os from "node:os";
|
|
10
10
|
import { randomUUID } from "node:crypto";
|
|
11
11
|
import { MCP_PREVIEW_RESOURCE_URI, RESOURCE_URI_META_KEY, buildConversionPanelHtml, writeMcpPreviewFile, } from "./mcp-preview-panel.js";
|
|
12
|
-
|
|
13
|
-
* Load ``PREMAN_*`` from repo JSON so project URLs win over stale **global** Cursor MCP env
|
|
14
|
-
* (which often sets the wrong ``PREMAN_BACKEND``, e.g. app port instead of API port).
|
|
15
|
-
* First match wins: ``.cursor/preman-mcp.config.json``, then ``preman-mcp.config.json`` (cwd).
|
|
16
|
-
*/
|
|
12
|
+
let REPO_CONFIG = null;
|
|
17
13
|
function applyRepoPremanConfig() {
|
|
18
14
|
const candidates = [
|
|
19
15
|
path.join(process.cwd(), ".cursor", "preman-mcp.config.json"),
|
|
@@ -24,13 +20,19 @@ function applyRepoPremanConfig() {
|
|
|
24
20
|
if (!existsSync(p))
|
|
25
21
|
continue;
|
|
26
22
|
const j = JSON.parse(readFileSync(p, "utf8"));
|
|
23
|
+
const override = j.PREMAN_CONFIG_OVERRIDE === true || j.PREMAN_CONFIG_OVERRIDE === "true";
|
|
24
|
+
const applied = [];
|
|
27
25
|
for (const [key, val] of Object.entries(j)) {
|
|
28
|
-
if (!key.startsWith("PREMAN_"))
|
|
26
|
+
if (!key.startsWith("PREMAN_") || key === "PREMAN_CONFIG_OVERRIDE")
|
|
29
27
|
continue;
|
|
30
|
-
if (typeof val
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
if (typeof val !== "string" || !val.trim())
|
|
29
|
+
continue;
|
|
30
|
+
if (!override && process.env[key])
|
|
31
|
+
continue;
|
|
32
|
+
process.env[key] = val.trim();
|
|
33
|
+
applied.push(key);
|
|
33
34
|
}
|
|
35
|
+
REPO_CONFIG = { path: p, override, applied };
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
36
38
|
catch {
|
|
@@ -42,6 +44,22 @@ applyRepoPremanConfig();
|
|
|
42
44
|
const BACKEND_URL = process.env.PREMAN_BACKEND || "https://api.preman.live";
|
|
43
45
|
const FRONTEND_URL = process.env.PREMAN_FRONTEND || "https://app.preman.live";
|
|
44
46
|
let API_KEY = process.env.PREMAN_API_KEY || "";
|
|
47
|
+
/**
|
|
48
|
+
* Where the URLs this process is using came from.
|
|
49
|
+
*
|
|
50
|
+
* Reported by `preman_status` because the most confusing failure in setup is a
|
|
51
|
+
* server that works perfectly against the wrong backend: the key is fine, the
|
|
52
|
+
* config on disk is fine, and every call still 401s. Naming the file that
|
|
53
|
+
* redirected it turns that into a one-line diagnosis.
|
|
54
|
+
*/
|
|
55
|
+
function configSource() {
|
|
56
|
+
return {
|
|
57
|
+
backend_url: BACKEND_URL,
|
|
58
|
+
repo_config: REPO_CONFIG
|
|
59
|
+
? { path: REPO_CONFIG.path, override: REPO_CONFIG.override, applied: REPO_CONFIG.applied }
|
|
60
|
+
: null,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
45
63
|
function detectCodingAgent() {
|
|
46
64
|
const forced = (process.env.PREMAN_CODING_AGENT || "").trim().toLowerCase();
|
|
47
65
|
if (forced)
|
|
@@ -1040,6 +1058,7 @@ export function createServer() {
|
|
|
1040
1058
|
backend_url: BACKEND_URL,
|
|
1041
1059
|
frontend_base_url: FRONTEND_BASE,
|
|
1042
1060
|
endpoints_page_url: buildAgentDashboardUrl("/endpoints"),
|
|
1061
|
+
config: configSource(),
|
|
1043
1062
|
message: "Stored API key is no longer valid. Run `npm exec -y premanmcp@latest -- login`, or use user_auth_* then preman_create_api_key, or run preman_login.",
|
|
1044
1063
|
}),
|
|
1045
1064
|
}],
|
|
@@ -1056,6 +1075,7 @@ export function createServer() {
|
|
|
1056
1075
|
backend_url: BACKEND_URL,
|
|
1057
1076
|
frontend_base_url: FRONTEND_BASE,
|
|
1058
1077
|
endpoints_page_url: buildAgentDashboardUrl("/endpoints"),
|
|
1078
|
+
config: configSource(),
|
|
1059
1079
|
coding_agent: workbench,
|
|
1060
1080
|
_agent_hints: {
|
|
1061
1081
|
next_actions: [
|