@retasc/cli 1.1.0 → 1.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/dist/index.js +1 -1
- package/dist/lib/claim.js +12 -24
- package/dist/lib/keystore.js +41 -0
- package/dist/proxy.js +5 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ const program = new Command();
|
|
|
15
15
|
program
|
|
16
16
|
.name("retasc")
|
|
17
17
|
.description("Retasc — sign in, create projects, mint agent API keys, and wire your agent to the MCP server.")
|
|
18
|
-
.version("1.1.
|
|
18
|
+
.version("1.1.1");
|
|
19
19
|
function requireLogin() {
|
|
20
20
|
if (!isLoggedIn()) {
|
|
21
21
|
console.error("Not signed in. Run `retasc login` first.");
|
package/dist/lib/claim.js
CHANGED
|
@@ -4,35 +4,23 @@
|
|
|
4
4
|
// ../commands/claim.ts.
|
|
5
5
|
import { readFileSync, existsSync } from "node:fs";
|
|
6
6
|
import { join, resolve } from "node:path";
|
|
7
|
+
import { resolveConn } from "./keystore.js";
|
|
7
8
|
const DEFAULT_MCP_URL = "https://mcp.retasc.com/mcp";
|
|
8
9
|
/**
|
|
9
10
|
* Resolve the agent API key + MCP URL the same way the workspace's MCP wiring does,
|
|
10
|
-
* so `retasc claim` speaks as the *same agent* the harness already uses.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `key` comes back empty if nothing is found, so the caller can error clearly.
|
|
11
|
+
* so `retasc claim` speaks as the *same agent* the harness already uses. Delegates
|
|
12
|
+
* to the shared `resolveConn` (RTSC-98) so it stays in lockstep with the proxy —
|
|
13
|
+
* covering explicit env, both legacy `.mcp.json` shapes, AND the canonical
|
|
14
|
+
* secret-free marker (`RETASC_WORKSPACE` → home keystore). `key` comes back empty
|
|
15
|
+
* if nothing is found, so the caller can error clearly.
|
|
16
16
|
*/
|
|
17
17
|
export function resolveMcpConn(opts = {}) {
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
key = entry.env.RETASC_MCP_KEY;
|
|
25
|
-
if (!url && typeof entry.env?.RETASC_MCP_URL === "string")
|
|
26
|
-
url = entry.env.RETASC_MCP_URL;
|
|
27
|
-
if (!url && typeof entry.url === "string")
|
|
28
|
-
url = entry.url;
|
|
29
|
-
if (!key && typeof entry.headers?.Authorization === "string") {
|
|
30
|
-
const m = entry.headers.Authorization.match(/^Bearer\s+(.+)$/i);
|
|
31
|
-
if (m)
|
|
32
|
-
key = m[1].trim();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return { url: url || opts.defaultUrl || DEFAULT_MCP_URL, key };
|
|
18
|
+
const { key, url } = resolveConn({
|
|
19
|
+
env: opts.env,
|
|
20
|
+
mcpEntry: opts.mcpJson?.mcpServers?.retasc,
|
|
21
|
+
defaultUrl: opts.defaultUrl || DEFAULT_MCP_URL,
|
|
22
|
+
});
|
|
23
|
+
return { url: url || DEFAULT_MCP_URL, key };
|
|
36
24
|
}
|
|
37
25
|
/** Read & parse the workspace `.mcp.json` (or null if absent/corrupt). */
|
|
38
26
|
export function readMcpJson(dir = process.cwd()) {
|
package/dist/lib/keystore.js
CHANGED
|
@@ -50,3 +50,44 @@ export function removeBinding(workspaceId) {
|
|
|
50
50
|
export function newWorkspaceId() {
|
|
51
51
|
return `ws_${randomUUID()}`;
|
|
52
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* RTSC-98: the ONE place that resolves a workspace's key + MCP url. Shared by the
|
|
55
|
+
* proxy (env-based) and the direct commands `claim`/`tidy`/`done` (.mcp.json-based)
|
|
56
|
+
* so the two paths can never drift again. Precedence: explicit `RETASC_MCP_KEY`
|
|
57
|
+
* env → legacy inline key in the marker (env or Authorization header) → canonical
|
|
58
|
+
* secret-free marker (`RETASC_WORKSPACE` → home keystore). `mcpEntry` is a
|
|
59
|
+
* workspace `.mcp.json`'s `mcpServers.retasc` entry, or undefined when only the
|
|
60
|
+
* environment carries the binding (the spawned proxy).
|
|
61
|
+
*/
|
|
62
|
+
export function resolveConn(opts) {
|
|
63
|
+
const env = opts.env ?? process.env;
|
|
64
|
+
const entry = opts.mcpEntry;
|
|
65
|
+
let key = env.RETASC_MCP_KEY || "";
|
|
66
|
+
let url = env.RETASC_MCP_URL || "";
|
|
67
|
+
if (entry) {
|
|
68
|
+
if (!key && typeof entry.env?.RETASC_MCP_KEY === "string")
|
|
69
|
+
key = entry.env.RETASC_MCP_KEY;
|
|
70
|
+
if (!url && typeof entry.env?.RETASC_MCP_URL === "string")
|
|
71
|
+
url = entry.env.RETASC_MCP_URL;
|
|
72
|
+
if (!url && typeof entry.url === "string")
|
|
73
|
+
url = entry.url;
|
|
74
|
+
if (!key && typeof entry.headers?.Authorization === "string") {
|
|
75
|
+
const m = String(entry.headers.Authorization).match(/^Bearer\s+(.+)$/i);
|
|
76
|
+
if (m)
|
|
77
|
+
key = m[1].trim();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Canonical (RTSC-92): secret-free marker → workspace id → home keystore.
|
|
81
|
+
if (!key) {
|
|
82
|
+
const wsId = env.RETASC_WORKSPACE || entry?.env?.RETASC_WORKSPACE;
|
|
83
|
+
if (wsId) {
|
|
84
|
+
const b = getBinding(String(wsId));
|
|
85
|
+
if (b) {
|
|
86
|
+
key = b.key;
|
|
87
|
+
if (!url)
|
|
88
|
+
url = b.url;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { key, url: url || opts.defaultUrl || "" };
|
|
93
|
+
}
|
package/dist/proxy.js
CHANGED
|
@@ -8,24 +8,11 @@
|
|
|
8
8
|
import { createInterface } from "node:readline";
|
|
9
9
|
import { hostname } from "node:os";
|
|
10
10
|
import { applyObservation, heartbeatRequest, isClaimLost, } from "./lib/watchdog.js";
|
|
11
|
-
import {
|
|
12
|
-
// RTSC-92: resolve the workspace key
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
const envUrl = process.env.RETASC_MCP_URL || "https://mcp.retasc.com/mcp";
|
|
17
|
-
if (process.env.RETASC_MCP_KEY) {
|
|
18
|
-
return { key: process.env.RETASC_MCP_KEY, url: envUrl };
|
|
19
|
-
}
|
|
20
|
-
const wsId = process.env.RETASC_WORKSPACE;
|
|
21
|
-
if (wsId) {
|
|
22
|
-
const entry = getBinding(wsId);
|
|
23
|
-
if (entry)
|
|
24
|
-
return { key: entry.key, url: entry.url || envUrl };
|
|
25
|
-
}
|
|
26
|
-
return { key: "", url: envUrl };
|
|
27
|
-
}
|
|
28
|
-
const resolved = resolveKeyUrl();
|
|
11
|
+
import { resolveConn } from "./lib/keystore.js";
|
|
12
|
+
// RTSC-92/98: resolve the workspace key via the SHARED resolver, so the proxy and
|
|
13
|
+
// the direct commands (claim/tidy/done) can never diverge. The proxy carries its
|
|
14
|
+
// binding in its own env (RETASC_MCP_KEY legacy, or RETASC_WORKSPACE → keystore).
|
|
15
|
+
const resolved = resolveConn({ env: process.env, defaultUrl: "https://mcp.retasc.com/mcp" });
|
|
29
16
|
let MCP_URL = resolved.url;
|
|
30
17
|
const KEY = resolved.key;
|
|
31
18
|
const HEARTBEAT_MS = Number(process.env.RETASC_HEARTBEAT_MS) || 10 * 60 * 1000;
|
package/package.json
CHANGED