clauder-hub 0.0.0-stage → 0.1.0

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.
Files changed (117) hide show
  1. package/LICENSE +27 -0
  2. package/README.md +310 -2
  3. package/bin/clauder-hub.mjs +61 -0
  4. package/logo.svg +1 -0
  5. package/package.json +54 -4
  6. package/server/dist/index.js +750 -0
  7. package/web/dist/assets/MonacoEditor-BbYsqB7V.css +1 -0
  8. package/web/dist/assets/MonacoEditor-Bdblyy-v.js +1007 -0
  9. package/web/dist/assets/abap-DLDM7-KI.js +1 -0
  10. package/web/dist/assets/apex-DNDY2TF8.js +1 -0
  11. package/web/dist/assets/azcli-Y6nb8tq_.js +1 -0
  12. package/web/dist/assets/babel-Dw5Eu3O9.js +16 -0
  13. package/web/dist/assets/bat-BwHxbl9M.js +1 -0
  14. package/web/dist/assets/bicep-CFznDFnq.js +2 -0
  15. package/web/dist/assets/cameligo-Bf6VGUru.js +1 -0
  16. package/web/dist/assets/clojure-Dnu-v4kV.js +1 -0
  17. package/web/dist/assets/codicon-DF1abBS2.ttf +0 -0
  18. package/web/dist/assets/coffee-Bd8akH9Z.js +1 -0
  19. package/web/dist/assets/cpp-BbWJElDN.js +1 -0
  20. package/web/dist/assets/csharp-Co3qMtFm.js +1 -0
  21. package/web/dist/assets/csp-D-4FJmMZ.js +1 -0
  22. package/web/dist/assets/css-DdJfP1eB.js +3 -0
  23. package/web/dist/assets/css.worker-CH7Os8C2.js +97 -0
  24. package/web/dist/assets/cssMode-DOakqY50.js +1 -0
  25. package/web/dist/assets/cypher-cTPe9QuQ.js +1 -0
  26. package/web/dist/assets/dart-BOtBlQCF.js +1 -0
  27. package/web/dist/assets/dockerfile-BG73LgW2.js +1 -0
  28. package/web/dist/assets/ecl-BEgZUVRK.js +1 -0
  29. package/web/dist/assets/editor.worker-BytiCuzy.js +30 -0
  30. package/web/dist/assets/elixir-BkW5O-1t.js +1 -0
  31. package/web/dist/assets/estree-DlGR-zBs.js +44 -0
  32. package/web/dist/assets/flow9-BeJ5waoc.js +1 -0
  33. package/web/dist/assets/freemarker2-WsMzPf-p.js +3 -0
  34. package/web/dist/assets/fsharp-PahG7c26.js +1 -0
  35. package/web/dist/assets/go-acbASCJo.js +1 -0
  36. package/web/dist/assets/graphql-BxJiqAUM.js +1 -0
  37. package/web/dist/assets/graphql-Houc-vhO.js +17 -0
  38. package/web/dist/assets/handlebars-CFf3afIj.js +1 -0
  39. package/web/dist/assets/hcl-DtV1sZF8.js +1 -0
  40. package/web/dist/assets/html-Cdlyoy-I.js +25 -0
  41. package/web/dist/assets/html-Duk6L3Ci.js +1 -0
  42. package/web/dist/assets/html.worker-DTgyLzoY.js +474 -0
  43. package/web/dist/assets/htmlMode-CuaMCYCU.js +1 -0
  44. package/web/dist/assets/index-CGbzqzmX.js +19 -0
  45. package/web/dist/assets/index-DI4uTQnz.css +32 -0
  46. package/web/dist/assets/index-DpS67tuQ.js +522 -0
  47. package/web/dist/assets/ini-Kd9XrMLS.js +1 -0
  48. package/web/dist/assets/java-CXBNlu9o.js +1 -0
  49. package/web/dist/assets/javascript-57wNn1QZ.js +1 -0
  50. package/web/dist/assets/json.worker-Dgwax7hT.js +62 -0
  51. package/web/dist/assets/jsonMode-DPgMOUkd.js +7 -0
  52. package/web/dist/assets/julia-cl7-CwDS.js +1 -0
  53. package/web/dist/assets/kotlin-s7OhZKlX.js +1 -0
  54. package/web/dist/assets/less-9HpZscsL.js +2 -0
  55. package/web/dist/assets/lexon-OrD6JF1K.js +1 -0
  56. package/web/dist/assets/liquid-DHlnUOel.js +1 -0
  57. package/web/dist/assets/lspLanguageFeatures-BIy_BVAi.js +4 -0
  58. package/web/dist/assets/lua-Cyyb5UIc.js +1 -0
  59. package/web/dist/assets/m3-B8OfTtLu.js +1 -0
  60. package/web/dist/assets/markdown-BFxVWTOG.js +1 -0
  61. package/web/dist/assets/markdown-Da4luf4E.js +70 -0
  62. package/web/dist/assets/mdx-SCDblWWe.js +1 -0
  63. package/web/dist/assets/mips-CiqrrVzr.js +1 -0
  64. package/web/dist/assets/msdax-DmeGPVcC.js +1 -0
  65. package/web/dist/assets/mysql-C_tMU-Nz.js +1 -0
  66. package/web/dist/assets/objective-c-BDtDVThU.js +1 -0
  67. package/web/dist/assets/pascal-vHIfCaH5.js +1 -0
  68. package/web/dist/assets/pascaligo-DtZ0uQbO.js +1 -0
  69. package/web/dist/assets/perl-Ub6l9XKa.js +1 -0
  70. package/web/dist/assets/pgsql-BlNEE0v7.js +1 -0
  71. package/web/dist/assets/php-BBUBE1dy.js +1 -0
  72. package/web/dist/assets/pla-DSh2-awV.js +1 -0
  73. package/web/dist/assets/postcss-2VMvKpSM.js +62 -0
  74. package/web/dist/assets/postiats-CocnycG-.js +1 -0
  75. package/web/dist/assets/powerquery-tScXyioY.js +1 -0
  76. package/web/dist/assets/powershell-COWaemsV.js +1 -0
  77. package/web/dist/assets/protobuf-Brw8urJB.js +2 -0
  78. package/web/dist/assets/pug-8SOpv6rk.js +1 -0
  79. package/web/dist/assets/python-DcjgL-6k.js +1 -0
  80. package/web/dist/assets/qsharp-Bw9ernYp.js +1 -0
  81. package/web/dist/assets/r-j7ic8hl3.js +1 -0
  82. package/web/dist/assets/razor-q_Zkc8t3.js +1 -0
  83. package/web/dist/assets/redis-Bu5POkcn.js +1 -0
  84. package/web/dist/assets/redshift-Bs9aos_-.js +1 -0
  85. package/web/dist/assets/restructuredtext-CqXO7rUv.js +1 -0
  86. package/web/dist/assets/ruby-zBfavPgS.js +1 -0
  87. package/web/dist/assets/rust-BzKRNQWT.js +1 -0
  88. package/web/dist/assets/sb-BBc9UKZt.js +1 -0
  89. package/web/dist/assets/scala-D9hQfWCl.js +1 -0
  90. package/web/dist/assets/scheme-BPhDTwHR.js +1 -0
  91. package/web/dist/assets/scss-CBJaRo0y.js +3 -0
  92. package/web/dist/assets/shell-DiJ1NA_G.js +1 -0
  93. package/web/dist/assets/solidity-Db0IVjzk.js +1 -0
  94. package/web/dist/assets/sophia-CnS9iZB_.js +1 -0
  95. package/web/dist/assets/sparql-CJmd_6j2.js +1 -0
  96. package/web/dist/assets/sql-ClhHkBeG.js +1 -0
  97. package/web/dist/assets/st-CHwy0fLd.js +1 -0
  98. package/web/dist/assets/standalone-fOeV0Vsa.js +29 -0
  99. package/web/dist/assets/swift-Bqt4WxQ4.js +3 -0
  100. package/web/dist/assets/systemverilog-Bs9z6M-B.js +1 -0
  101. package/web/dist/assets/tcl-Dm6ycUr_.js +1 -0
  102. package/web/dist/assets/ts.worker-CE_y865M.js +67735 -0
  103. package/web/dist/assets/tsMode-N3PGleJF.js +11 -0
  104. package/web/dist/assets/twig-Csy3S7wG.js +1 -0
  105. package/web/dist/assets/typescript-CpwMS6-X.js +22 -0
  106. package/web/dist/assets/typescript-UQxkBsMs.js +1 -0
  107. package/web/dist/assets/typespec-Btyra-wh.js +1 -0
  108. package/web/dist/assets/vb-Db0cS2oM.js +1 -0
  109. package/web/dist/assets/wgsl-BTesnYfV.js +298 -0
  110. package/web/dist/assets/workers-BVzxuZVI.js +1 -0
  111. package/web/dist/assets/xml-BDNQC6ch.js +1 -0
  112. package/web/dist/assets/yaml-CwaMJBxz.js +154 -0
  113. package/web/dist/assets/yaml-FyKAiCgl.js +1 -0
  114. package/web/dist/favicon.svg +1 -0
  115. package/web/dist/index.html +20 -0
  116. package/web/dist/logo-small.svg +1 -0
  117. package/web/dist/logo.svg +1 -0
