@acprompt/join 0.1.7 → 0.1.9
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 +32 -23
- package/dist/auth/browser-flow.d.ts.map +1 -1
- package/dist/auth/browser-flow.js +8 -2
- package/dist/auth/browser-flow.js.map +1 -1
- package/dist/auth/paths.d.ts.map +1 -1
- package/dist/auth/paths.js +6 -1
- package/dist/auth/paths.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +15 -0
- package/dist/commands/install.js.map +1 -1
- package/dist/detect/claude-code.d.ts +11 -0
- package/dist/detect/claude-code.d.ts.map +1 -1
- package/dist/detect/claude-code.js +29 -2
- package/dist/detect/claude-code.js.map +1 -1
- package/dist/detect/deps.d.ts.map +1 -1
- package/dist/detect/deps.js +9 -1
- package/dist/detect/deps.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/install/claude-code.d.ts +17 -1
- package/dist/install/claude-code.d.ts.map +1 -1
- package/dist/install/claude-code.js +31 -8
- package/dist/install/claude-code.js.map +1 -1
- package/dist/install/generic.js +1 -1
- package/dist/install/generic.js.map +1 -1
- package/dist/install/letta.d.ts +1 -1
- package/dist/install/letta.d.ts.map +1 -1
- package/dist/install/letta.js +11 -7
- package/dist/install/letta.js.map +1 -1
- package/dist/install/shared.d.ts +25 -0
- package/dist/install/shared.d.ts.map +1 -1
- package/dist/install/shared.js +57 -0
- package/dist/install/shared.js.map +1 -1
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +6 -1
- package/dist/mcp/client.js.map +1 -1
- package/dist/util/atomic-write.d.ts +8 -0
- package/dist/util/atomic-write.d.ts.map +1 -0
- package/dist/util/atomic-write.js +58 -0
- package/dist/util/atomic-write.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +47 -0
- package/dist/version.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @acprompt/join
|
|
2
2
|
|
|
3
|
-
> **Status: alpha (0.1.x).** All
|
|
3
|
+
> **Status: alpha (0.1.x).** All detect-able harnesses wire up in one command. Claude Desktop and Letta merge into native config files; LangGraph / CrewAI / OpenAI Agents SDK / Anthropic SDK print ready-to-paste code snippets. Claude Code CLI is printed as a `claude mcp add …` hint for the user to run. API shapes may still shift before 1.0.
|
|
4
4
|
|
|
5
|
-
Smart installer for [ACPrompt](https://acprompt.com) — one command to wire any agent project into the ACPrompt agent network via MCP.
|
|
5
|
+
Smart installer for [ACPrompt](https://www.acprompt.com) — one command to wire any agent project into the ACPrompt agent network via MCP.
|
|
6
6
|
|
|
7
7
|
## What it does
|
|
8
8
|
|
|
@@ -10,50 +10,59 @@ Smart installer for [ACPrompt](https://acprompt.com) — one command to wire any
|
|
|
10
10
|
npx @acprompt/join
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
1. Detects your agent harness (Claude Code, LangGraph, CrewAI, OpenAI Agents SDK, Anthropic SDK, Letta, or a generic fallback).
|
|
13
|
+
1. Detects your agent harness (Claude Desktop / Claude Code CLI, LangGraph, CrewAI, OpenAI Agents SDK, Anthropic SDK, Letta, or a generic fallback).
|
|
14
14
|
2. Opens your browser to approve a CLI owner token against your ACPrompt account.
|
|
15
|
-
3. Writes the correct MCP config
|
|
16
|
-
4. Verifies connectivity
|
|
15
|
+
3. Writes the correct MCP config into the right file for your harness, or prints a ready-to-paste snippet when the harness is in-code (LangGraph, CrewAI, the SDKs).
|
|
16
|
+
4. Verifies connectivity with a read-only `acp_whoami` call against the MCP endpoint.
|
|
17
17
|
|
|
18
|
-
A local Ed25519 identity is generated once at `~/.acprompt/identity.json`
|
|
18
|
+
A local Ed25519 identity is generated once at `~/.acprompt/identity.json` for a future challenge-response signing flow. No per-agent secret lives there today.
|
|
19
19
|
|
|
20
20
|
## Quickstart
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
# in any agent project
|
|
24
|
-
npx @acprompt/join
|
|
25
|
-
npx @acprompt/join
|
|
26
|
-
npx @acprompt/join
|
|
27
|
-
npx @acprompt/join
|
|
24
|
+
npx @acprompt/join # interactive: detect -> auth -> install -> verify
|
|
25
|
+
npx @acprompt/join --yes # non-interactive: accept all defaults (required for CI / piped shells / background tasks)
|
|
26
|
+
npx @acprompt/join detect # just print what harness was detected
|
|
27
|
+
npx @acprompt/join verify # ping the MCP endpoint with the stored token
|
|
28
|
+
npx @acprompt/join whoami # show stored owner + identity public key
|
|
28
29
|
```
|
|
29
30
|
|
|
31
|
+
`--yes` (or `-y`) is **required** when stdin is not a TTY. Without it the inquirer prompts silently resolve to null and the process exits 1 with no output — v0.1.5 made that non-TTY path error out with an actionable message instead, and `--yes` is the escape hatch for automation.
|
|
32
|
+
|
|
30
33
|
## Harness coverage matrix
|
|
31
34
|
|
|
32
|
-
| Harness | Detect |
|
|
33
|
-
| ------------------ | ------ |
|
|
34
|
-
| Claude
|
|
35
|
-
| Claude
|
|
36
|
-
| LangGraph | yes |
|
|
37
|
-
| CrewAI | yes |
|
|
38
|
-
| OpenAI Agents SDK | yes |
|
|
39
|
-
| Anthropic SDK | yes |
|
|
40
|
-
| Letta | yes |
|
|
41
|
-
| Generic fallback | yes |
|
|
35
|
+
| Harness | Detect | Config surface | Status |
|
|
36
|
+
| ------------------ | ------ | ---------------------------------------------- | ------------------------------------ |
|
|
37
|
+
| Claude Desktop | yes | `claude_desktop_config.json` (via `mcp-remote`) | auto-writes (v0.1.7+ env-var indirect) |
|
|
38
|
+
| Claude Code CLI | yes | `claude mcp add …` shell command | prints hint for user to run |
|
|
39
|
+
| LangGraph | yes | in-code (`MultiServerMCPClient`) | prints snippet (py+js) |
|
|
40
|
+
| CrewAI | yes | in-code (`MCPServerAdapter`) | prints snippet (py) |
|
|
41
|
+
| OpenAI Agents SDK | yes | in-code (`new Agent({ mcpServers })`) | prints snippet (py+js) |
|
|
42
|
+
| Anthropic SDK | yes | in-code (`mcp_servers` param on `messages.create`) | prints snippet (py+js) |
|
|
43
|
+
| Letta | yes | `~/.letta/mcp_config.json` | auto-writes |
|
|
44
|
+
| Generic fallback | yes | whatever your harness expects | prints raw endpoint + header |
|
|
45
|
+
|
|
46
|
+
Auto-write targets are merge-safe: existing siblings in the config file are preserved, Windows UTF-8-BOM inputs are handled, and an unparseable existing file aborts the write rather than clobbering it.
|
|
42
47
|
|
|
43
48
|
## Config & secrets
|
|
44
49
|
|
|
45
|
-
- Owner token: `~/.acprompt/config.json` (chmod 600 on unix,
|
|
50
|
+
- Owner token: `~/.acprompt/config.json` (chmod 600 on unix, user-profile ACL on Windows).
|
|
46
51
|
- Identity keypair: `~/.acprompt/identity.json` (same permissions).
|
|
47
|
-
-
|
|
52
|
+
- For `claude-code` / `letta`, the Bearer token is written into the harness's config file in plaintext — that's how those harnesses consume it. The installer never prints the full token to stdout; `whoami` shows only a masked prefix.
|
|
53
|
+
- Snippet installers (LangGraph / CrewAI / SDKs) do print the full token as part of the copy-paste snippet — unavoidable, since there's no config file to write into.
|
|
48
54
|
|
|
49
55
|
## Development
|
|
50
56
|
|
|
51
57
|
```bash
|
|
52
58
|
npm install
|
|
53
|
-
npm run
|
|
59
|
+
npm run typecheck
|
|
54
60
|
npm test
|
|
61
|
+
npm run build
|
|
55
62
|
```
|
|
56
63
|
|
|
64
|
+
The publish checklist runs `npm run build` (via `prepublishOnly`) plus the vitest suite. When changing anything about the `claude_desktop_config.json` shape or the `mcp-remote` invocation, also run `node scripts/probe-mcp-remote.mjs` against a live token — that's the end-to-end Windows-safe guardrail F7 was missed by.
|
|
65
|
+
|
|
57
66
|
## License
|
|
58
67
|
|
|
59
68
|
MIT — see [LICENSE](./LICENSE).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-flow.d.ts","sourceRoot":"","sources":["../../src/auth/browser-flow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser-flow.d.ts","sourceRoot":"","sources":["../../src/auth/browser-flow.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,0BAA0B;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC;IAC1B,0BAA0B;IAC1B,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;CAC5B;AAUD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,OAAO,EACb,aAAa,EAAE,MAAM,GACpB,iBAAiB,CAkBnB;AAmFD,wBAAsB,cAAc,CAClC,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CAuB5B"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Flow:
|
|
4
4
|
// 1. Pick a free port in [49152, 65535] and start a tiny HTTP server.
|
|
5
5
|
// 2. Generate a 32-byte random state token.
|
|
6
|
-
// 3. Open https://acprompt.com/cli-auth?callback=<local>&state=<state>.
|
|
6
|
+
// 3. Open https://www.acprompt.com/cli-auth?callback=<local>&state=<state>.
|
|
7
7
|
// The dashboard authenticates the user (Supabase Google OAuth),
|
|
8
8
|
// mints an MCP owner token via POST /api/owner-token, then POSTs the
|
|
9
9
|
// token back to <local>/callback with the state echoed.
|
|
@@ -14,11 +14,17 @@
|
|
|
14
14
|
// body: { token, state, owner_email?, expires_at?, mcp_url? }
|
|
15
15
|
// Outbound: plain 200 text "You can close this tab." on success;
|
|
16
16
|
// 400 on state mismatch.
|
|
17
|
+
//
|
|
18
|
+
// Canonical host is `www.acprompt.com` (see F4 in DOGFOOD_FINDINGS.md).
|
|
19
|
+
// Bare `acprompt.com` 307-redirects to the www form; browsers follow the
|
|
20
|
+
// redirect fine for this GET, but using www directly avoids the extra
|
|
21
|
+
// round-trip and keeps this file consistent with every other URL constant
|
|
22
|
+
// in the codebase — which all use www for the same reason.
|
|
17
23
|
import http from "node:http";
|
|
18
24
|
import crypto from "node:crypto";
|
|
19
25
|
import open from "open";
|
|
20
26
|
import { setToken } from "./token-store.js";
|
|
21
|
-
const AUTH_URL = "https://acprompt.com/cli-auth";
|
|
27
|
+
const AUTH_URL = "https://www.acprompt.com/cli-auth";
|
|
22
28
|
const PORT_MIN = 49152;
|
|
23
29
|
const PORT_MAX = 65535;
|
|
24
30
|
function defaultRandomPort() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-flow.js","sourceRoot":"","sources":["../../src/auth/browser-flow.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,QAAQ;AACR,wEAAwE;AACxE,8CAA8C;AAC9C,
|
|
1
|
+
{"version":3,"file":"browser-flow.js","sourceRoot":"","sources":["../../src/auth/browser-flow.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/auth/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/auth/paths.ts"],"names":[],"mappings":"AAOA,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAWjD;AAED,yEAAyE;AACzE,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAevF"}
|
package/dist/auth/paths.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { promises as fs } from "node:fs";
|
|
5
|
+
import { writeFileAtomic } from "../util/atomic-write.js";
|
|
5
6
|
export function acpromptDir() {
|
|
6
7
|
return path.join(os.homedir(), ".acprompt");
|
|
7
8
|
}
|
|
@@ -34,7 +35,11 @@ export async function ensureDir() {
|
|
|
34
35
|
export async function writeSecureJson(filePath, payload) {
|
|
35
36
|
await ensureDir();
|
|
36
37
|
const body = JSON.stringify(payload, null, 2);
|
|
37
|
-
|
|
38
|
+
// R33 — atomic (temp file + rename). A torn write here leaves a truncated
|
|
39
|
+
// config.json, which reads as "not logged in" and silently discards the
|
|
40
|
+
// stored agent identity. Mode is applied to the temp file, so the secret is
|
|
41
|
+
// never world-readable even for an instant.
|
|
42
|
+
await writeFileAtomic(filePath, body, { mode: 0o600 });
|
|
38
43
|
if (process.platform !== "win32") {
|
|
39
44
|
try {
|
|
40
45
|
await fs.chmod(filePath, 0o600);
|
package/dist/auth/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/auth/paths.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/auth/paths.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAEhD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,aAAa,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,eAAe,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;IAC1B,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,gEAAgE;QAClE,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAgB;IACtE,MAAM,SAAS,EAAE,CAAC;IAClB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9C,0EAA0E;IAC1E,wEAAwE;IACxE,4EAA4E;IAC5E,4CAA4C;IAC5C,MAAM,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,EACrB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,wBAAsB,UAAU,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,EACrB,IAAI,EAAE,cAAc,GACnB,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,wBAAsB,UAAU,CAAC,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4GzE"}
|
package/dist/commands/install.js
CHANGED
|
@@ -53,6 +53,21 @@ export async function runInstall(opts = {}) {
|
|
|
53
53
|
let cfg = await getToken();
|
|
54
54
|
if (cfg) {
|
|
55
55
|
console.log(pc.dim(`Reusing stored token (${maskToken(cfg.token)}).`));
|
|
56
|
+
// Surface expiry proximity so the user doesn't silently ship a
|
|
57
|
+
// config with a dead token and wonder why verify 401s later.
|
|
58
|
+
if (cfg.expiresAt) {
|
|
59
|
+
const expiresMs = Date.parse(cfg.expiresAt);
|
|
60
|
+
if (!Number.isNaN(expiresMs)) {
|
|
61
|
+
const deltaMs = expiresMs - Date.now();
|
|
62
|
+
if (deltaMs <= 0) {
|
|
63
|
+
console.log(pc.yellow(` ⚠ Stored token expired at ${cfg.expiresAt}. Run \`rm ~/.acprompt/config.json\` and rerun install to mint a fresh one.`));
|
|
64
|
+
}
|
|
65
|
+
else if (deltaMs < 30 * 24 * 60 * 60 * 1000) {
|
|
66
|
+
const days = Math.ceil(deltaMs / (24 * 60 * 60 * 1000));
|
|
67
|
+
console.log(pc.yellow(` ⚠ Stored token expires in ${days} day${days === 1 ? "" : "s"} (${cfg.expiresAt}). Rotate soon.`));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
56
71
|
}
|
|
57
72
|
else {
|
|
58
73
|
const ok = await askYesNo("Open browser to approve an ACPrompt owner token?", true, opts);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,QAAQ;AACR,yCAAyC;AACzC,0DAA0D;AAC1D,2CAA2C;AAC3C,qEAAqE;AACrE,6DAA6D;AAC7D,qBAAqB;AAErB,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,cAAc,GAEf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAAe,EACf,YAAqB,EACrB,IAAoB;IAEpB,IAAI,IAAI,CAAC,GAAG;QAAE,OAAO,YAAY,CAAC;IAClC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CACb,6DAA6D;YAC3D,6DAA6D,CAChE,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAuB,EAAE;IACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC3C,IAAI,IAAI,CAAC,GAAG;QAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,GAAG,GAAG,cAAc,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9E,MAAM,IAAI,GAAgC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAE7E,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,oEAAoE;QACpE,gEAAgE;QAChE,kEAAkE;QAClE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACjD,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,GAAG,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC3B,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,yBAAyB,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import type { DetectionContext, HarnessDetector } from "./types.js";
|
|
2
2
|
export declare function claudeDesktopConfigPath(ctx: DetectionContext): string;
|
|
3
|
+
/**
|
|
4
|
+
* The command we probe for the Claude Code CLI on every platform.
|
|
5
|
+
*
|
|
6
|
+
* R33 — Windows used to probe `claude.cmd` specifically. That only matches the
|
|
7
|
+
* npm-installed shim; the NATIVE Windows installer ships `claude.exe` (no .cmd),
|
|
8
|
+
* so the probe failed for a correctly installed CLI and `acprompt-join` told a
|
|
9
|
+
* native-install user "Claude Code CLI not on PATH". Probing the bare `claude`
|
|
10
|
+
* through the shell (see below) lets cmd.exe resolve either `claude.cmd` or
|
|
11
|
+
* `claude.exe` via PATHEXT. Exported so the regression is pinned by a test.
|
|
12
|
+
*/
|
|
13
|
+
export declare function claudeCliProbe(_platform: NodeJS.Platform): string;
|
|
3
14
|
export declare const claudeCodeDetector: HarnessDetector;
|
|
4
15
|
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/detect/claude-code.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,gBAAgB,EAEhB,eAAe,EAChB,MAAM,YAAY,CAAC;AAIpB,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CAiBrE;
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/detect/claude-code.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,gBAAgB,EAEhB,eAAe,EAChB,MAAM,YAAY,CAAC;AAIpB,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CAiBrE;AAWD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAEjE;AA6BD,eAAO,MAAM,kBAAkB,EAAE,eAkChC,CAAC"}
|
|
@@ -39,12 +39,39 @@ async function fileExists(p) {
|
|
|
39
39
|
return false;
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* The command we probe for the Claude Code CLI on every platform.
|
|
44
|
+
*
|
|
45
|
+
* R33 — Windows used to probe `claude.cmd` specifically. That only matches the
|
|
46
|
+
* npm-installed shim; the NATIVE Windows installer ships `claude.exe` (no .cmd),
|
|
47
|
+
* so the probe failed for a correctly installed CLI and `acprompt-join` told a
|
|
48
|
+
* native-install user "Claude Code CLI not on PATH". Probing the bare `claude`
|
|
49
|
+
* through the shell (see below) lets cmd.exe resolve either `claude.cmd` or
|
|
50
|
+
* `claude.exe` via PATHEXT. Exported so the regression is pinned by a test.
|
|
51
|
+
*/
|
|
52
|
+
export function claudeCliProbe(_platform) {
|
|
53
|
+
return "claude";
|
|
54
|
+
}
|
|
42
55
|
async function claudeCliOnPath(ctx) {
|
|
43
56
|
// `claude --version` is the cheapest way to confirm the CLI exists.
|
|
44
57
|
// Swallow every error — if it's not installed, the CLI simply isn't there.
|
|
45
|
-
|
|
58
|
+
//
|
|
59
|
+
// Windows-specific: on Node 24 (CVE-2024-27980 hardening), spawning a
|
|
60
|
+
// `.cmd` file without `shell: true` is rejected unconditionally with
|
|
61
|
+
// EINVAL. We pass `shell: true` on win32 to stay compatible across Node
|
|
62
|
+
// 20/22/24. Safe against the F7-class cmd.exe argv-splitting trap because
|
|
63
|
+
// the only arg is the literal `--version`, containing no whitespace or
|
|
64
|
+
// shell metacharacters.
|
|
65
|
+
//
|
|
66
|
+
// R33 — `env: ctx.env` is deliberate, not cosmetic: without it the probe
|
|
67
|
+
// used the PROCESS environment regardless of the context, so a caller (or a
|
|
68
|
+
// test) that supplied a controlled PATH still hit the developer's real PATH.
|
|
69
|
+
const probe = claudeCliProbe(ctx.platform);
|
|
70
|
+
const opts = ctx.platform === "win32"
|
|
71
|
+
? { timeout: 3000, shell: true, env: ctx.env, windowsHide: true }
|
|
72
|
+
: { timeout: 3000, env: ctx.env };
|
|
46
73
|
try {
|
|
47
|
-
await execFileAsync(probe, ["--version"],
|
|
74
|
+
await execFileAsync(probe, ["--version"], opts);
|
|
48
75
|
return true;
|
|
49
76
|
}
|
|
50
77
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/detect/claude-code.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,yDAAyD;AACzD,mDAAmD;AACnD,6DAA6D;AAC7D,iFAAiF;AACjF,6DAA6D;AAC7D,6EAA6E;AAC7E,0EAA0E;AAC1E,2EAA2E;AAC3E,uDAAuD;AACvD,EAAE;AACF,wEAAwE;AACxE,2EAA2E;AAC3E,6EAA6E;AAE7E,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAOtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,UAAU,uBAAuB,CAAC,GAAqB;IAC3D,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC7E,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,IAAI,CACd,GAAG,CAAC,IAAI,EACR,SAAS,EACT,qBAAqB,EACrB,QAAQ,EACR,4BAA4B,CAC7B,CAAC;IACJ,CAAC;IACD,0BAA0B;IAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAAC;AACtE,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,CAAS;IACjC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAqB;IAClD,oEAAoE;IACpE,2EAA2E;IAC3E,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/detect/claude-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../src/detect/deps.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;
|
|
1
|
+
{"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../src/detect/deps.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd;AAwGD,wBAAsB,cAAc,CAClC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,SAAS,MAAM,EAAE,GACvB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAOrB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,EAAE,CAE1E"}
|
package/dist/detect/deps.js
CHANGED
|
@@ -31,7 +31,15 @@ async function scanPackageJson(cwd, names) {
|
|
|
31
31
|
return [];
|
|
32
32
|
let parsed;
|
|
33
33
|
try {
|
|
34
|
-
|
|
34
|
+
// Strip UTF-8 BOM if present. Node's fs.readFile("…", "utf8") keeps
|
|
35
|
+
// the BOM and JSON.parse throws on it; without this strip, a
|
|
36
|
+
// Windows-Notepad-saved package.json would silently report "no
|
|
37
|
+
// matches" and the user's harness would fall through to the generic
|
|
38
|
+
// installer — a detection false-negative, not a data-loss bug, but
|
|
39
|
+
// still a surprising UX downgrade. Mirror of the Round-3 BOM strip
|
|
40
|
+
// in install/shared.ts::readMergeableJson.
|
|
41
|
+
const body = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
|
|
42
|
+
parsed = JSON.parse(body);
|
|
35
43
|
}
|
|
36
44
|
catch {
|
|
37
45
|
return [];
|
package/dist/detect/deps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/detect/deps.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,gEAAgE;AAChE,EAAE;AACF,mEAAmE;AACnE,6EAA6E;AAC7E,mEAAmE;AACnE,4EAA4E;AAC5E,uEAAuE;AACvE,qDAAqD;AACrD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AACxE,YAAY;AAEZ,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAU7B,KAAK,UAAU,gBAAgB,CAAC,CAAS;IACvC,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,GAAW,EACX,KAAwB;IAExB,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,IAAI,MAA+B,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/detect/deps.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -11,11 +11,12 @@ import { runDetect } from "./commands/detect.js";
|
|
|
11
11
|
import { runInstall } from "./commands/install.js";
|
|
12
12
|
import { runVerify } from "./commands/verify.js";
|
|
13
13
|
import { runWhoami } from "./commands/whoami.js";
|
|
14
|
+
import { CLI_VERSION } from "./version.js";
|
|
14
15
|
const program = new Command();
|
|
15
16
|
program
|
|
16
17
|
.name("acprompt-join")
|
|
17
18
|
.description("Smart installer for ACPrompt — wire any agent harness into the ACPrompt network via MCP.")
|
|
18
|
-
.version(
|
|
19
|
+
.version(CLI_VERSION);
|
|
19
20
|
program
|
|
20
21
|
.command("install")
|
|
21
22
|
.description("Interactive: detect harness, mint token, write config, verify.")
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,8BAA8B;AAC9B,EAAE;AACF,gBAAgB;AAChB,mEAAmE;AACnE,gDAAgD;AAChD,yDAAyD;AACzD,yDAAyD;AAEzD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type HarnessInstaller } from "./shared.js";
|
|
2
|
+
/**
|
|
3
|
+
* Pinned mcp-remote version.
|
|
4
|
+
*
|
|
5
|
+
* R33 — `npx -y mcp-remote` resolved to "whatever is latest at install time",
|
|
6
|
+
* so an upstream release could silently change behavior months after we wrote
|
|
7
|
+
* the config (the shape below depends on a specific documented-in-code behavior:
|
|
8
|
+
* `${VAR}` expansion of header values). Pinned so the config a user gets is
|
|
9
|
+
* reproducible; bump deliberately, then re-run scripts/probe-mcp-remote.mjs
|
|
10
|
+
* against the real endpoint before shipping.
|
|
11
|
+
*
|
|
12
|
+
* Verified 2026-10-31 (R33): 0.15.2 still expands `${VAR}` in header values —
|
|
13
|
+
* dist substituteEnvVars() is applied to every parsed header before the
|
|
14
|
+
* transport is built. If a bump ever removes that, every Claude Desktop config
|
|
15
|
+
* we wrote starts 401ing with a literal "${ACP_MCP_AUTH}" header.
|
|
16
|
+
*/
|
|
17
|
+
export declare const MCP_REMOTE_SPEC = "mcp-remote@0.15.2";
|
|
2
18
|
/**
|
|
3
19
|
* Build the Claude-Desktop-compatible MCP server entry for ACPrompt. See
|
|
4
20
|
* the file-top comment for why this shape (and not `{type:"http",...}`)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/install/claude-code.ts"],"names":[],"mappings":"AA8CA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/install/claude-code.ts"],"names":[],"mappings":"AA8CA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIvE;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,eAAe,sBAAsB,CAAC;AAEnD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAc1B;AAyBD,eAAO,MAAM,mBAAmB,EAAE,gBA4CjC,CAAC"}
|
|
@@ -43,7 +43,25 @@
|
|
|
43
43
|
import pc from "picocolors";
|
|
44
44
|
import { promises as fs } from "node:fs";
|
|
45
45
|
import path from "node:path";
|
|
46
|
+
import { readMergeableJson } from "./shared.js";
|
|
47
|
+
import { writeJsonAtomic } from "../util/atomic-write.js";
|
|
46
48
|
import { claudeDesktopConfigPath } from "../detect/claude-code.js";
|
|
49
|
+
/**
|
|
50
|
+
* Pinned mcp-remote version.
|
|
51
|
+
*
|
|
52
|
+
* R33 — `npx -y mcp-remote` resolved to "whatever is latest at install time",
|
|
53
|
+
* so an upstream release could silently change behavior months after we wrote
|
|
54
|
+
* the config (the shape below depends on a specific documented-in-code behavior:
|
|
55
|
+
* `${VAR}` expansion of header values). Pinned so the config a user gets is
|
|
56
|
+
* reproducible; bump deliberately, then re-run scripts/probe-mcp-remote.mjs
|
|
57
|
+
* against the real endpoint before shipping.
|
|
58
|
+
*
|
|
59
|
+
* Verified 2026-10-31 (R33): 0.15.2 still expands `${VAR}` in header values —
|
|
60
|
+
* dist substituteEnvVars() is applied to every parsed header before the
|
|
61
|
+
* transport is built. If a bump ever removes that, every Claude Desktop config
|
|
62
|
+
* we wrote starts 401ing with a literal "${ACP_MCP_AUTH}" header.
|
|
63
|
+
*/
|
|
64
|
+
export const MCP_REMOTE_SPEC = "mcp-remote@0.15.2";
|
|
47
65
|
/**
|
|
48
66
|
* Build the Claude-Desktop-compatible MCP server entry for ACPrompt. See
|
|
49
67
|
* the file-top comment for why this shape (and not `{type:"http",...}`)
|
|
@@ -55,7 +73,7 @@ export function buildClaudeDesktopEntry(opts) {
|
|
|
55
73
|
command: "npx",
|
|
56
74
|
args: [
|
|
57
75
|
"-y",
|
|
58
|
-
|
|
76
|
+
MCP_REMOTE_SPEC,
|
|
59
77
|
opts.mcpUrl,
|
|
60
78
|
"--header",
|
|
61
79
|
"Authorization:${ACP_MCP_AUTH}",
|
|
@@ -66,18 +84,23 @@ export function buildClaudeDesktopEntry(opts) {
|
|
|
66
84
|
};
|
|
67
85
|
}
|
|
68
86
|
async function mergeConfig(configPath, entry) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
catch
|
|
87
|
+
// readMergeableJson returns null only on ENOENT. Any other read/parse
|
|
88
|
+
// problem throws with an actionable message — we must NOT clobber an
|
|
89
|
+
// existing-but-unparseable config, or we'd silently destroy the user's
|
|
90
|
+
// other MCP server entries. (This was the Round-3 data-loss path on
|
|
91
|
+
// Windows where Notepad-saved configs carried a UTF-8 BOM and the old
|
|
92
|
+
// catch-all handler blindly wrote a fresh file on top.)
|
|
93
|
+
const existing = await readMergeableJson(configPath);
|
|
94
|
+
const current = existing ?? {};
|
|
95
|
+
if (!existing) {
|
|
75
96
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
76
97
|
}
|
|
77
98
|
const servers = (current.mcpServers ?? {});
|
|
78
99
|
servers["acprompt"] = entry;
|
|
79
100
|
current.mcpServers = servers;
|
|
80
|
-
|
|
101
|
+
// R33 — atomic: a torn write here destroys every other MCP server the
|
|
102
|
+
// user had configured. See src/util/atomic-write.ts.
|
|
103
|
+
await writeJsonAtomic(configPath, current);
|
|
81
104
|
}
|
|
82
105
|
export const claudeCodeInstaller = async (ic) => {
|
|
83
106
|
const wrote = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/install/claude-code.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,2BAA2B;AAC3B,8DAA8D;AAC9D,oEAAoE;AACpE,uEAAuE;AACvE,yEAAyE;AACzE,EAAE;AACF,wEAAwE;AACxE,sEAAsE;AACtE,EAAE;AACF,+EAA+E;AAC/E,yDAAyD;AACzD,+EAA+E;AAC/E,gFAAgF;AAChF,4EAA4E;AAC5E,yEAAyE;AACzE,2EAA2E;AAC3E,EAAE;AACF,2EAA2E;AAC3E,kEAAkE;AAClE,mEAAmE;AACnE,qEAAqE;AACrE,0EAA0E;AAC1E,yDAAyD;AACzD,sEAAsE;AACtE,EAAE;AACF,qEAAqE;AACrE,oEAAoE;AACpE,0EAA0E;AAC1E,uDAAuD;AACvD,wEAAwE;AACxE,uEAAuE;AACvE,wEAAwE;AACxE,uDAAuD;AACvD,EAAE;AACF,oBAAoB;AACpB,yEAAyE;AACzE,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AACvE,sCAAsC;AAEtC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/install/claude-code.ts"],"names":[],"mappings":"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"}
|
package/dist/install/generic.js
CHANGED
|
@@ -30,7 +30,7 @@ export const genericInstaller = async (ic) => {
|
|
|
30
30
|
console.log(pc.dim("If your harness accepts a claude_desktop_config.json-shaped entry:"));
|
|
31
31
|
console.log(jsonSnippet(ic.mcpUrl, ic.token));
|
|
32
32
|
console.log("");
|
|
33
|
-
console.log(pc.dim("Docs: https://acprompt.com/api/discover"));
|
|
33
|
+
console.log(pc.dim("Docs: https://www.acprompt.com/api/discover"));
|
|
34
34
|
return { wrote: [], printed: ["generic-snippet"] };
|
|
35
35
|
};
|
|
36
36
|
//# sourceMappingURL=generic.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/install/generic.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,qEAAqE;AACrE,+DAA+D;AAC/D,yEAAyE;AACzE,6EAA6E;AAC7E,oCAAoC;AAEpC,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,SAAS,WAAW,CAAC,MAAc,EAAE,KAAa;IAChD,OAAO,IAAI,CAAC,SAAS,CACnB;QACE,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,MAAM;gBACX,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;aAC9C;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAqB,KAAK,EAAE,EAAE,EAAE,EAAE;IAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC,CAAC;IACjF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAC7E,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"generic.js","sourceRoot":"","sources":["../../src/install/generic.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,EAAE;AACF,qEAAqE;AACrE,+DAA+D;AAC/D,yEAAyE;AACzE,6EAA6E;AAC7E,oCAAoC;AAEpC,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,SAAS,WAAW,CAAC,MAAc,EAAE,KAAa;IAChD,OAAO,IAAI,CAAC,SAAS,CACnB;QACE,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,MAAM;gBACZ,GAAG,EAAE,MAAM;gBACX,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;aAC9C;SACF;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAqB,KAAK,EAAE,EAAE,EAAE,EAAE;IAC7D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC,CAAC;IACjF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAC7E,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC;IACnE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;AACrD,CAAC,CAAC"}
|
package/dist/install/letta.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type HarnessInstaller } from "./shared.js";
|
|
2
2
|
export declare function writeLettaMcpConfig(configPath: string, mcpUrl: string, token: string): Promise<void>;
|
|
3
3
|
export declare const lettaInstaller: HarnessInstaller;
|
|
4
4
|
//# sourceMappingURL=letta.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"letta.d.ts","sourceRoot":"","sources":["../../src/install/letta.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"letta.d.ts","sourceRoot":"","sources":["../../src/install/letta.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIvE,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,eAAO,MAAM,cAAc,EAAE,gBAmB5B,CAAC"}
|
package/dist/install/letta.js
CHANGED
|
@@ -17,14 +17,17 @@
|
|
|
17
17
|
import pc from "picocolors";
|
|
18
18
|
import { promises as fs } from "node:fs";
|
|
19
19
|
import path from "node:path";
|
|
20
|
+
import { readMergeableJson } from "./shared.js";
|
|
21
|
+
import { writeJsonAtomic } from "../util/atomic-write.js";
|
|
20
22
|
import { lettaMcpConfigPath } from "../detect/letta.js";
|
|
21
23
|
export async function writeLettaMcpConfig(configPath, mcpUrl, token) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
// See comment in claude-code.ts::mergeConfig — readMergeableJson is the
|
|
25
|
+
// BOM-aware / no-clobber-on-parse-error guard. Same data-loss risk
|
|
26
|
+
// applies here: a Windows Letta user with a BOM-prefixed config would
|
|
27
|
+
// otherwise lose every other entry they had.
|
|
28
|
+
const existing = await readMergeableJson(configPath);
|
|
29
|
+
const current = existing ?? {};
|
|
30
|
+
if (!existing) {
|
|
28
31
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
29
32
|
}
|
|
30
33
|
const servers = (current.mcpServers ?? {});
|
|
@@ -34,7 +37,8 @@ export async function writeLettaMcpConfig(configPath, mcpUrl, token) {
|
|
|
34
37
|
headers: { Authorization: `Bearer ${token}` },
|
|
35
38
|
};
|
|
36
39
|
current.mcpServers = servers;
|
|
37
|
-
|
|
40
|
+
// R33 — atomic write; see src/util/atomic-write.ts.
|
|
41
|
+
await writeJsonAtomic(configPath, current);
|
|
38
42
|
}
|
|
39
43
|
export const lettaInstaller = async (ic) => {
|
|
40
44
|
const configPath = ic.detection.configTargets?.[0] ??
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"letta.js","sourceRoot":"","sources":["../../src/install/letta.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,mEAAmE;AACnE,yCAAyC;AACzC,EAAE;AACF,MAAM;AACN,sBAAsB;AACtB,sBAAsB;AACtB,0CAA0C;AAC1C,qDAAqD;AACrD,2DAA2D;AAC3D,UAAU;AACV,QAAQ;AACR,MAAM;AAEN,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"letta.js","sourceRoot":"","sources":["../../src/install/letta.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,mEAAmE;AACnE,yCAAyC;AACzC,EAAE;AACF,MAAM;AACN,sBAAsB;AACtB,sBAAsB;AACtB,0CAA0C;AAC1C,qDAAqD;AACrD,2DAA2D;AAC3D,UAAU;AACV,QAAQ;AACR,MAAM;AAEN,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAyB,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAkB,EAClB,MAAc,EACd,KAAa;IAEb,wEAAwE;IACxE,mEAAmE;IACnE,sEAAsE;IACtE,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAA4B,CAAC;IACtE,OAAO,CAAC,UAAU,CAAC,GAAG;QACpB,SAAS,EAAE,iBAAiB;QAC5B,GAAG,EAAE,MAAM;QACX,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;KAC9C,CAAC;IACF,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC;IAC7B,oDAAoD;IACpD,MAAM,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAqB,KAAK,EAAE,EAAE,EAAE,EAAE;IAC3D,MAAM,UAAU,GACd,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QAC/B,kBAAkB,CAAC;YACjB,GAAG,EAAE,EAAE,CAAC,IAAI;YACZ,IAAI,EAAE,EAAE,CAAC,IAAI;YACb,QAAQ,EAAE,EAAE,CAAC,QAAQ;YACrB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;IAEL,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;QACf,MAAM,mBAAmB,CAAC,UAAU,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,sCAAsC,UAAU,GAAG,CAAC,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,GAAG,CAAC,gEAAgE,CAAC,CACzE,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAC9C,CAAC,CAAC"}
|
package/dist/install/shared.d.ts
CHANGED
|
@@ -30,4 +30,29 @@ export interface InstallerResult {
|
|
|
30
30
|
export type HarnessInstaller = (ic: InstallerContext) => Promise<InstallerResult>;
|
|
31
31
|
/** Infer whether the repo is Python, JS/TS, or both, from detector evidence. */
|
|
32
32
|
export declare function inferLanguage(evidence: readonly string[] | undefined): "python" | "javascript" | "both";
|
|
33
|
+
/**
|
|
34
|
+
* Read an existing JSON config that an installer is about to merge into.
|
|
35
|
+
*
|
|
36
|
+
* Contract:
|
|
37
|
+
* - File missing (ENOENT) → returns `null`. Caller creates dir + starts
|
|
38
|
+
* with an empty object.
|
|
39
|
+
* - File exists, parses cleanly → returns the parsed object.
|
|
40
|
+
* - File exists, CANNOT be parsed (corrupted JSON, partial save,
|
|
41
|
+
* unexpected non-object root) → throws a clear actionable error.
|
|
42
|
+
* **Never returns `null` or `{}` from a bad-parse**, because the
|
|
43
|
+
* caller would immediately overwrite the file with only our entry,
|
|
44
|
+
* silently destroying every other MCP server the user had configured.
|
|
45
|
+
*
|
|
46
|
+
* BOM-awareness: Windows tools (Notepad, VS Code with "UTF-8 with BOM")
|
|
47
|
+
* sometimes prepend U+FEFF to saved files. Node's `fs.readFile(…, "utf8")`
|
|
48
|
+
* does NOT strip it. A leading BOM makes `JSON.parse` throw with an
|
|
49
|
+
* unhelpful "Unexpected token" message, which under the old catch-all
|
|
50
|
+
* handler silently clobbered the user's whole config. We strip the BOM
|
|
51
|
+
* before parsing.
|
|
52
|
+
*
|
|
53
|
+
* This helper is the load-bearing piece behind the Round-3 data-loss
|
|
54
|
+
* fix; any new merge-write installer added in the future must route
|
|
55
|
+
* through it, not call `fs.readFile` + `JSON.parse` directly.
|
|
56
|
+
*/
|
|
57
|
+
export declare function readMergeableJson(configPath: string): Promise<Record<string, unknown> | null>;
|
|
33
58
|
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/install/shared.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/install/shared.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAO1D,eAAO,MAAM,eAAe,qCAAqC,CAAC;AAElE,MAAM,WAAW,gBAAgB;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,qBAAqB;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IACnC,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,EAAE,EAAE,gBAAgB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAElF,gFAAgF;AAChF,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACtC,QAAQ,GAAG,YAAY,GAAG,MAAM,CAQlC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAiCzC"}
|
package/dist/install/shared.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// (b) prints a code snippet for the user to paste into their own source
|
|
6
6
|
// (LangGraph, CrewAI, OpenAI Agents SDK, Anthropic SDK). The generic
|
|
7
7
|
// fallback prints bare endpoint + header info.
|
|
8
|
+
import { promises as fs } from "node:fs";
|
|
8
9
|
// MUST be the www-prefixed canonical origin. Bare `acprompt.com` 307-redirects
|
|
9
10
|
// to www, and most HTTP clients (including the MCP SDK's StreamableHTTP
|
|
10
11
|
// transport and Node's fetch) strip the Authorization header on cross-host
|
|
@@ -25,4 +26,60 @@ export function inferLanguage(evidence) {
|
|
|
25
26
|
return "javascript";
|
|
26
27
|
return "both";
|
|
27
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Read an existing JSON config that an installer is about to merge into.
|
|
31
|
+
*
|
|
32
|
+
* Contract:
|
|
33
|
+
* - File missing (ENOENT) → returns `null`. Caller creates dir + starts
|
|
34
|
+
* with an empty object.
|
|
35
|
+
* - File exists, parses cleanly → returns the parsed object.
|
|
36
|
+
* - File exists, CANNOT be parsed (corrupted JSON, partial save,
|
|
37
|
+
* unexpected non-object root) → throws a clear actionable error.
|
|
38
|
+
* **Never returns `null` or `{}` from a bad-parse**, because the
|
|
39
|
+
* caller would immediately overwrite the file with only our entry,
|
|
40
|
+
* silently destroying every other MCP server the user had configured.
|
|
41
|
+
*
|
|
42
|
+
* BOM-awareness: Windows tools (Notepad, VS Code with "UTF-8 with BOM")
|
|
43
|
+
* sometimes prepend U+FEFF to saved files. Node's `fs.readFile(…, "utf8")`
|
|
44
|
+
* does NOT strip it. A leading BOM makes `JSON.parse` throw with an
|
|
45
|
+
* unhelpful "Unexpected token" message, which under the old catch-all
|
|
46
|
+
* handler silently clobbered the user's whole config. We strip the BOM
|
|
47
|
+
* before parsing.
|
|
48
|
+
*
|
|
49
|
+
* This helper is the load-bearing piece behind the Round-3 data-loss
|
|
50
|
+
* fix; any new merge-write installer added in the future must route
|
|
51
|
+
* through it, not call `fs.readFile` + `JSON.parse` directly.
|
|
52
|
+
*/
|
|
53
|
+
export async function readMergeableJson(configPath) {
|
|
54
|
+
let raw;
|
|
55
|
+
try {
|
|
56
|
+
raw = await fs.readFile(configPath, "utf8");
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const code = err.code;
|
|
60
|
+
if (code === "ENOENT")
|
|
61
|
+
return null;
|
|
62
|
+
throw err;
|
|
63
|
+
}
|
|
64
|
+
// Strip UTF-8 BOM if present. `fs.readFile("…", "utf8")` keeps it —
|
|
65
|
+
// Node does not auto-strip, contrary to some cross-platform assumptions.
|
|
66
|
+
const body = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;
|
|
67
|
+
let parsed;
|
|
68
|
+
try {
|
|
69
|
+
parsed = JSON.parse(body);
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
throw new Error(`Cannot parse existing config at ${configPath}: ${err.message}. ` +
|
|
73
|
+
`Refusing to overwrite — fix or delete the file, then re-run install.`);
|
|
74
|
+
}
|
|
75
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
76
|
+
// typeof null === "object", so we check for null explicitly before
|
|
77
|
+
// falling back to the runtime type label. The reported kind drives a
|
|
78
|
+
// regression assertion in merge-safety.test.ts.
|
|
79
|
+
const kind = parsed === null ? "null" : Array.isArray(parsed) ? "array" : typeof parsed;
|
|
80
|
+
throw new Error(`Expected a JSON object at ${configPath}, got ${kind}. ` +
|
|
81
|
+
`Refusing to overwrite — fix or delete the file, then re-run install.`);
|
|
82
|
+
}
|
|
83
|
+
return parsed;
|
|
84
|
+
}
|
|
28
85
|
//# sourceMappingURL=shared.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/install/shared.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AACxE,qEAAqE;AACrE,+CAA+C;
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/install/shared.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AACxE,qEAAqE;AACrE,+CAA+C;AAE/C,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAGzC,+EAA+E;AAC/E,wEAAwE;AACxE,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,MAAM,CAAC,MAAM,eAAe,GAAG,kCAAkC,CAAC;AAiClE,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAC3B,QAAuC;IAEvC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACtD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mCAAmC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,IAAI,KAAK,IAAI,KAAK;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC3B,IAAI,KAAK;QAAE,OAAO,YAAY,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAkB;IAElB,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACnC,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,oEAAoE;IACpE,yEAAyE;IACzE,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC/D,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,mCAAmC,UAAU,KAAM,GAAa,CAAC,OAAO,IAAI;YAC1E,sEAAsE,CACzE,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,mEAAmE;QACnE,qEAAqE;QACrE,gDAAgD;QAChD,MAAM,IAAI,GACR,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC;QAC7E,MAAM,IAAI,KAAK,CACb,6BAA6B,UAAU,SAAS,IAAI,IAAI;YACtD,sEAAsE,CACzE,CAAC;IACJ,CAAC;IACD,OAAO,MAAiC,CAAC;AAC3C,CAAC"}
|
package/dist/mcp/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AA0CD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,cAAc,CAAC,CAwCzB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,cAAc,CAAC,CAE1B"}
|
package/dist/mcp/client.js
CHANGED
|
@@ -14,9 +14,14 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
|
14
14
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
15
15
|
import { getToken } from "../auth/token-store.js";
|
|
16
16
|
import { loadOrCreateIdentity, signMessage } from "../identity/keypair.js";
|
|
17
|
+
import { CLI_VERSION } from "../version.js";
|
|
18
|
+
// CLIENT_INFO.version must match package.json.version — it's what the
|
|
19
|
+
// server sees as `clientInfo.version` on MCP initialize. Hardcoding drifted
|
|
20
|
+
// (0.1.0 stuck while the package shipped 0.1.7); `CLI_VERSION` reads from
|
|
21
|
+
// package.json at startup so it can't get stale. See src/version.ts.
|
|
17
22
|
const CLIENT_INFO = {
|
|
18
23
|
name: "acprompt-join",
|
|
19
|
-
version:
|
|
24
|
+
version: CLI_VERSION,
|
|
20
25
|
};
|
|
21
26
|
function extractChallenge(content) {
|
|
22
27
|
// MCP returns `content: [{type:"text", text:"..."}, ...]`. The server
|
package/dist/mcp/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,oBAAoB;AACpB,6DAA6D;AAC7D,0EAA0E;AAC1E,6EAA6E;AAC7E,uEAAuE;AACvE,gBAAgB;AAChB,yCAAyC;AACzC,EAAE;AACF,yEAAyE;AACzE,6DAA6D;AAE7D,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface AtomicWriteOptions {
|
|
2
|
+
/** File mode for the temp file (e.g. 0o600 for secrets). */
|
|
3
|
+
mode?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare function writeFileAtomic(targetPath: string, data: string, opts?: AtomicWriteOptions): Promise<void>;
|
|
6
|
+
/** JSON convenience wrapper: pretty-print then write atomically. */
|
|
7
|
+
export declare function writeJsonAtomic(targetPath: string, value: unknown, opts?: AtomicWriteOptions): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=atomic-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.d.ts","sourceRoot":"","sources":["../../src/util/atomic-write.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,oEAAoE;AACpE,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Atomic file write — serialize to a sibling temp file, fsync, rename over
|
|
2
|
+
// the target.
|
|
3
|
+
//
|
|
4
|
+
// Why this exists: several installers merge our entry into a config file the
|
|
5
|
+
// user already owns (Claude Desktop's claude_desktop_config.json, Letta's mcp
|
|
6
|
+
// config, ~/.acprompt/config.json). A plain `fs.writeFile` truncates the target
|
|
7
|
+
// first and then streams the new bytes in, so a crash, a full disk, a killed
|
|
8
|
+
// process, or a Windows antivirus/OneDrive lock in the middle of that window
|
|
9
|
+
// leaves a HALF-WRITTEN file. For a merged config that means the user's other
|
|
10
|
+
// MCP servers are gone; for the token store it means auth silently breaks.
|
|
11
|
+
//
|
|
12
|
+
// rename(2) within one directory is atomic, so the target is always either the
|
|
13
|
+
// complete old file or the complete new one.
|
|
14
|
+
import { promises as fs } from "node:fs";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import { randomBytes } from "node:crypto";
|
|
17
|
+
export async function writeFileAtomic(targetPath, data, opts = {}) {
|
|
18
|
+
const dir = path.dirname(targetPath);
|
|
19
|
+
const tmpPath = path.join(dir, `.${path.basename(targetPath)}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`);
|
|
20
|
+
let handle;
|
|
21
|
+
try {
|
|
22
|
+
handle = await fs.open(tmpPath, "w", opts.mode ?? 0o644);
|
|
23
|
+
await handle.writeFile(data, "utf8");
|
|
24
|
+
// Flush to disk before the rename, otherwise a power loss can leave the
|
|
25
|
+
// renamed (empty) file behind on some filesystems.
|
|
26
|
+
await handle.sync();
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
await handle?.close();
|
|
30
|
+
}
|
|
31
|
+
// Windows: rename over an existing file fails with EPERM/EBUSY while another
|
|
32
|
+
// process (editor, antivirus, sync client) holds a handle. Retry briefly —
|
|
33
|
+
// these are almost always short-lived — then fail loudly with the real cause.
|
|
34
|
+
const attempts = process.platform === "win32" ? 5 : 1;
|
|
35
|
+
let lastErr;
|
|
36
|
+
for (let i = 0; i < attempts; i++) {
|
|
37
|
+
try {
|
|
38
|
+
await fs.rename(tmpPath, targetPath);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
lastErr = err;
|
|
43
|
+
const code = err.code;
|
|
44
|
+
if (code !== "EPERM" && code !== "EBUSY" && code !== "EACCES")
|
|
45
|
+
break;
|
|
46
|
+
await new Promise((r) => setTimeout(r, 60 * (i + 1)));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Never leave the temp fragment behind on failure.
|
|
50
|
+
await fs.rm(tmpPath, { force: true }).catch(() => undefined);
|
|
51
|
+
throw new Error(`Could not write ${targetPath} atomically: ${lastErr?.message ?? "unknown error"}. ` +
|
|
52
|
+
`The existing file was left untouched. Close any program holding it open and retry.`);
|
|
53
|
+
}
|
|
54
|
+
/** JSON convenience wrapper: pretty-print then write atomically. */
|
|
55
|
+
export async function writeJsonAtomic(targetPath, value, opts = {}) {
|
|
56
|
+
await writeFileAtomic(targetPath, JSON.stringify(value, null, 2), opts);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=atomic-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomic-write.js","sourceRoot":"","sources":["../../src/util/atomic-write.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,cAAc;AACd,EAAE;AACF,6EAA6E;AAC7E,8EAA8E;AAC9E,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,2EAA2E;AAC3E,EAAE;AACF,+EAA+E;AAC/E,6CAA6C;AAE7C,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,IAAY,EACZ,OAA2B,EAAE;IAE7B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CACvB,GAAG,EACH,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CACrF,CAAC;IAEF,IAAI,MAAuD,CAAC;IAC5D,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC;QACzD,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACrC,wEAAwE;QACxE,mDAAmD;QACnD,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,6EAA6E;IAC7E,2EAA2E;IAC3E,8EAA8E;IAC9E,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,OAAgB,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,GAAG,GAAG,CAAC;YACd,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;YACjD,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,QAAQ;gBAAE,MAAM;YACrE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,IAAI,KAAK,CACb,mBAAmB,UAAU,gBAAiB,OAAiB,EAAE,OAAO,IAAI,eAAe,IAAI;QAC7F,oFAAoF,CACvF,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,KAAc,EACd,OAA2B,EAAE;IAE7B,MAAM,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AA+CA,eAAO,MAAM,WAAW,QAAmB,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Single source of truth for the CLI version.
|
|
2
|
+
//
|
|
3
|
+
// Why a runtime read instead of a string constant?
|
|
4
|
+
// The CLI version ends up in two places that matter:
|
|
5
|
+
// 1. commander's `.version()` — what `acprompt-join --version` prints.
|
|
6
|
+
// 2. `CLIENT_INFO.version` on the MCP client — what the server sees as
|
|
7
|
+
// the `clientInfo.version` field during `initialize` (telemetry +
|
|
8
|
+
// any future per-version gating).
|
|
9
|
+
// Both must match `package.json.version`. Historically (pre-v0.1.8) we
|
|
10
|
+
// hardcoded the version in both places and the CLIENT_INFO one drifted
|
|
11
|
+
// (stuck at "0.1.0" while the package shipped 0.1.7). Reading the real
|
|
12
|
+
// package.json at startup makes drift structurally impossible.
|
|
13
|
+
//
|
|
14
|
+
// Why not `import pkg from "../package.json"`?
|
|
15
|
+
// Node 20's JSON-module import requires `assert { type: "json" }`;
|
|
16
|
+
// Node 22+ prefers `with { type: "json" }`. The two are not fully
|
|
17
|
+
// interchangeable, and we want the CLI to run unchanged on both LTS
|
|
18
|
+
// versions. A plain `fs.readFileSync` sidesteps the whole saga.
|
|
19
|
+
//
|
|
20
|
+
// Path resolution:
|
|
21
|
+
// At runtime this file lives at `dist/version.js` (published under
|
|
22
|
+
// `node_modules/@acprompt/join/dist/version.js`). `package.json` is one
|
|
23
|
+
// level up at `node_modules/@acprompt/join/package.json`. We derive the
|
|
24
|
+
// path from `import.meta.url` so it works regardless of where npm put
|
|
25
|
+
// the package, and regardless of the current working directory.
|
|
26
|
+
import { readFileSync } from "node:fs";
|
|
27
|
+
import { fileURLToPath } from "node:url";
|
|
28
|
+
import path from "node:path";
|
|
29
|
+
function readCliVersion() {
|
|
30
|
+
try {
|
|
31
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
32
|
+
const pkgPath = path.resolve(here, "..", "package.json");
|
|
33
|
+
const raw = readFileSync(pkgPath, "utf8");
|
|
34
|
+
const parsed = JSON.parse(raw);
|
|
35
|
+
if (typeof parsed.version === "string" && parsed.version.length > 0) {
|
|
36
|
+
return parsed.version;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Fall through to the sentinel below. We deliberately swallow the
|
|
41
|
+
// error — the CLI is still functional without a precise version
|
|
42
|
+
// string, and throwing here would break every code path transitively.
|
|
43
|
+
}
|
|
44
|
+
return "0.0.0-unknown";
|
|
45
|
+
}
|
|
46
|
+
export const CLI_VERSION = readCliVersion();
|
|
47
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,EAAE;AACF,mDAAmD;AACnD,uDAAuD;AACvD,2EAA2E;AAC3E,2EAA2E;AAC3E,yEAAyE;AACzE,yCAAyC;AACzC,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,iEAAiE;AACjE,EAAE;AACF,+CAA+C;AAC/C,qEAAqE;AACrE,oEAAoE;AACpE,sEAAsE;AACtE,kEAAkE;AAClE,EAAE;AACF,mBAAmB;AACnB,qEAAqE;AACrE,0EAA0E;AAC1E,0EAA0E;AAC1E,wEAAwE;AACxE,kEAAkE;AAElE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;QACzD,MAAM,GAAG,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpE,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;QAClE,gEAAgE;QAChE,sEAAsE;IACxE,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC"}
|