multi-ccp 0.1.3 → 0.1.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.
- package/README.md +44 -17
- package/README.zh-CN.md +44 -17
- package/dist/cli/program.js +213 -19
- package/dist/cli/program.js.map +1 -1
- package/dist/core/ccr.js +19 -1
- package/dist/core/ccr.js.map +1 -1
- package/dist/core/presets.d.ts +47 -0
- package/dist/core/presets.js +142 -0
- package/dist/core/presets.js.map +1 -0
- package/dist/core/profiles.d.ts +2 -1
- package/dist/core/profiles.js +19 -3
- package/dist/core/profiles.js.map +1 -1
- package/dist/core/types.d.ts +8 -0
- package/dist/web/assets/app.js +71 -0
- package/dist/web/assets/index.html +111 -0
- package/dist/web/assets/styles.css +1 -0
- package/dist/web/server.d.ts +6 -0
- package/dist/web/server.js +531 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
import { spawn } from "node:child_process";
|
|
8
|
+
import { assertProfileName, CcpError } from "../core/errors.js";
|
|
9
|
+
import { getHomeWorkDir, getMainClaudeDir } from "../core/paths.js";
|
|
10
|
+
import { createApiProfile, createCcrProfile, createLoginProfile, listProfiles, removeProfile, resolveConfigDir, summarizeProfile } from "../core/profiles.js";
|
|
11
|
+
import { ensureCcrPreset, getCcrRouteChoices, getCcrStatus, readCcrConfig, restartCcrService, startCcrService, stopCcrService } from "../core/ccr.js";
|
|
12
|
+
import { createApiProfileFromPreset, createCcrProfileFromPreset, listProfilePresets } from "../core/presets.js";
|
|
13
|
+
import { readMeta, readSettings, writeMeta, writeSettings } from "../core/settings.js";
|
|
14
|
+
const DEFAULT_HOST = "127.0.0.1";
|
|
15
|
+
const DEFAULT_PORT = 7821;
|
|
16
|
+
const JSON_HEADERS = { "content-type": "application/json; charset=utf-8" };
|
|
17
|
+
let nextActivityId = 1;
|
|
18
|
+
const activity = [];
|
|
19
|
+
function addActivity(type, message) {
|
|
20
|
+
activity.unshift({ id: nextActivityId++, time: new Date().toISOString(), type, message: redact(message) });
|
|
21
|
+
if (activity.length > 100)
|
|
22
|
+
activity.pop();
|
|
23
|
+
}
|
|
24
|
+
function redact(value) {
|
|
25
|
+
return value
|
|
26
|
+
.replace(/(ANTHROPIC_AUTH_TOKEN\s*[=:]\s*)[^\s,}]+/gi, "$1[redacted]")
|
|
27
|
+
.replace(/(authorization\s*[:=]\s*bearer\s+)[^\s,}]+/gi, "$1[redacted]")
|
|
28
|
+
.replace(/(api[_-]?key\s*[=:]\s*)[^\s,}]+/gi, "$1[redacted]")
|
|
29
|
+
.replace(/sk-[A-Za-z0-9._-]{8,}/g, "sk-****");
|
|
30
|
+
}
|
|
31
|
+
function json(res, status, data) {
|
|
32
|
+
res.writeHead(status, JSON_HEADERS);
|
|
33
|
+
res.end(JSON.stringify(data));
|
|
34
|
+
}
|
|
35
|
+
function notFound(res) {
|
|
36
|
+
json(res, 404, { error: "Not found" });
|
|
37
|
+
}
|
|
38
|
+
function methodNotAllowed(res) {
|
|
39
|
+
json(res, 405, { error: "Method not allowed" });
|
|
40
|
+
}
|
|
41
|
+
async function readJsonBody(req) {
|
|
42
|
+
const chunks = [];
|
|
43
|
+
for await (const chunk of req)
|
|
44
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
45
|
+
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
46
|
+
if (!raw)
|
|
47
|
+
return {};
|
|
48
|
+
return JSON.parse(raw);
|
|
49
|
+
}
|
|
50
|
+
function requireToken(req, token) {
|
|
51
|
+
if (req.headers["x-ccp-ui-token"] !== token) {
|
|
52
|
+
throw new CcpError("Invalid UI token.");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function publicSettings(settings) {
|
|
56
|
+
if (!settings)
|
|
57
|
+
return undefined;
|
|
58
|
+
const cloned = JSON.parse(JSON.stringify(settings));
|
|
59
|
+
if (cloned.env?.ANTHROPIC_AUTH_TOKEN) {
|
|
60
|
+
cloned.env.ANTHROPIC_AUTH_TOKEN = maskToken(cloned.env.ANTHROPIC_AUTH_TOKEN);
|
|
61
|
+
}
|
|
62
|
+
return cloned;
|
|
63
|
+
}
|
|
64
|
+
function maskToken(token) {
|
|
65
|
+
if (!token || token === "REPLACE_WITH_FULL_TOKEN")
|
|
66
|
+
return "missing";
|
|
67
|
+
if (token.length <= 8)
|
|
68
|
+
return "configured";
|
|
69
|
+
return `${token.slice(0, 3)}****${token.slice(-4)}`;
|
|
70
|
+
}
|
|
71
|
+
function hostnameOf(url) {
|
|
72
|
+
try {
|
|
73
|
+
return new URL(url).hostname;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return url;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function tagsForProfile(profile, isMain, ccrRunning) {
|
|
80
|
+
const type = isMain ? "main" : profile.type;
|
|
81
|
+
const tags = [];
|
|
82
|
+
tags.push(type === "main" ? "Main" : type === "api" ? "API" : type === "login" ? "Login" : type === "ccr" ? "CCR" : "Unknown");
|
|
83
|
+
let status = "ready";
|
|
84
|
+
let statusText = "Ready";
|
|
85
|
+
if (profile.type === "api" && profile.tokenStatus === "missing") {
|
|
86
|
+
status = "needs_attention";
|
|
87
|
+
statusText = "Missing Token";
|
|
88
|
+
}
|
|
89
|
+
if (profile.type === "api" && !profile.baseUrl) {
|
|
90
|
+
status = "needs_attention";
|
|
91
|
+
statusText = "Missing Base URL";
|
|
92
|
+
}
|
|
93
|
+
if (profile.type === "ccr" && !ccrRunning) {
|
|
94
|
+
status = "needs_attention";
|
|
95
|
+
statusText = "CCR Offline";
|
|
96
|
+
}
|
|
97
|
+
if (profile.type === "unknown" && !isMain) {
|
|
98
|
+
status = "unknown";
|
|
99
|
+
statusText = "Unknown";
|
|
100
|
+
}
|
|
101
|
+
tags.push(status === "ready" ? "Ready" : statusText);
|
|
102
|
+
if (profile.type === "api") {
|
|
103
|
+
tags.push(profile.model ? "Custom Model" : "Default Model");
|
|
104
|
+
}
|
|
105
|
+
else if (profile.type === "login") {
|
|
106
|
+
tags.push("Login Profile");
|
|
107
|
+
}
|
|
108
|
+
else if (profile.type === "ccr") {
|
|
109
|
+
tags.push(profile.meta?.ccrRoute ? "Preset Bound" : "Endpoint Bound");
|
|
110
|
+
}
|
|
111
|
+
else if (isMain) {
|
|
112
|
+
tags.push("Main Config");
|
|
113
|
+
}
|
|
114
|
+
return { status, statusText, tags };
|
|
115
|
+
}
|
|
116
|
+
async function toWebProfile(profile, isMain, ccrRunning, includeSettings = false) {
|
|
117
|
+
const tagState = tagsForProfile(profile, isMain, ccrRunning);
|
|
118
|
+
const settings = includeSettings ? await readSettings(profile.dir) : undefined;
|
|
119
|
+
return {
|
|
120
|
+
...profile,
|
|
121
|
+
type: isMain ? "main" : profile.type,
|
|
122
|
+
...tagState,
|
|
123
|
+
startCommand: isMain ? "claude" : `ccp start ${profile.name}`,
|
|
124
|
+
settings: publicSettings(settings)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async function getAllProfiles(includeSettings = false) {
|
|
128
|
+
const ccr = await getCcrStatus();
|
|
129
|
+
const profiles = [];
|
|
130
|
+
const mainDir = getMainClaudeDir();
|
|
131
|
+
if (existsSync(mainDir)) {
|
|
132
|
+
const main = await summarizeProfile("main", mainDir);
|
|
133
|
+
profiles.push(await toWebProfile(main, true, ccr.running, includeSettings));
|
|
134
|
+
}
|
|
135
|
+
for (const profile of await listProfiles()) {
|
|
136
|
+
profiles.push(await toWebProfile(profile, false, ccr.running, includeSettings));
|
|
137
|
+
}
|
|
138
|
+
return profiles;
|
|
139
|
+
}
|
|
140
|
+
function dashboardFromProfiles(profiles, ccr) {
|
|
141
|
+
const count = (type) => profiles.filter((profile) => profile.type === type).length;
|
|
142
|
+
return {
|
|
143
|
+
profiles: {
|
|
144
|
+
total: profiles.length,
|
|
145
|
+
main: count("main"),
|
|
146
|
+
api: count("api"),
|
|
147
|
+
login: count("login"),
|
|
148
|
+
ccr: count("ccr"),
|
|
149
|
+
needsAttention: profiles.filter((profile) => profile.status !== "ready").length
|
|
150
|
+
},
|
|
151
|
+
ccr: {
|
|
152
|
+
installed: ccr.installed,
|
|
153
|
+
running: ccr.running,
|
|
154
|
+
endpoint: ccr.endpoint,
|
|
155
|
+
uiUrl: `${ccr.endpoint.replace(/\/$/, "")}/ui/`,
|
|
156
|
+
apiKeyStatus: ccr.apiKeyStatus
|
|
157
|
+
},
|
|
158
|
+
activity: activity.slice(0, 8)
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
async function updateApiSettings(name, body) {
|
|
162
|
+
const config = await resolveConfigDir(name, { allowMain: false });
|
|
163
|
+
const settings = (await readSettings(config.dir)) ?? { theme: "dark" };
|
|
164
|
+
settings.env ??= {};
|
|
165
|
+
const baseUrl = String(body.baseUrl ?? "").trim();
|
|
166
|
+
const token = String(body.token ?? "");
|
|
167
|
+
const model = String(body.model ?? "").trim();
|
|
168
|
+
const opusModel = String(body.opusModel ?? "").trim();
|
|
169
|
+
const sonnetModel = String(body.sonnetModel ?? "").trim();
|
|
170
|
+
const haikuModel = String(body.haikuModel ?? "").trim();
|
|
171
|
+
const subagentModel = String(body.subagentModel ?? "").trim();
|
|
172
|
+
if (baseUrl)
|
|
173
|
+
settings.env.ANTHROPIC_BASE_URL = baseUrl;
|
|
174
|
+
if (token.trim())
|
|
175
|
+
settings.env.ANTHROPIC_AUTH_TOKEN = token.trim();
|
|
176
|
+
setOptionalEnv(settings, "ANTHROPIC_MODEL", model);
|
|
177
|
+
setOptionalEnv(settings, "ANTHROPIC_DEFAULT_OPUS_MODEL", opusModel || model);
|
|
178
|
+
setOptionalEnv(settings, "ANTHROPIC_DEFAULT_SONNET_MODEL", sonnetModel || model);
|
|
179
|
+
setOptionalEnv(settings, "ANTHROPIC_DEFAULT_HAIKU_MODEL", haikuModel || model);
|
|
180
|
+
setOptionalEnv(settings, "CLAUDE_CODE_SUBAGENT_MODEL", subagentModel);
|
|
181
|
+
await writeSettings(config.dir, settings);
|
|
182
|
+
const summarized = await summarizeProfile(name, config.dir);
|
|
183
|
+
const ccr = await getCcrStatus();
|
|
184
|
+
addActivity("success", `Updated profile '${name}'.`);
|
|
185
|
+
return toWebProfile(summarized, false, ccr.running, true);
|
|
186
|
+
}
|
|
187
|
+
function setOptionalEnv(settings, key, value) {
|
|
188
|
+
settings.env ??= {};
|
|
189
|
+
if (value)
|
|
190
|
+
settings.env[key] = value;
|
|
191
|
+
else
|
|
192
|
+
delete settings.env[key];
|
|
193
|
+
}
|
|
194
|
+
async function updateCcrBinding(name, body) {
|
|
195
|
+
const config = await resolveConfigDir(name, { allowMain: false });
|
|
196
|
+
const route = String(body.route ?? "").trim();
|
|
197
|
+
if (!route)
|
|
198
|
+
throw new CcpError("CCR route is required.");
|
|
199
|
+
const meta = (await readMeta(config.dir));
|
|
200
|
+
if (!meta || meta.type !== "ccr")
|
|
201
|
+
throw new CcpError(`Profile '${name}' is not a CCR profile.`);
|
|
202
|
+
const preset = String(body.preset ?? meta.ccrPreset ?? name).trim() || name;
|
|
203
|
+
meta.ccrRoute = route;
|
|
204
|
+
meta.ccrPreset = preset;
|
|
205
|
+
await writeMeta(config.dir, meta);
|
|
206
|
+
await ensureCcrPreset(preset, route);
|
|
207
|
+
const summarized = await summarizeProfile(name, config.dir);
|
|
208
|
+
const ccr = await getCcrStatus();
|
|
209
|
+
addActivity("success", `Updated CCR route for '${name}'.`);
|
|
210
|
+
return toWebProfile(summarized, false, ccr.running, true);
|
|
211
|
+
}
|
|
212
|
+
function assetRoot() {
|
|
213
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
214
|
+
const distAssets = path.join(here, "assets");
|
|
215
|
+
if (existsSync(distAssets))
|
|
216
|
+
return distAssets;
|
|
217
|
+
return path.resolve(here, "../../src/web/assets");
|
|
218
|
+
}
|
|
219
|
+
function contentType(filePath) {
|
|
220
|
+
if (filePath.endsWith(".html"))
|
|
221
|
+
return "text/html; charset=utf-8";
|
|
222
|
+
if (filePath.endsWith(".css"))
|
|
223
|
+
return "text/css; charset=utf-8";
|
|
224
|
+
if (filePath.endsWith(".js"))
|
|
225
|
+
return "text/javascript; charset=utf-8";
|
|
226
|
+
if (filePath.endsWith(".svg"))
|
|
227
|
+
return "image/svg+xml";
|
|
228
|
+
return "application/octet-stream";
|
|
229
|
+
}
|
|
230
|
+
async function serveStatic(res, pathname, token) {
|
|
231
|
+
const root = assetRoot();
|
|
232
|
+
const safePath = pathname === "/" ? "/index.html" : pathname;
|
|
233
|
+
const resolved = path.resolve(root, `.${safePath}`);
|
|
234
|
+
if (!resolved.startsWith(path.resolve(root)))
|
|
235
|
+
return notFound(res);
|
|
236
|
+
try {
|
|
237
|
+
let data = await readFile(resolved, "utf8");
|
|
238
|
+
if (resolved.endsWith("index.html")) {
|
|
239
|
+
data = data.replace("__CCP_UI_TOKEN__", token);
|
|
240
|
+
}
|
|
241
|
+
res.writeHead(200, { "content-type": contentType(resolved) });
|
|
242
|
+
res.end(data);
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
notFound(res);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function openBrowser(url) {
|
|
249
|
+
const command = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
250
|
+
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
251
|
+
const child = spawn(command, args, { detached: true, stdio: "ignore" });
|
|
252
|
+
child.unref();
|
|
253
|
+
}
|
|
254
|
+
function terminalCommandForProfile(name) {
|
|
255
|
+
return name.toLowerCase() === "main" ? "claude" : `ccp start ${name}`;
|
|
256
|
+
}
|
|
257
|
+
function spawnDetached(command, args, cwd) {
|
|
258
|
+
return new Promise((resolve, reject) => {
|
|
259
|
+
const child = spawn(command, args, { cwd, detached: true, stdio: "ignore" });
|
|
260
|
+
child.once("error", reject);
|
|
261
|
+
child.once("spawn", () => {
|
|
262
|
+
child.unref();
|
|
263
|
+
resolve();
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
async function spawnFirstAvailable(commands, cwd) {
|
|
268
|
+
let lastError;
|
|
269
|
+
for (const candidate of commands) {
|
|
270
|
+
try {
|
|
271
|
+
await spawnDetached(candidate.command, candidate.args, cwd);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
lastError = error;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const reason = lastError instanceof Error ? ` ${lastError.message}` : "";
|
|
279
|
+
throw new CcpError(`Failed to open terminal.${reason}`);
|
|
280
|
+
}
|
|
281
|
+
function ensureLocalhostActionAllowed(host) {
|
|
282
|
+
if (!["127.0.0.1", "localhost", "::1"].includes(host)) {
|
|
283
|
+
throw new CcpError("This local system action is only available when ccp ui is bound to localhost.");
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function shellQuote(value) {
|
|
287
|
+
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
288
|
+
}
|
|
289
|
+
async function openTerminal(commandLine, cwd) {
|
|
290
|
+
if (process.platform === "win32") {
|
|
291
|
+
await spawnDetached("cmd.exe", ["/d", "/c", "start", "", "/D", cwd, "cmd.exe", "/k", commandLine], cwd);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const commandInCwd = `cd ${shellQuote(cwd)} && ${commandLine}`;
|
|
295
|
+
if (process.platform === "darwin") {
|
|
296
|
+
const script = `tell application "Terminal" to do script ${JSON.stringify(commandInCwd)}`;
|
|
297
|
+
await spawnDetached("osascript", ["-e", script], cwd);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
await spawnFirstAvailable([
|
|
301
|
+
{ command: "x-terminal-emulator", args: ["-e", "sh", "-lc", commandInCwd] },
|
|
302
|
+
{ command: "gnome-terminal", args: ["--", "sh", "-lc", commandInCwd] },
|
|
303
|
+
{ command: "konsole", args: ["-e", "sh", "-lc", commandInCwd] },
|
|
304
|
+
{ command: "xfce4-terminal", args: ["-e", `sh -lc ${JSON.stringify(commandInCwd)}`] },
|
|
305
|
+
{ command: "xterm", args: ["-e", "sh", "-lc", commandInCwd] }
|
|
306
|
+
], cwd);
|
|
307
|
+
}
|
|
308
|
+
async function revealPathInFileManager(filePath) {
|
|
309
|
+
if (process.platform === "win32") {
|
|
310
|
+
await spawnDetached("explorer.exe", [`/select,${filePath}`]);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (process.platform === "darwin") {
|
|
314
|
+
await spawnDetached("open", ["-R", filePath]);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
await spawnDetached("dbus-send", [
|
|
319
|
+
"--session",
|
|
320
|
+
"--dest=org.freedesktop.FileManager1",
|
|
321
|
+
"--type=method_call",
|
|
322
|
+
"/org/freedesktop/FileManager1",
|
|
323
|
+
"org.freedesktop.FileManager1.ShowItems",
|
|
324
|
+
`array:string:${pathToFileURL(filePath).href}`,
|
|
325
|
+
"string:"
|
|
326
|
+
]);
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
await spawnDetached("xdg-open", [path.dirname(filePath)]);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
async function revealProfileSettings(name, host) {
|
|
333
|
+
ensureLocalhostActionAllowed(host);
|
|
334
|
+
if (name.toLowerCase() !== "main")
|
|
335
|
+
assertProfileName(name);
|
|
336
|
+
const config = await resolveConfigDir(name, { allowMain: true });
|
|
337
|
+
const profile = await summarizeProfile(config.name, config.dir);
|
|
338
|
+
await revealPathInFileManager(profile.settingsPath);
|
|
339
|
+
addActivity("success", `Opened settings path for '${config.name}'.`);
|
|
340
|
+
return profile.settingsPath;
|
|
341
|
+
}
|
|
342
|
+
async function launchProfileTerminal(name, host) {
|
|
343
|
+
ensureLocalhostActionAllowed(host);
|
|
344
|
+
if (name.toLowerCase() !== "main")
|
|
345
|
+
assertProfileName(name);
|
|
346
|
+
const config = await resolveConfigDir(name, { allowMain: true });
|
|
347
|
+
const cwd = getHomeWorkDir();
|
|
348
|
+
await mkdir(cwd, { recursive: true });
|
|
349
|
+
const commandLine = terminalCommandForProfile(config.name);
|
|
350
|
+
await openTerminal(commandLine, cwd);
|
|
351
|
+
addActivity("success", `Opened terminal for '${config.name}'.`);
|
|
352
|
+
return commandLine;
|
|
353
|
+
}
|
|
354
|
+
async function handleApi(req, res, pathname, token, host) {
|
|
355
|
+
try {
|
|
356
|
+
if (req.method !== "GET")
|
|
357
|
+
requireToken(req, token);
|
|
358
|
+
if (pathname === "/api/presets") {
|
|
359
|
+
if (req.method !== "GET")
|
|
360
|
+
return methodNotAllowed(res);
|
|
361
|
+
return json(res, 200, { presets: listProfilePresets() });
|
|
362
|
+
}
|
|
363
|
+
if (pathname === "/api/profiles/preset") {
|
|
364
|
+
if (req.method !== "POST")
|
|
365
|
+
return methodNotAllowed(res);
|
|
366
|
+
const body = await readJsonBody(req);
|
|
367
|
+
const presetId = body.presetId ?? "";
|
|
368
|
+
let created;
|
|
369
|
+
if (body.kind === "ccr") {
|
|
370
|
+
created = await createCcrProfileFromPreset({ presetId, name: body.name, token: body.token });
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
created = await createApiProfileFromPreset({ presetId, name: body.name, token: body.token ?? "" });
|
|
374
|
+
}
|
|
375
|
+
addActivity("success", `Created profile '${created.name}' from preset '${presetId}'.`);
|
|
376
|
+
return json(res, 201, { profile: await toWebProfile(created, false, (await getCcrStatus()).running, true) });
|
|
377
|
+
}
|
|
378
|
+
if (pathname === "/api/dashboard") {
|
|
379
|
+
if (req.method !== "GET")
|
|
380
|
+
return methodNotAllowed(res);
|
|
381
|
+
const profiles = await getAllProfiles();
|
|
382
|
+
return json(res, 200, dashboardFromProfiles(profiles, await getCcrStatus()));
|
|
383
|
+
}
|
|
384
|
+
if (pathname === "/api/profiles") {
|
|
385
|
+
if (req.method !== "GET")
|
|
386
|
+
return methodNotAllowed(res);
|
|
387
|
+
return json(res, 200, { profiles: await getAllProfiles() });
|
|
388
|
+
}
|
|
389
|
+
if (pathname === "/api/activity") {
|
|
390
|
+
if (req.method !== "GET")
|
|
391
|
+
return methodNotAllowed(res);
|
|
392
|
+
return json(res, 200, { activity });
|
|
393
|
+
}
|
|
394
|
+
if (pathname === "/api/ccr/status") {
|
|
395
|
+
if (req.method !== "GET")
|
|
396
|
+
return methodNotAllowed(res);
|
|
397
|
+
const status = await getCcrStatus();
|
|
398
|
+
const profiles = await getAllProfiles();
|
|
399
|
+
return json(res, 200, { ...status, uiUrl: `${status.endpoint.replace(/\/$/, "")}/ui/`, profilesUsingCcr: profiles.filter((profile) => profile.type === "ccr").length });
|
|
400
|
+
}
|
|
401
|
+
if (pathname === "/api/ccr/routes") {
|
|
402
|
+
if (req.method !== "GET")
|
|
403
|
+
return methodNotAllowed(res);
|
|
404
|
+
return json(res, 200, { routes: getCcrRouteChoices(await readCcrConfig()) });
|
|
405
|
+
}
|
|
406
|
+
if (pathname === "/api/ccr/start") {
|
|
407
|
+
if (req.method !== "POST")
|
|
408
|
+
return methodNotAllowed(res);
|
|
409
|
+
await startCcrService();
|
|
410
|
+
addActivity("success", "CCR start command sent.");
|
|
411
|
+
return json(res, 200, { status: await getCcrStatus() });
|
|
412
|
+
}
|
|
413
|
+
if (pathname === "/api/ccr/restart") {
|
|
414
|
+
if (req.method !== "POST")
|
|
415
|
+
return methodNotAllowed(res);
|
|
416
|
+
await restartCcrService();
|
|
417
|
+
addActivity("success", "CCR restart command sent.");
|
|
418
|
+
return json(res, 200, { status: await getCcrStatus() });
|
|
419
|
+
}
|
|
420
|
+
if (pathname === "/api/ccr/stop") {
|
|
421
|
+
if (req.method !== "POST")
|
|
422
|
+
return methodNotAllowed(res);
|
|
423
|
+
await stopCcrService();
|
|
424
|
+
addActivity("success", "CCR stop command sent.");
|
|
425
|
+
return json(res, 200, { status: await getCcrStatus() });
|
|
426
|
+
}
|
|
427
|
+
if (pathname === "/api/profiles/api" && req.method === "POST") {
|
|
428
|
+
const body = await readJsonBody(req);
|
|
429
|
+
const created = await createApiProfile({ name: body.name ?? "", baseUrl: body.baseUrl ?? "", token: body.token ?? "", model: body.model ?? "" });
|
|
430
|
+
addActivity("success", `Created API profile '${created.name}'.`);
|
|
431
|
+
return json(res, 201, { profile: await toWebProfile(created, false, (await getCcrStatus()).running, true) });
|
|
432
|
+
}
|
|
433
|
+
if (pathname === "/api/profiles/login" && req.method === "POST") {
|
|
434
|
+
const body = await readJsonBody(req);
|
|
435
|
+
const created = await createLoginProfile({ name: body.name ?? "" });
|
|
436
|
+
addActivity("success", `Created login profile '${created.name}'.`);
|
|
437
|
+
return json(res, 201, { profile: await toWebProfile(created, false, (await getCcrStatus()).running, true) });
|
|
438
|
+
}
|
|
439
|
+
if (pathname === "/api/profiles/ccr" && req.method === "POST") {
|
|
440
|
+
const body = await readJsonBody(req);
|
|
441
|
+
const created = await createCcrProfile({ name: body.name ?? "", presetName: body.presetName, route: body.route ?? "", token: body.token ?? "" });
|
|
442
|
+
addActivity("success", `Created CCR profile '${created.name}'.`);
|
|
443
|
+
return json(res, 201, { profile: await toWebProfile(created, false, (await getCcrStatus()).running, true) });
|
|
444
|
+
}
|
|
445
|
+
const revealSettingsMatch = pathname.match(/^\/api\/profiles\/([^/]+)\/reveal-settings$/);
|
|
446
|
+
if (revealSettingsMatch) {
|
|
447
|
+
if (req.method !== "POST")
|
|
448
|
+
return methodNotAllowed(res);
|
|
449
|
+
const name = decodeURIComponent(revealSettingsMatch[1]);
|
|
450
|
+
const settingsPath = await revealProfileSettings(name, host);
|
|
451
|
+
return json(res, 200, { path: settingsPath });
|
|
452
|
+
}
|
|
453
|
+
const terminalMatch = pathname.match(/^\/api\/profiles\/([^/]+)\/terminal$/);
|
|
454
|
+
if (terminalMatch) {
|
|
455
|
+
if (req.method !== "POST")
|
|
456
|
+
return methodNotAllowed(res);
|
|
457
|
+
const name = decodeURIComponent(terminalMatch[1]);
|
|
458
|
+
const command = await launchProfileTerminal(name, host);
|
|
459
|
+
return json(res, 200, { command });
|
|
460
|
+
}
|
|
461
|
+
const profileMatch = pathname.match(/^\/api\/profiles\/([^/]+)$/);
|
|
462
|
+
if (profileMatch) {
|
|
463
|
+
const name = decodeURIComponent(profileMatch[1]);
|
|
464
|
+
if (req.method === "GET") {
|
|
465
|
+
const config = await resolveConfigDir(name, { allowMain: true });
|
|
466
|
+
const profile = await summarizeProfile(config.name, config.dir);
|
|
467
|
+
return json(res, 200, { profile: await toWebProfile(profile, config.isMain, (await getCcrStatus()).running, true) });
|
|
468
|
+
}
|
|
469
|
+
if (req.method === "PUT") {
|
|
470
|
+
const body = await readJsonBody(req);
|
|
471
|
+
const kind = String(body.kind ?? "api");
|
|
472
|
+
const profile = kind === "ccr" ? await updateCcrBinding(name, body) : await updateApiSettings(name, body);
|
|
473
|
+
return json(res, 200, { profile });
|
|
474
|
+
}
|
|
475
|
+
if (req.method === "DELETE") {
|
|
476
|
+
const body = await readJsonBody(req);
|
|
477
|
+
if (body.confirmName !== name)
|
|
478
|
+
throw new CcpError("Profile name confirmation does not match.");
|
|
479
|
+
const removed = await removeProfile(name);
|
|
480
|
+
addActivity("success", `Deleted profile '${name}' at ${removed}.`);
|
|
481
|
+
return json(res, 200, { removed });
|
|
482
|
+
}
|
|
483
|
+
return methodNotAllowed(res);
|
|
484
|
+
}
|
|
485
|
+
notFound(res);
|
|
486
|
+
}
|
|
487
|
+
catch (error) {
|
|
488
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
489
|
+
addActivity("error", message);
|
|
490
|
+
json(res, error instanceof CcpError ? 400 : 500, { error: redact(message) });
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
export async function startUiServer(options = {}) {
|
|
494
|
+
const host = options.host ?? DEFAULT_HOST;
|
|
495
|
+
const port = options.port ?? DEFAULT_PORT;
|
|
496
|
+
const token = randomBytes(24).toString("hex");
|
|
497
|
+
const server = createServer(async (req, res) => {
|
|
498
|
+
const url = new URL(req.url ?? "/", `http://${host}:${port}`);
|
|
499
|
+
if (url.pathname.startsWith("/api/")) {
|
|
500
|
+
await handleApi(req, res, url.pathname, token, host);
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
await serveStatic(res, url.pathname, token);
|
|
504
|
+
});
|
|
505
|
+
const url = `http://${host}:${port}/`;
|
|
506
|
+
try {
|
|
507
|
+
await new Promise((resolve, reject) => {
|
|
508
|
+
server.once("error", reject);
|
|
509
|
+
server.listen(port, host, () => resolve());
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
catch (error) {
|
|
513
|
+
server.close();
|
|
514
|
+
if (error instanceof Error && error.code === "EADDRINUSE") {
|
|
515
|
+
console.log(`ccp ui is already running at ${url}`);
|
|
516
|
+
if (options.open !== false)
|
|
517
|
+
openBrowser(url);
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
throw error;
|
|
521
|
+
}
|
|
522
|
+
addActivity("info", `UI started at ${url}`);
|
|
523
|
+
console.log(`ccp ui running at ${url}`);
|
|
524
|
+
console.log("Press Ctrl+C to stop.");
|
|
525
|
+
if (host !== DEFAULT_HOST) {
|
|
526
|
+
console.log("Warning: ccp ui is not bound to 127.0.0.1. Use only on trusted networks.");
|
|
527
|
+
}
|
|
528
|
+
if (options.open)
|
|
529
|
+
openBrowser(url);
|
|
530
|
+
}
|
|
531
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "multi-ccp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Cross-platform Claude Code profile manager for API, login, and router workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"CHANGELOG.md"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "tsc -p tsconfig.json",
|
|
17
|
+
"build": "tsc -p tsconfig.json && node scripts/copy-web-assets.mjs",
|
|
18
18
|
"dev": "tsx src/cli/index.ts",
|
|
19
19
|
"test": "vitest run",
|
|
20
20
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|