@agent-chat/mention-watcher 0.0.2 → 0.0.5
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.
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// src/setup.ts
|
|
4
4
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
5
5
|
import { join } from "path";
|
|
6
|
+
import { userInfo } from "os";
|
|
6
7
|
function loadEnvFile(path) {
|
|
7
8
|
if (!existsSync(path)) return {};
|
|
8
9
|
const result = {};
|
|
@@ -56,11 +57,13 @@ async function runSetup() {
|
|
|
56
57
|
const envPath = join(cwd, ".env");
|
|
57
58
|
const fileEnv = loadEnvFile(envPath);
|
|
58
59
|
const env = { ...fileEnv, ...process.env };
|
|
60
|
+
const sysUser = userInfo().username ?? "user";
|
|
61
|
+
const sysName = sysUser.charAt(0).toUpperCase() + sysUser.slice(1);
|
|
59
62
|
const API_URL = env.API_SERVER_URL ?? "http://localhost:3000";
|
|
60
|
-
const EMAIL = env.SETUP_EMAIL ?? env.ADMIN_EMAIL ??
|
|
61
|
-
const PASSWORD = env.SETUP_PASSWORD ?? env.ADMIN_PASSWORD ??
|
|
62
|
-
const NAME = env.SETUP_NAME ?? env.ADMIN_NAME ??
|
|
63
|
-
const AGENT_NAME = env.SETUP_AGENT_NAME ?? env.AGENT_NAME ??
|
|
63
|
+
const EMAIL = env.SETUP_EMAIL ?? env.ADMIN_EMAIL ?? `${sysUser}@localhost`;
|
|
64
|
+
const PASSWORD = env.SETUP_PASSWORD ?? env.ADMIN_PASSWORD ?? `${sysUser}123`;
|
|
65
|
+
const NAME = env.SETUP_NAME ?? env.ADMIN_NAME ?? sysName;
|
|
66
|
+
const AGENT_NAME = env.SETUP_AGENT_NAME ?? env.AGENT_NAME ?? `${sysUser}-agent`;
|
|
64
67
|
const MCP_NAME = env.MCP_SERVER_NAME ?? "agent-chat";
|
|
65
68
|
console.log(`
|
|
66
69
|
agent-chat setup`);
|
|
@@ -68,26 +71,56 @@ agent-chat setup`);
|
|
|
68
71
|
console.log(` Account : ${EMAIL}`);
|
|
69
72
|
console.log(` Agent name : ${AGENT_NAME}`);
|
|
70
73
|
console.log("");
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
74
|
+
async function post(path, body) {
|
|
75
|
+
try {
|
|
76
|
+
return await fetch(`${API_URL}${path}`, {
|
|
77
|
+
method: "POST",
|
|
78
|
+
headers: { "Content-Type": "application/json" },
|
|
79
|
+
body: JSON.stringify(body)
|
|
80
|
+
});
|
|
81
|
+
} catch (err) {
|
|
82
|
+
console.error(` \u2717 Could not reach API server at ${API_URL}`);
|
|
83
|
+
console.error(` Make sure the dev server is running: pnpm dev`);
|
|
84
|
+
console.error(` Error: ${err.message}`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
let loginRes = await post("/auth/login", { email: EMAIL, password: PASSWORD });
|
|
89
|
+
if (!loginRes.ok) {
|
|
90
|
+
const loginErr = await loginRes.json().catch(() => ({ error: loginRes.statusText }));
|
|
91
|
+
const shouldRegister = loginRes.status === 401 || loginRes.status === 404;
|
|
92
|
+
if (!shouldRegister) {
|
|
93
|
+
console.error(` \u2717 Login failed (${loginRes.status}): ${loginErr.error ?? loginRes.statusText}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
console.log(` \u2192 Account not found, registering as "${NAME}"\u2026`);
|
|
97
|
+
const regRes = await post("/auth/register", { name: NAME, email: EMAIL, password: PASSWORD });
|
|
98
|
+
if (!regRes.ok) {
|
|
99
|
+
const regErr = await regRes.json().catch(() => ({ error: regRes.statusText }));
|
|
100
|
+
console.error(` \u2717 Registration failed (${regRes.status}): ${regErr.error ?? regRes.statusText}`);
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
console.log(` \u2713 Registered: ${NAME} <${EMAIL}>`);
|
|
104
|
+
loginRes = await post("/auth/login", { email: EMAIL, password: PASSWORD });
|
|
105
|
+
if (!loginRes.ok) {
|
|
106
|
+
console.error(` \u2717 Login after registration failed`);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
83
109
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
110
|
+
const loginData = await loginRes.json();
|
|
111
|
+
console.log(` \u2713 Logged in: ${loginData.entity.name} <${loginData.entity.email}>`);
|
|
112
|
+
const setupRes = await post("/auth/setup", {
|
|
113
|
+
name: NAME,
|
|
114
|
+
email: EMAIL,
|
|
115
|
+
password: PASSWORD,
|
|
116
|
+
agentName: AGENT_NAME
|
|
117
|
+
});
|
|
118
|
+
if (!setupRes.ok) {
|
|
119
|
+
const body = await setupRes.text();
|
|
120
|
+
console.error(` \u2717 Agent provisioning failed (${setupRes.status}): ${body}`);
|
|
87
121
|
process.exit(1);
|
|
88
122
|
}
|
|
89
|
-
const data = await
|
|
90
|
-
console.log(` \u2713 Account : ${data.entity.name} <${data.entity.email}>`);
|
|
123
|
+
const data = await setupRes.json();
|
|
91
124
|
console.log(` \u2713 Agent : ${data.agentEntity.name}`);
|
|
92
125
|
console.log(` \u2713 Token : ${data.agentToken}`);
|
|
93
126
|
console.log("");
|
package/dist/cli.js
CHANGED
package/dist/setup.js
CHANGED
package/dist/watch.js
CHANGED
|
@@ -5,6 +5,57 @@ import * as fs from "fs";
|
|
|
5
5
|
import * as path from "path";
|
|
6
6
|
import * as pty from "node-pty";
|
|
7
7
|
import { WebSocket } from "ws";
|
|
8
|
+
function loadEnvFile(filePath) {
|
|
9
|
+
if (!fs.existsSync(filePath)) return {};
|
|
10
|
+
const result = {};
|
|
11
|
+
for (const line of fs.readFileSync(filePath, "utf8").split("\n")) {
|
|
12
|
+
const trimmed = line.trim();
|
|
13
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
14
|
+
const eq = trimmed.indexOf("=");
|
|
15
|
+
if (eq < 0) continue;
|
|
16
|
+
const key = trimmed.slice(0, eq).trim();
|
|
17
|
+
const val = trimmed.slice(eq + 1).trim().replace(/^["']|["']$/g, "");
|
|
18
|
+
result[key] = val;
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
function syncMcpToken(workspaceDir, mcpServerName) {
|
|
23
|
+
const envToken = loadEnvFile(path.join(workspaceDir, ".env")).AGENT_TOKEN;
|
|
24
|
+
if (!envToken) return;
|
|
25
|
+
const claudePaths = [
|
|
26
|
+
path.join(workspaceDir, ".mcp.json"),
|
|
27
|
+
path.join(workspaceDir, ".claude", "mcp.json")
|
|
28
|
+
];
|
|
29
|
+
for (const configPath of claudePaths) {
|
|
30
|
+
if (!fs.existsSync(configPath)) continue;
|
|
31
|
+
let config;
|
|
32
|
+
try {
|
|
33
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
34
|
+
} catch {
|
|
35
|
+
process.stderr.write(`[mention-watcher] Could not parse ${configPath}, skipping
|
|
36
|
+
`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const server = config?.mcpServers?.[mcpServerName];
|
|
40
|
+
if (!server) continue;
|
|
41
|
+
const current = server.env?.AGENT_TOKEN;
|
|
42
|
+
if (current === envToken) {
|
|
43
|
+
process.stderr.write(`[mention-watcher] MCP token up-to-date: ${configPath}
|
|
44
|
+
`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
server.env = server.env ?? {};
|
|
48
|
+
server.env.AGENT_TOKEN = envToken;
|
|
49
|
+
try {
|
|
50
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
51
|
+
process.stderr.write(`[mention-watcher] MCP token synced: ${configPath}
|
|
52
|
+
`);
|
|
53
|
+
} catch (err) {
|
|
54
|
+
process.stderr.write(`[mention-watcher] Failed to write ${configPath}: ${err.message}
|
|
55
|
+
`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
8
59
|
var AGENT_TOKEN = process.env.AGENT_TOKEN ?? "";
|
|
9
60
|
var WS_URL = process.env.WS_SERVER_URL ?? "ws://localhost:3001";
|
|
10
61
|
var API_URL = process.env.API_SERVER_URL ?? "http://localhost:3000";
|
|
@@ -136,6 +187,7 @@ async function main() {
|
|
|
136
187
|
process.stderr.write("[mention-watcher] Error: AGENT_TOKEN is required\n");
|
|
137
188
|
process.exit(1);
|
|
138
189
|
}
|
|
190
|
+
syncMcpToken(WORKSPACE_DIR, MCP_NAME);
|
|
139
191
|
const jwt = await resolveJwt();
|
|
140
192
|
const cols = process.stdout.columns || 80;
|
|
141
193
|
const rows = process.stdout.rows || 24;
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-chat/mention-watcher",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "PTY wrapper that pushes @mentions from agent-chat into Claude Code (or any LLM CLI)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
+
"mention-watcher": "./dist/cli.js",
|
|
7
8
|
"agent-chat": "./dist/cli.js",
|
|
8
9
|
"agent-chat-watch": "./dist/watch.js",
|
|
9
10
|
"agent-chat-setup": "./dist/setup.js"
|