agent-gate-installer 1.3.1 → 1.4.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/bin/install.mjs +20 -3
- package/bin/install.test.mjs +115 -0
- package/package.json +1 -1
package/bin/install.mjs
CHANGED
|
@@ -132,6 +132,21 @@ function registerMcpServer(settings, venvPython) {
|
|
|
132
132
|
log(" + Registered agent-gate MCP server");
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
function writeMcpConfigFile(venvPython) {
|
|
136
|
+
const mcpConfigPath = join("/tmp", "agent-gate-mcp-config.json");
|
|
137
|
+
const config = {
|
|
138
|
+
mcpServers: {
|
|
139
|
+
"agent-gate": {
|
|
140
|
+
type: "stdio",
|
|
141
|
+
command: venvPython,
|
|
142
|
+
args: [join(INSTALL_DIR, "src", "agent_gate", "server.py")],
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
writeFileSync(mcpConfigPath, JSON.stringify(config, null, 4) + "\n", "utf8");
|
|
147
|
+
log(` + Wrote ${mcpConfigPath}`);
|
|
148
|
+
}
|
|
149
|
+
|
|
135
150
|
async function promptForToken() {
|
|
136
151
|
const readline = createInterface({ input: process.stdin, output: process.stdout });
|
|
137
152
|
return new Promise((resolve) => {
|
|
@@ -164,6 +179,11 @@ async function install() {
|
|
|
164
179
|
|
|
165
180
|
mkdirSync(CLAUDE_HOME, { recursive: true });
|
|
166
181
|
|
|
182
|
+
const venvDirectory = join(INSTALL_DIR, ".venv");
|
|
183
|
+
const venvPython = getVenvPython(venvDirectory);
|
|
184
|
+
|
|
185
|
+
writeMcpConfigFile(venvPython);
|
|
186
|
+
|
|
167
187
|
if (existsSync(join(INSTALL_DIR, ".git"))) {
|
|
168
188
|
log(" ~ agent-gate already cloned, pulling latest...");
|
|
169
189
|
try {
|
|
@@ -184,9 +204,6 @@ async function install() {
|
|
|
184
204
|
}
|
|
185
205
|
}
|
|
186
206
|
|
|
187
|
-
const venvDirectory = join(INSTALL_DIR, ".venv");
|
|
188
|
-
const venvPython = getVenvPython(venvDirectory);
|
|
189
|
-
|
|
190
207
|
if (existsSync(venvDirectory)) {
|
|
191
208
|
log(" ~ venv already exists");
|
|
192
209
|
} else {
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Tests for writeMcpConfigFile behavior in install.mjs.
|
|
5
|
+
*
|
|
6
|
+
* Verifies that /tmp/agent-gate-mcp-config.json is written even when
|
|
7
|
+
* earlier install steps (clone, venv, pip) fail.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { existsSync, readFileSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { execSync } from "node:child_process";
|
|
13
|
+
|
|
14
|
+
const MCP_CONFIG_PATH = "/tmp/agent-gate-mcp-config.json";
|
|
15
|
+
let passed = 0;
|
|
16
|
+
let failed = 0;
|
|
17
|
+
|
|
18
|
+
function cleanup() {
|
|
19
|
+
try { rmSync(MCP_CONFIG_PATH); } catch { /* ok */ }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function assert(condition, message) {
|
|
23
|
+
if (condition) {
|
|
24
|
+
console.log(` PASS: ${message}`);
|
|
25
|
+
passed++;
|
|
26
|
+
} else {
|
|
27
|
+
console.log(` FAIL: ${message}`);
|
|
28
|
+
failed++;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// --- Test 1: writeMcpConfigFile writes correct content ---
|
|
33
|
+
console.log("\nTest 1: writeMcpConfigFile writes correct JSON");
|
|
34
|
+
cleanup();
|
|
35
|
+
{
|
|
36
|
+
// Inline the function logic to test it in isolation
|
|
37
|
+
const venvPython = "/root/.claude/agent-gate/.venv/bin/python";
|
|
38
|
+
const INSTALL_DIR = "/root/.claude/agent-gate";
|
|
39
|
+
const config = {
|
|
40
|
+
mcpServers: {
|
|
41
|
+
"agent-gate": {
|
|
42
|
+
type: "stdio",
|
|
43
|
+
command: venvPython,
|
|
44
|
+
args: [join(INSTALL_DIR, "src", "agent_gate", "server.py")],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
writeFileSync(MCP_CONFIG_PATH, JSON.stringify(config, null, 4) + "\n", "utf8");
|
|
49
|
+
|
|
50
|
+
assert(existsSync(MCP_CONFIG_PATH), "File exists at /tmp/agent-gate-mcp-config.json");
|
|
51
|
+
|
|
52
|
+
const content = JSON.parse(readFileSync(MCP_CONFIG_PATH, "utf8"));
|
|
53
|
+
assert(content.mcpServers?.["agent-gate"] !== undefined, "Has agent-gate MCP server entry");
|
|
54
|
+
assert(content.mcpServers["agent-gate"].type === "stdio", "Type is stdio");
|
|
55
|
+
assert(content.mcpServers["agent-gate"].command === venvPython, "Command points to venv python");
|
|
56
|
+
assert(
|
|
57
|
+
content.mcpServers["agent-gate"].args[0].endsWith("server.py"),
|
|
58
|
+
"Args point to server.py"
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
cleanup();
|
|
62
|
+
|
|
63
|
+
// --- Test 2: Simulate install failure — MCP config should still be written ---
|
|
64
|
+
console.log("\nTest 2: MCP config written even when install exits early");
|
|
65
|
+
cleanup();
|
|
66
|
+
{
|
|
67
|
+
// Run the installer with a bad GH_TOKEN in non-interactive mode.
|
|
68
|
+
// The clone step will fail, but we want the MCP config to exist.
|
|
69
|
+
try {
|
|
70
|
+
execSync(
|
|
71
|
+
`GH_TOKEN=bad_token node "${join(import.meta.dirname, "install.mjs")}" --non-interactive`,
|
|
72
|
+
{ encoding: "utf8", stdio: "pipe", timeout: 30000 }
|
|
73
|
+
);
|
|
74
|
+
} catch {
|
|
75
|
+
// Expected — install fails at clone step
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
assert(
|
|
79
|
+
existsSync(MCP_CONFIG_PATH),
|
|
80
|
+
"MCP config file exists after failed install (written before clone)"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
cleanup();
|
|
84
|
+
|
|
85
|
+
// --- Test 3: Simulate install with existing clone but broken pip ---
|
|
86
|
+
console.log("\nTest 3: MCP config written even when pip install fails");
|
|
87
|
+
cleanup();
|
|
88
|
+
{
|
|
89
|
+
// Create a fake INSTALL_DIR so clone is skipped, but venv/pip will fail
|
|
90
|
+
const fakeInstallDir = "/tmp/agent-gate-test-install";
|
|
91
|
+
try { rmSync(fakeInstallDir, { recursive: true }); } catch { /* ok */ }
|
|
92
|
+
mkdirSync(join(fakeInstallDir, ".git"), { recursive: true });
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
execSync(
|
|
96
|
+
`HOME=/tmp/agent-gate-test-home GH_TOKEN=x node "${join(import.meta.dirname, "install.mjs")}" --non-interactive`,
|
|
97
|
+
{ encoding: "utf8", stdio: "pipe", timeout: 30000, env: { ...process.env, HOME: "/tmp/agent-gate-test-home" } }
|
|
98
|
+
);
|
|
99
|
+
} catch {
|
|
100
|
+
// Expected — install fails at venv/pip step
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
assert(
|
|
104
|
+
existsSync(MCP_CONFIG_PATH),
|
|
105
|
+
"MCP config file exists after pip failure (written before pip)"
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
try { rmSync(fakeInstallDir, { recursive: true }); } catch { /* ok */ }
|
|
109
|
+
try { rmSync("/tmp/agent-gate-test-home", { recursive: true }); } catch { /* ok */ }
|
|
110
|
+
}
|
|
111
|
+
cleanup();
|
|
112
|
+
|
|
113
|
+
// --- Summary ---
|
|
114
|
+
console.log(`\n${passed} passed, ${failed} failed\n`);
|
|
115
|
+
process.exit(failed > 0 ? 1 : 0);
|