claude-home 1.8.0 → 1.8.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 +28 -18
- package/bin/cli.js +31 -24
- package/package.json +22 -3
- package/public/index.html +971 -281
- package/server.js +344 -44
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ Direct links (`#/note/filename`) let you open a specific note instantly.
|
|
|
53
53
|
Visual overview of all your Claude projects with session count, token usage, cost, and memory files. Drill into any project to browse its sessions, memory entries, and `CLAUDE.md` files.
|
|
54
54
|
|
|
55
55
|
### Plans
|
|
56
|
-
Read and search your GSD/planning files from `~/.claude/plans
|
|
56
|
+
Read and search your GSD/planning files from `~/.claude/plans/` (or your configured config dir). Export or publish as a Gist with one click.
|
|
57
57
|
|
|
58
58
|
### Memory
|
|
59
59
|
Inspect your auto-memory entries across all projects.
|
|
@@ -68,7 +68,7 @@ Read and edit your `CLAUDE.md` files (global and per-project). Inspect permissio
|
|
|
68
68
|
|
|
69
69
|
## No tokens. No cloud. No tracking.
|
|
70
70
|
|
|
71
|
-
claude-home is a local Express server that reads your `~/.claude/`
|
|
71
|
+
claude-home is a local Express server that reads your Claude config directory (`~/.claude/` by default) directly. It never calls the Claude API, never sends data anywhere, and works completely offline (except for the marketplace and Gist sharing features).
|
|
72
72
|
|
|
73
73
|
---
|
|
74
74
|
|
|
@@ -86,15 +86,6 @@ npm install -g claude-home
|
|
|
86
86
|
|
|
87
87
|
> Requires Node.js 18+.
|
|
88
88
|
|
|
89
|
-
### From source
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
git clone https://github.com/ZenekeZene/claude-home
|
|
93
|
-
cd claude-home
|
|
94
|
-
npm install
|
|
95
|
-
npm start
|
|
96
|
-
```
|
|
97
|
-
|
|
98
89
|
---
|
|
99
90
|
|
|
100
91
|
## Usage
|
|
@@ -123,10 +114,12 @@ Or toggle it directly from the **Hooks** section in the UI.
|
|
|
123
114
|
```
|
|
124
115
|
claude-home [options]
|
|
125
116
|
|
|
126
|
-
--port, -p <n>
|
|
127
|
-
--no-open
|
|
128
|
-
--
|
|
129
|
-
|
|
117
|
+
--port, -p <n> Port to use (default: 3141)
|
|
118
|
+
--no-open Don't open the browser automatically
|
|
119
|
+
--config-dir <path> Claude config directory (default: ~/.claude)
|
|
120
|
+
Also: CLAUDE_CONFIG_DIR env var
|
|
121
|
+
--version, -v Print version
|
|
122
|
+
--help, -h Show help
|
|
130
123
|
|
|
131
124
|
Commands:
|
|
132
125
|
setup-hook Add SessionStart hook + /claude-home slash command
|
|
@@ -134,11 +127,28 @@ Commands:
|
|
|
134
127
|
stop Stop the running claude-home server
|
|
135
128
|
```
|
|
136
129
|
|
|
130
|
+
### Multiple Claude installations
|
|
131
|
+
|
|
132
|
+
If you use separate Claude Code configurations (e.g. `~/.claude` for personal and `~/.claude-work` for work), you can point claude-home at any of them:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# Via flag
|
|
136
|
+
claude-home --config-dir ~/.claude-work
|
|
137
|
+
|
|
138
|
+
# Via environment variable
|
|
139
|
+
CLAUDE_CONFIG_DIR=~/.claude-work claude-home
|
|
140
|
+
|
|
141
|
+
# Install the auto-start hook into the work config
|
|
142
|
+
claude-home --config-dir ~/.claude-work setup-hook
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The dashboard will read sessions, settings, skills, commands, agents, and plans from the specified directory. The UI will reflect the correct paths throughout.
|
|
146
|
+
|
|
137
147
|
---
|
|
138
148
|
|
|
139
149
|
## Claude integration (Notes & Today)
|
|
140
150
|
|
|
141
|
-
claude-home can receive content directly from Claude during active sessions. Go to **Config → Integrations** and click **Set up** — this adds instructions to your
|
|
151
|
+
claude-home can receive content directly from Claude during active sessions. Go to **Config → Integrations** and click **Set up** — this adds instructions to your `CLAUDE.md` and grants the necessary write permissions automatically.
|
|
142
152
|
|
|
143
153
|
Once set up, from any Claude session you can say:
|
|
144
154
|
- *"Save this as a note"* → creates a note in the Notes view
|
|
@@ -157,7 +167,7 @@ Publish sessions or plans as public GitHub Gists. Go to **Config → Sharing**,
|
|
|
157
167
|
|
|
158
168
|
claude-home includes a marketplace to discover and install skills from GitHub repositories.
|
|
159
169
|
|
|
160
|
-
On first run it comes pre-configured with the [Anthropic Official skills repo](https://github.com/anthropics/skills). You can add your own sources (including private repos) by editing `~/.claude/claude-home/marketplace.json
|
|
170
|
+
On first run it comes pre-configured with the [Anthropic Official skills repo](https://github.com/anthropics/skills). You can add your own sources (including private repos) by editing `~/.claude/claude-home/marketplace.json` (or the equivalent in your configured config dir):
|
|
161
171
|
|
|
162
172
|
```json
|
|
163
173
|
{
|
|
@@ -175,7 +185,7 @@ On first run it comes pre-configured with the [Anthropic Official skills repo](h
|
|
|
175
185
|
}
|
|
176
186
|
```
|
|
177
187
|
|
|
178
|
-
For private repos, set your token in `~/.claude/claude-home/.env
|
|
188
|
+
For private repos, set your token in `~/.claude/claude-home/.env` (or your config dir equivalent):
|
|
179
189
|
|
|
180
190
|
```
|
|
181
191
|
GITHUB_TOKEN=ghp_your_token_here
|
package/bin/cli.js
CHANGED
|
@@ -9,18 +9,7 @@ const os = require('os');
|
|
|
9
9
|
|
|
10
10
|
const pkg = require('../package.json');
|
|
11
11
|
|
|
12
|
-
// ───
|
|
13
|
-
const DATA_DIR = path.join(os.homedir(), '.claude', 'claude-home');
|
|
14
|
-
try {
|
|
15
|
-
if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
16
|
-
const marketplaceDest = path.join(DATA_DIR, 'marketplace.json');
|
|
17
|
-
if (!fs.existsSync(marketplaceDest)) {
|
|
18
|
-
const defaultSrc = path.join(__dirname, '..', 'marketplace.default.json');
|
|
19
|
-
if (fs.existsSync(defaultSrc)) fs.copyFileSync(defaultSrc, marketplaceDest);
|
|
20
|
-
}
|
|
21
|
-
} catch { /* ignore */ }
|
|
22
|
-
|
|
23
|
-
// ─── Arg parsing ─────────────────────────────────────────────────────────────
|
|
12
|
+
// ─── Arg parsing (must happen before path derivation) ────────────────────────
|
|
24
13
|
|
|
25
14
|
const args = process.argv.slice(2);
|
|
26
15
|
const subcommand = args[0];
|
|
@@ -31,9 +20,25 @@ function getFlag(name, def) {
|
|
|
31
20
|
return args[idx + 1];
|
|
32
21
|
}
|
|
33
22
|
|
|
23
|
+
const configDirFlag = getFlag('--config-dir', '');
|
|
24
|
+
if (configDirFlag) process.env.CLAUDE_CONFIG_DIR = path.resolve(configDirFlag);
|
|
25
|
+
|
|
34
26
|
const port = parseInt(getFlag('--port', getFlag('-p', process.env.PORT || 3141)), 10);
|
|
35
27
|
const noOpen = args.includes('--no-open');
|
|
36
28
|
|
|
29
|
+
// ─── Config directory + data dir ─────────────────────────────────────────────
|
|
30
|
+
const CLAUDE_DIR = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
|
|
31
|
+
const DATA_DIR = path.join(CLAUDE_DIR, 'claude-home');
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
if (!fs.existsSync(DATA_DIR)) fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
35
|
+
const marketplaceDest = path.join(DATA_DIR, 'marketplace.json');
|
|
36
|
+
if (!fs.existsSync(marketplaceDest)) {
|
|
37
|
+
const defaultSrc = path.join(__dirname, '..', 'marketplace.default.json');
|
|
38
|
+
if (fs.existsSync(defaultSrc)) fs.copyFileSync(defaultSrc, marketplaceDest);
|
|
39
|
+
}
|
|
40
|
+
} catch { /* ignore */ }
|
|
41
|
+
|
|
37
42
|
if (args.includes('--version') || args.includes('-v')) {
|
|
38
43
|
console.log(pkg.version);
|
|
39
44
|
process.exit(0);
|
|
@@ -48,10 +53,12 @@ if (args.includes('--help') || args.includes('-h')) {
|
|
|
48
53
|
claude-home setup-hook
|
|
49
54
|
|
|
50
55
|
Options:
|
|
51
|
-
--port, -p <n>
|
|
52
|
-
--no-open
|
|
53
|
-
--
|
|
54
|
-
|
|
56
|
+
--port, -p <n> Port to use (default: 3141)
|
|
57
|
+
--no-open Don't open the browser automatically
|
|
58
|
+
--config-dir <path> Claude config directory (default: ~/.claude)
|
|
59
|
+
Also: CLAUDE_CONFIG_DIR env var
|
|
60
|
+
--version, -v Print version
|
|
61
|
+
--help, -h Show help
|
|
55
62
|
|
|
56
63
|
Commands:
|
|
57
64
|
setup-hook Add SessionStart hook and /claude-home slash command
|
|
@@ -102,7 +109,7 @@ promptSetupHookIfNeeded().then(() => {
|
|
|
102
109
|
// ─── Update check ────────────────────────────────────────────────────────────
|
|
103
110
|
|
|
104
111
|
function checkForUpdates() {
|
|
105
|
-
const cacheFile = path.join(
|
|
112
|
+
const cacheFile = path.join(DATA_DIR, '.update-check');
|
|
106
113
|
const TTL = 24 * 60 * 60 * 1000; // 24h
|
|
107
114
|
|
|
108
115
|
try {
|
|
@@ -149,8 +156,8 @@ function isPortFree(p) {
|
|
|
149
156
|
}
|
|
150
157
|
|
|
151
158
|
function promptSetupHookIfNeeded() {
|
|
152
|
-
const settingsPath = path.join(
|
|
153
|
-
const sentinelPath = path.join(
|
|
159
|
+
const settingsPath = path.join(CLAUDE_DIR, 'settings.json');
|
|
160
|
+
const sentinelPath = path.join(DATA_DIR, '.hook-prompted');
|
|
154
161
|
|
|
155
162
|
// Already prompted before, or hook already set up
|
|
156
163
|
if (fs.existsSync(sentinelPath)) return Promise.resolve();
|
|
@@ -186,8 +193,8 @@ function openBrowser(url) {
|
|
|
186
193
|
}
|
|
187
194
|
|
|
188
195
|
function setupHook() {
|
|
189
|
-
const settingsPath = path.join(
|
|
190
|
-
const commandsDir = path.join(
|
|
196
|
+
const settingsPath = path.join(CLAUDE_DIR, 'settings.json');
|
|
197
|
+
const commandsDir = path.join(CLAUDE_DIR, 'commands');
|
|
191
198
|
const commandPath = path.join(commandsDir, 'claude-home.md');
|
|
192
199
|
const hookCommand = `lsof -ti:${port} >/dev/null 2>&1 || (claude-home --no-open &>/dev/null &)`;
|
|
193
200
|
|
|
@@ -235,9 +242,9 @@ function setupHook() {
|
|
|
235
242
|
}
|
|
236
243
|
|
|
237
244
|
function removeHook() {
|
|
238
|
-
const settingsPath = path.join(
|
|
239
|
-
const commandPath = path.join(
|
|
240
|
-
const sentinelPath = path.join(
|
|
245
|
+
const settingsPath = path.join(CLAUDE_DIR, 'settings.json');
|
|
246
|
+
const commandPath = path.join(CLAUDE_DIR, 'commands', 'claude-home.md');
|
|
247
|
+
const sentinelPath = path.join(DATA_DIR, '.hook-prompted');
|
|
241
248
|
|
|
242
249
|
// Remove SessionStart hook
|
|
243
250
|
let removed = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-home",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.3",
|
|
4
4
|
"description": "Web dashboard for Claude Code — browse sessions, manage skills, hooks, commands, and agents",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,12 @@
|
|
|
14
14
|
"README.md"
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
|
-
"start": "node server.js"
|
|
17
|
+
"start": "node server.js",
|
|
18
|
+
"dev": "vite",
|
|
19
|
+
"build": "vite build",
|
|
20
|
+
"preview": "vite preview",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest"
|
|
18
23
|
},
|
|
19
24
|
"engines": {
|
|
20
25
|
"node": ">=18"
|
|
@@ -35,6 +40,20 @@
|
|
|
35
40
|
"author": "ZenekeZene",
|
|
36
41
|
"license": "MIT",
|
|
37
42
|
"dependencies": {
|
|
38
|
-
"
|
|
43
|
+
"@tanstack/react-query": "^5.96.2",
|
|
44
|
+
"express": "^4.18.2",
|
|
45
|
+
"highlight.js": "^11.11.1",
|
|
46
|
+
"marked": "^17.0.6",
|
|
47
|
+
"react": "^18.3.1",
|
|
48
|
+
"react-dom": "^18.3.1",
|
|
49
|
+
"react-router-dom": "^6.30.3"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
53
|
+
"@testing-library/react": "^16.3.2",
|
|
54
|
+
"@testing-library/user-event": "^14.6.1",
|
|
55
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
56
|
+
"jsdom": "^29.0.2",
|
|
57
|
+
"vitest": "^3.2.4"
|
|
39
58
|
}
|
|
40
59
|
}
|