package/LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ Clauder Hub License
2
+
3
+ Copyright (c) 2026 goldyndevs. All rights reserved.
4
+
5
+ Clauder Hub is free to use. You may install it from the npm registry and run
6
+ it on any number of your own machines, for personal or commercial work.
7
+
8
+ You may not, in whole or in part:
9
+
10
+ - copy, modify, merge, translate or create derivative works of it;
11
+ - redistribute, sublicense, sell, rent or publish it, or offer it as a hosted
12
+ service;
13
+ - decompile, reverse engineer or extract its source code, except where the law
14
+ explicitly permits it regardless of this restriction;
15
+ - remove or alter this license or any copyright notice.
16
+
17
+ All rights not expressly granted here are reserved by goldyndevs.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Contact: goldyndevs@gmail.com
package/README.md CHANGED
@@ -1,3 +1,311 @@
1
- # Temporary Holding Version
1
+ # Clauder Hub
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **A handy ADE (agentic development environment) for Claude Code: one local dashboard over every Claude Code session on your machine.**
4
+
5
+ Clauder Hub is a wrapper around Claude Code. It starts real `claude` processes
6
+ in real terminals, shows them in your browser, and adds what a single terminal
7
+ window cannot give you: every project's sessions in one place, an inbox of
8
+ everything Claude is waiting on, answers from your phone, scheduled and
9
+ webhook-triggered runs, and stats read straight from the transcripts.
10
+
11
+ Nothing is reimplemented and nothing is installed into Claude Code. The
12
+ terminal you see *is* the `claude` CLI you already use, with your login, your
13
+ settings and your plugins.
14
+
15
+ ---
16
+
17
+ ## Why
18
+
19
+ Claude Code is great in one terminal. It gets messy with five:
20
+
21
+ - 😵 **Too many windows.** Sessions in several repos, each in its own tab, and
22
+ no way to see at a glance which ones are working, done, or stuck.
23
+ - ⏳ **Silent waits.** A session asks for permission or asks a question, and
24
+ sits there for an hour because you were in another window (or away from
25
+ your desk).
26
+ - 🔁 **Repeated chores.** Nightly test runs, dependency checks, triage on an
27
+ incoming webhook: you either babysit them or script around the CLI yourself.
28
+ - 🧰 **Context bloat.** Every agent, skill, MCP server and plugin you ever
29
+ installed loads into every session, even when the task needs three of them.
30
+ - 📊 **No overview.** Where did the tokens go? Which tools, subagents and MCP
31
+ servers did a session actually use?
32
+
33
+ Clauder Hub keeps all of that in one browser tab, and lets you answer from
34
+ Slack or Telegram when you are not at the machine.
35
+
36
+ ---
37
+
38
+ ## Feature tour
39
+
40
+ ### 🖥️ Sessions and terminals
41
+
42
+ - Every session of a project, read from `~/.claude/projects/...`, including the
43
+ ones you started in a plain terminal.
44
+ - **New session** opens a plain `claude` straight in an embedded terminal
45
+ (xterm.js over a pty on the hub). Resume any past session the same way.
46
+ - Closing the browser only detaches: the process keeps running in the hub.
47
+ Pop a session out into a window of its own (`#/w/...`) if you like.
48
+ - Sessions started outside the hub are visible but have no hooks; resume one
49
+ in the hub to bring it in.
50
+
51
+ ### 🌐 The global page: many projects, one view
52
+
53
+ - One hub runs per machine and remembers every project you gave it.
54
+ - The global page (`#/global`) shows a card per project, **one inbox across all
55
+ of them**, and the global channels.
56
+ - Each project keeps its own database, queue, cron jobs, channels, presets and
57
+ categories, and they all keep running while you look at another project.
58
+
59
+ ### 📥 Inbox: everything Claude is waiting on
60
+
61
+ - Permission requests, `AskUserQuestion` questions, ends of turns, MCP
62
+ suggestions and finished tasks land in the inbox as cards with buttons.
63
+ - Answer from the dashboard or from any channel. **The first answer from
64
+ anywhere wins**, and the others are told who answered.
65
+ - An answer is delivered by *typing into the pty*, exactly as you would.
66
+ Hooks never approve, deny or delay anything on their own.
67
+
68
+ ### 💬 Channels: Telegram, Slack and webhooks
69
+
70
+ | Channel | How it connects | Two-way |
71
+ | --- | --- | --- |
72
+ | Telegram | Bot API, long polling (no public URL needed) | Yes, inline buttons and replies |
73
+ | Slack | Socket Mode (no public URL needed) | Yes, blocks, buttons and threads |
74
+ | Webhook | JSON, plain text, Discord or Teams (Adaptive Card) | JSON carries a `replyUrl`; chat formats are one-way |
75
+
76
+ **BotFather-style commands** (on Slack use `!` instead of `/`, since Slack keeps `/` for itself):
77
+
78
+ | Command | What it does |
79
+ | --- | --- |
80
+ | `/new <prompt>` | Start a session (alone, it asks for the prompt) |
81
+ | `/run <prompt>` | Queue an unattended run |
82
+ | `/sessions` | Pick a session; your plain messages then go to it |
83
+ | `/summary` | What a session did, read from its transcript (no tokens spent) |
84
+ | `/stop` | Stop a running session (asks first) |
85
+ | `/queue` | The run queue, with cancel buttons |
86
+ | `/cancel`, `/help` | Drop a pending question, or show the menu |
87
+
88
+ A **global bot** also has `/projects`, `/use <name>` and `/addproject`, and
89
+ relays every project's questions labelled with the project name.
90
+
91
+ **Natural-language fallbacks.** Misspell a command, describe a session instead
92
+ of naming it ("the one fixing the login bug"), or describe a folder for
93
+ `/addproject` ("my calendar app"), and the hub asks a small Claude model
94
+ (Haiku, no tools) for its best guesses. They come back as buttons; **nothing
95
+ runs until you press one**. Plain chat on Slack is never guessed at, since
96
+ people talk there.
97
+
98
+ ### ⏰ Automation: cron, webhooks and a queue per project
99
+
100
+ - **Cron jobs** and **webhook triggers** start unattended sessions.
101
+ - A webhook is `POST /api/trigger/<job id>` with the job's token in the
102
+ `x-clauder-token` header. `{{payload.field}}` in the job's prompt pulls a
103
+ value from the request body (`{{payload}}` is the whole body, `{{now}}` the time).
104
+ - Every run goes through **one queue per project**: runs in a project go one at
105
+ a time, different projects run side by side.
106
+ - **Task categories** define what "done" means for a kind of task (a PR, an RCA,
107
+ test evidence...). A session with a category is closed only when Claude
108
+ reports every required deliverable; if something is missing, the hub types
109
+ back what is missing.
110
+
111
+ ### 🧰 Toolsets and presets
112
+
113
+ - Turn agents, skills, MCP servers and plugins **off** for one session (its
114
+ Toolset tab), or save the choice as a **preset** for jobs and as the default
115
+ for new sessions.
116
+ - Applied only through that session's own `--settings` file. Changing a live
117
+ session restarts it on the same conversation.
118
+
119
+ ### 📊 Stats from the transcripts
120
+
121
+ - Tokens (input, output, cache) by model and by day.
122
+ - Tool calls grouped as built-in, MCP (by server), skills and subagents, plus
123
+ each subagent's own tokens and calls.
124
+ - All parsed from the JSONL transcripts Claude Code already writes. Nothing
125
+ extra is collected.
126
+
127
+ ### 📁 Files and editor
128
+
129
+ - A file tree in the sidebar (create, rename, move, delete) and a **Monaco**
130
+ editor with tabs.
131
+ - GitLens-style **blame** annotations from `git blame` (read-only, git is only
132
+ asked, never told).
133
+
134
+ ### 📝 Prompts, memory and inventory
135
+
136
+ - Every word the hub adds to a session or sends to a channel is a prompt you
137
+ can edit and restore (Hub prompts).
138
+ - `CLAUDE.md` files, rules, auto memory, agents, skills and commands can be
139
+ edited in place after reviewing a diff.
140
+ - Inventory of agents, skills, commands, MCP servers, hooks and plugins by
141
+ scope (user, project, local, plugin).
142
+ - **MCP suggestions:** when a session is blocked on a missing integration it
143
+ says so and stops. The `claude mcp add --scope project ...` command runs only
144
+ when you approve it, then the session resumes so the server loads.
145
+
146
+ ### 🤖 No forms: configuration is a conversation
147
+
148
+ Creating a cron job, a run, a category, a preset or a channel opens a Claude
149
+ session with that purpose. Claude asks what it needs, shows the final JSON,
150
+ and saves it through the hub API after you say yes.
151
+
152
+ ---
153
+
154
+ ## Use cases
155
+
156
+ **Approve a permission from your phone.** You step away while Claude refactors
157
+ a module. It hits a `Bash` permission prompt; the request arrives in Telegram
158
+ with buttons. Tap *Allow*, and the hub types the answer into the terminal.
159
+
160
+ **Reply late, safely.** You reply to a question an hour later by replying to
161
+ its Telegram message. If it was already answered, or the session has moved
162
+ on, the hub tells you so (and points at the newer question) instead of
163
+ applying your old "yes" to whatever dialog is showing now.
164
+
165
+ **Nightly jobs with a summary.** A cron job runs `npm test` and triages
166
+ failures every night at 2:00. Each run waits its turn in the project's queue,
167
+ and its end of turn (or its done report, if the job has a category) lands in
168
+ the inbox and your channels. In the morning, `/summary` shows what it did.
169
+
170
+ **Juggle five projects from one page.** Add each repo once. The global page
171
+ shows every project, a single inbox, and one global bot that tags each
172
+ message with its project. `/use api-server` then `/new fix the flaky test`
173
+ starts work there from chat.
174
+
175
+ **Add a project by describing it.** Tell the global bot `/addproject my
176
+ calendar app`. It looks through your usual code folders and offers matching
177
+ folders as buttons; press one and the project is in the hub.
178
+
179
+ **Trigger Claude from another system.** Point a GitHub, n8n or monitoring
180
+ webhook at `POST /api/trigger/<job id>`; the job's prompt picks fields out of
181
+ the payload with `{{payload.issue.title}}` and queues a run.
182
+
183
+ **Lean sessions for focused work.** Make a "frontend" preset that turns off the
184
+ database MCP servers and backend agents, and use it for UI jobs and new
185
+ sessions.
186
+
187
+ ---
188
+
189
+ ## Quick start
190
+
191
+ **Requirements**
192
+
193
+ - Node.js 22 or newer
194
+ - [Claude Code](https://docs.claude.com/en/docs/claude-code) installed and
195
+ logged in (`claude` on your PATH)
196
+
197
+ **Install and run**
198
+
199
+ ```bash
200
+ npx clauder-hub "/path/to/your/project"
201
+ # or keep it installed:
202
+ npm i -g clauder-hub
203
+ clauder-hub "/path/to/your/project" # 'clauder-hub .' for the current folder
204
+ ```
205
+
206
+ Open **http://localhost:4329**. The port moves up if it is taken (`--port <n>`
207
+ to pick one); the hub prints the one it chose. It remembers its projects, so
208
+ later runs can be just `clauder-hub`, and running it again with another path
209
+ while the hub is up adds that folder to the running hub. `clauder-hub --help`
210
+ lists the options.
211
+
212
+ ---
213
+
214
+ ## How it works
215
+
216
+ ```
217
+ Browser (React + xterm.js) Telegram / Slack / webhooks
218
+ | ^ | ^
219
+ REST + WebSocket | answers | | questions
220
+ v | v |
221
+ +-----------------------------------------------------------------------+
222
+ | Clauder Hub server (Express + ws, 127.0.0.1, one per machine) |
223
+ | |
224
+ | inbox / channels / queue + cron / stats / files / prompts |
225
+ +-----------------------------------------------------------------------+
226
+ | spawns in a pty, types answers ^ HTTP hooks (answered {} at once)
227
+ v |
228
+ +--------------------------+ writes +--------------------------+
229
+ | real `claude` process | -------------> | ~/.claude/projects/... |
230
+ | --settings (hooks) | | JSONL transcripts |
231
+ | --append-system-prompt | +--------------------------+
232
+ +--------------------------+ | read for stats
233
+ ```
234
+
235
+ | Need | How |
236
+ | --- | --- |
237
+ | Show the terminal | `claude` runs in a pty on the hub; the page attaches over a WebSocket |
238
+ | Know a session is waiting | HTTP hooks passed per process with `--settings` (SessionStart, UserPromptSubmit, PermissionRequest, PreToolUse for AskUserQuestion, Notification, Stop, SessionEnd). The hub answers each with `{}` immediately, so hooks never decide or delay anything |
239
+ | Answer from anywhere | The answer is typed into the pty, as a person would |
240
+ | Done reports, MCP suggestions | `--append-system-prompt-file`, read back from the last message by the Stop hook |
241
+ | Toolsets | Settings keys merged into the session's own `--settings` file |
242
+ | Stats | The JSONL transcripts Claude Code writes anyway |
243
+
244
+ **Data layout** (`CLAUDER_HUB_HOME` moves it):
245
+
246
+ ```
247
+ ~/.clauder-hub/
248
+ hub.db project list and hub prompts
249
+ hub.lock one hub per machine; a second start hands its folder over
250
+ global/ the global context (global channels, hub tasks)
251
+ projects/<id>/ hub.db per project: sessions, inbox, jobs, channels, presets
252
+ run/ per-terminal --settings files and appended system prompts
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Safety and privacy
258
+
259
+ - 🔒 **Local only.** The server listens on `127.0.0.1`, never on your network.
260
+ It runs a shell-capable agent, so keep it that way.
261
+ - 🧼 **Nothing installed into Claude Code.** No MCP server, skill, plugin or
262
+ settings file is written. Hooks and the extra prompt are passed per process
263
+ on the command line. The only exceptions are ones you ask for by name:
264
+ running a suggested `claude mcp add --scope project`, or saving an
265
+ instruction file after reviewing its diff.
266
+ - 🙅 **Hooks never decide.** Every hook is answered `{}` before the hub does
267
+ anything with it, so the hub cannot approve or block a tool call by itself.
268
+ - ✋ **Confirm before acting.** Stopping, deleting, running commands and
269
+ starting unattended runs ask first in the dashboard. Channel guesses are
270
+ buttons that do nothing until pressed.
271
+ - 📡 **What leaves the machine:** only what you configure. Channel messages go
272
+ to the Slack, Telegram or webhook you set up, and natural-language guesses
273
+ use your own Claude Code login (a small Haiku call).
274
+
275
+ ---
276
+
277
+ ## FAQ
278
+
279
+ **Does it replace Claude Code?**
280
+ No. It runs the `claude` you already have, in a real terminal. Everything you
281
+ can do in Claude Code you still do in that terminal.
282
+
283
+ **Do I need a server or a public URL for Telegram or Slack?**
284
+ No. Telegram uses long polling and Slack uses Socket Mode, both outgoing
285
+ connections from your machine.
286
+
287
+ **What happens to sessions when I close the browser?**
288
+ They keep running in the hub. Reopen the page and attach again.
289
+
290
+ **Can it see sessions I started in a normal terminal?**
291
+ Yes, they are listed with their stats. To answer them from the inbox or a
292
+ channel, resume them in the hub so they get its hooks.
293
+
294
+ **Does it cost extra tokens?**
295
+ Stats and `/summary` are read from transcripts and cost nothing. Only the
296
+ natural-language fallbacks in channels make a small Haiku call.
297
+
298
+ **Can two hubs run at once?**
299
+ One hub runs per machine. Starting another hands its project folder to the
300
+ running one.
301
+
302
+ **Where is my data?**
303
+ In `~/.clauder-hub` (or `CLAUDER_HUB_HOME`), plus the transcripts Claude Code
304
+ keeps in `~/.claude`.
305
+
306
+ ---
307
+
308
+ ## License
309
+
310
+ Free to use, not open source: see [LICENSE](LICENSE). © 2026 goldyndevs.
311
+ Questions and ideas: goldyndevs@gmail.com
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+
6
+ const here = path.dirname(fileURLToPath(import.meta.url));
7
+ const serverEntry = path.join(here, "..", "server", "dist", "index.js");
8
+
9
+ const args = process.argv.slice(2);
10
+
11
+ if (args.includes("-h") || args.includes("--help")) {
12
+ console.log(`
13
+ clauder-hub [project path] [--port <n>]
14
+
15
+ Opens the dashboard for the Claude Code sessions of your projects. One hub
16
+ runs per machine and keeps every project it was given: their sessions, cron
17
+ jobs and webhooks run as long as it does. A path adds that project and opens
18
+ it ('clauder-hub .' for the current folder); when a hub is already running,
19
+ the path is handed to it.
20
+
21
+ --port <n> Preferred port (default 4329). If it is taken, the next free
22
+ one is used.
23
+ version Print the version.
24
+
25
+ Examples:
26
+ npx clauder-hub "C:\\Source code\\your-repo"
27
+ cd your-repo && npx clauder-hub .
28
+ npx clauder-hub
29
+ `);
30
+ process.exit(0);
31
+ }
32
+
33
+ if (args[0] === "version") {
34
+ const pkg = JSON.parse(fs.readFileSync(path.join(here, "..", "package.json"), "utf8"));
35
+ console.log(pkg.version);
36
+ process.exit(0);
37
+ }
38
+
39
+ function flag(name) {
40
+ const index = args.indexOf(name);
41
+ return index === -1 ? undefined : args[index + 1];
42
+ }
43
+
44
+ const positional = args.find((arg, index) => !arg.startsWith("-") && args[index - 1] !== "--port");
45
+ const target = positional ? path.resolve(positional) : "";
46
+
47
+ if (target && (!fs.existsSync(target) || !fs.statSync(target).isDirectory())) {
48
+ console.error(`\n ${target} is not a folder.\n`);
49
+ process.exit(1);
50
+ }
51
+
52
+ if (!fs.existsSync(serverEntry)) {
53
+ console.error(`\n The hub has not been built yet.\n Run 'npm run build' in ${path.join(here, "..")}\n`);
54
+ process.exit(1);
55
+ }
56
+
57
+ const port = flag("--port");
58
+ if (port) process.env.PORT = port;
59
+ if (target) process.env.CLAUDER_HUB_PROJECT = target;
60
+
61
+ await import(pathToFileURL(serverEntry).href);
package/logo.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 18 48 30" width="480px" height="300px" baseProfile="basic"><rect width="36" height="24" x="6" y="18" fill="#d77757"/><rect width="3" height="9" x="9" y="39" fill="#d77757"/><rect width="3" height="9" x="15" y="39" fill="#d77757"/><rect width="3" height="9" x="30" y="39" fill="#d77757"/><rect width="3" height="9" x="36" y="39" fill="#d77757"/><rect width="7.5" height="6" y="33" fill="#d77757"/><rect width="7.5" height="6" x="40.5" y="33" fill="#d77757"/><rect width="9" height="9" x="12" y="24"/><rect width="9" height="9" x="27" y="24"/><rect width="3" height="6" x="22.5" y="22.5" transform="rotate(90 24 25.5)"/><rect width="3" height="7" x="37" y="22" transform="rotate(90 38.5 25.5)"/><rect width="3" height="7" x="8" y="22" transform="rotate(90 9.5 25.5)"/></svg>
package/package.json CHANGED
@@ -1,6 +1,56 @@
1
1
  {
2
2
  "name": "clauder-hub",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "A local dashboard that runs, watches and automates the Claude Code sessions of every project on the machine",
5
+ "license": "SEE LICENSE IN LICENSE",
6
+ "author": "goldyndevs <goldyndevs@gmail.com>",
7
+ "homepage": "https://www.npmjs.com/package/clauder-hub",
8
+ "type": "module",
9
+ "engines": {
10
+ "node": ">=22"
11
+ },
12
+ "keywords": [
13
+ "claude",
14
+ "claude-code",
15
+ "dashboard",
16
+ "terminal",
17
+ "automation"
18
+ ],
19
+ "workspaces": [
20
+ "server",
21
+ "web"
22
+ ],
23
+ "bin": {
24
+ "clauder-hub": "bin/clauder-hub.mjs"
25
+ },
26
+ "files": [
27
+ "LICENSE",
28
+ "logo.svg",
29
+ "bin",
30
+ "server/dist",
31
+ "web/dist"
32
+ ],
33
+ "scripts": {
34
+ "dev": "node scripts/dev.mjs",
35
+ "build": "npm run build:server && npm -w web run build",
36
+ "typecheck": "npm -w server run typecheck && npm -w web run typecheck",
37
+ "prepare": "npm run build",
38
+ "build:server": "esbuild server/src/index.ts --bundle --platform=node --format=esm --target=node22 --minify --outfile=server/dist/index.js --external:better-sqlite3 --external:@lydell/node-pty --banner:js=\"import{createRequire}from'node:module';const require=createRequire(import.meta.url);\""
39
+ },
40
+ "dependencies": {
41
+ "@lydell/node-pty": "1.2.0-beta.18",
42
+ "better-sqlite3": "^13.0.3",
43
+ "material-icon-theme": "^5.40.0"
44
+ },
45
+ "devDependencies": {
46
+ "cors": "^2.8.5",
47
+ "croner": "^9.1.0",
48
+ "esbuild": "^0.28.2",
49
+ "express": "^4.21.2",
50
+ "ignore": "^7.0.14",
51
+ "nanoid": "^5.0.9",
52
+ "tsx": "^4.19.2",
53
+ "ws": "^8.18.0",
54
+ "zod": "^4.1.13"
55
+ }
56
+ }