claudeck 1.0.2 → 1.0.3
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 +5 -2
- package/cli.js +66 -1
- package/package.json +1 -1
- package/server.js +15 -1
package/README.md
CHANGED
|
@@ -24,16 +24,19 @@
|
|
|
24
24
|
# One-command launch (no install needed)
|
|
25
25
|
npx claudeck
|
|
26
26
|
|
|
27
|
+
# Custom port
|
|
28
|
+
npx claudeck --port 3000
|
|
29
|
+
|
|
27
30
|
# Or install globally
|
|
28
31
|
npm install -g claudeck
|
|
29
32
|
claudeck
|
|
30
33
|
```
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
On first run, Claudeck will ask you to choose a port (default: `9009`), then open your browser to the URL shown in the terminal. The port is saved to `~/.claudeck/.env` for future runs.
|
|
33
36
|
|
|
34
37
|
> Requires **Node.js 18+** and Claude Code CLI authentication (`claude auth login`).
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
User data lives in `~/.claudeck/` (config, database, plugins) — safe for NPX upgrades.
|
|
37
40
|
|
|
38
41
|
---
|
|
39
42
|
|
package/cli.js
CHANGED
|
@@ -1,2 +1,67 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
5
|
+
import { createInterface } from "readline";
|
|
6
|
+
|
|
7
|
+
const DEFAULT_PORT = 9009;
|
|
8
|
+
const envDir = process.env.CLAUDECK_HOME || join(homedir(), ".claudeck");
|
|
9
|
+
const envPath = join(envDir, ".env");
|
|
10
|
+
mkdirSync(envDir, { recursive: true });
|
|
11
|
+
|
|
12
|
+
function readEnv() {
|
|
13
|
+
try { return readFileSync(envPath, "utf-8"); } catch { return ""; }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function savePort(port) {
|
|
17
|
+
let content = readEnv();
|
|
18
|
+
if (/^PORT=.*/m.test(content)) {
|
|
19
|
+
content = content.replace(/^PORT=.*/m, `PORT=${port}`);
|
|
20
|
+
} else {
|
|
21
|
+
content = content.trimEnd() + `\nPORT=${port}\n`;
|
|
22
|
+
}
|
|
23
|
+
writeFileSync(envPath, content);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getSavedPort() {
|
|
27
|
+
const match = readEnv().match(/^PORT=(\d+)/m);
|
|
28
|
+
return match ? match[1] : null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function ask(question) {
|
|
32
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
33
|
+
return new Promise(resolve => {
|
|
34
|
+
rl.question(question, answer => { rl.close(); resolve(answer.trim()); });
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function main() {
|
|
39
|
+
// --port flag takes priority
|
|
40
|
+
const portArg = process.argv.find(a => a.startsWith('--port'));
|
|
41
|
+
if (portArg) {
|
|
42
|
+
const port = portArg.includes('=') ? portArg.split('=')[1] : process.argv[process.argv.indexOf(portArg) + 1];
|
|
43
|
+
if (port) {
|
|
44
|
+
process.env.PORT = port;
|
|
45
|
+
savePort(port);
|
|
46
|
+
return import("./server.js");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// If port already saved, use it
|
|
51
|
+
const saved = getSavedPort();
|
|
52
|
+
if (saved) {
|
|
53
|
+
process.env.PORT = saved;
|
|
54
|
+
return import("./server.js");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// First run — ask user
|
|
58
|
+
console.log(`\n\x1b[36m Claudeck\x1b[0m — first-time setup\n`);
|
|
59
|
+
const answer = await ask(` Which port would you like to use? \x1b[2m(default: ${DEFAULT_PORT})\x1b[0m `);
|
|
60
|
+
const port = answer && /^\d+$/.test(answer) ? answer : String(DEFAULT_PORT);
|
|
61
|
+
process.env.PORT = port;
|
|
62
|
+
savePort(port);
|
|
63
|
+
console.log(`\x1b[2m Saved to ~/.claudeck/.env\x1b[0m\n`);
|
|
64
|
+
return import("./server.js");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudeck",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A browser-based UI for Claude Code — chat, run workflows, manage MCP servers, track costs, and orchestrate autonomous agents from a local web interface. Installable as a PWA.",
|
|
6
6
|
"main": "server.js",
|
package/server.js
CHANGED
|
@@ -164,7 +164,21 @@ const PORT = process.env.PORT || 9009;
|
|
|
164
164
|
// Mount full-stack plugin routes, then start server
|
|
165
165
|
mountPluginRoutes(app, fullStackPluginsDir).then(() => {
|
|
166
166
|
server.listen(PORT, () => {
|
|
167
|
-
|
|
167
|
+
const url = `http://localhost:${PORT}`;
|
|
168
|
+
console.log(`
|
|
169
|
+
\x1b[36m _____ _ _ _
|
|
170
|
+
/ ____| | | | | |
|
|
171
|
+
| | | | __ _ _ _ __| | ___ ___| | __
|
|
172
|
+
| | | |/ _\` | | | |/ _\` |/ _ \\/ __| |/ /
|
|
173
|
+
| |____| | (_| | |_| | (_| | __/ (__| <
|
|
174
|
+
\\_____|_|\\__,_|\\__,_|\\__,_|\\___|\\___|_|\\_\\\x1b[0m
|
|
175
|
+
|
|
176
|
+
\x1b[2m Browser UI for Claude Code\x1b[0m
|
|
177
|
+
|
|
178
|
+
\x1b[1m\x1b[32m➜\x1b[0m \x1b[1mReady:\x1b[0m ${url}
|
|
179
|
+
\x1b[2m➜ Port:\x1b[0m ${PORT}
|
|
180
|
+
\x1b[2m➜ Data:\x1b[0m ~/.claudeck/
|
|
181
|
+
`);
|
|
168
182
|
});
|
|
169
183
|
});
|
|
170
184
|
|