mulmoterminal 0.4.0 → 0.5.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.
- package/README.md +54 -12
- package/bin/mulmoterminal.js +1 -1
- package/dist/assets/index-Cl4YTNRR.js +314 -0
- package/dist/assets/index-DntDzL2r.css +1 -0
- package/dist/assets/{marp-BJeBr0yc.js → marp-D8GYTlaB.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +11 -8
- package/plugins/plugins.json +1 -1
- package/server/accounting-tool.ts +194 -0
- package/server/backends/accounting.ts +41 -0
- package/server/backends/collectionWatchers.ts +80 -0
- package/server/backends/collections.ts +2 -2
- package/server/backends/feeds.ts +74 -0
- package/server/backends/fileChange.spec.ts +77 -0
- package/server/backends/fileChange.ts +51 -0
- package/server/backends/html.spec.ts +1 -1
- package/server/backends/html.ts +6 -18
- package/server/backends/markdown.ts +8 -15
- package/server/backends/notifier.spec.ts +80 -0
- package/server/backends/notifier.ts +78 -0
- package/server/backends/scheduler.spec.ts +175 -0
- package/server/backends/scheduler.ts +158 -0
- package/server/backends/whisper.ts +197 -0
- package/server/backends/workspaceSetup.spec.ts +76 -0
- package/server/backends/workspaceSetup.ts +88 -0
- package/server/dir-config.spec.ts +153 -0
- package/server/dir-config.ts +147 -0
- package/server/host-tools.ts +5 -1
- package/server/index.ts +176 -6
- package/server/plugins-registry.ts +1 -1
- package/dist/assets/index-BiacYhkj.css +0 -1
- package/dist/assets/index-Ctrr8pOx.js +0 -296
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ Requires the [`claude`](https://claude.com/claude-code) CLI on your `PATH` and
|
|
|
25
25
|
**Node ≥ 22.9**.
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
npx mulmoterminal # start on http://localhost:
|
|
28
|
+
npx mulmoterminal # start on http://localhost:34567 and open the browser
|
|
29
29
|
# or install globally:
|
|
30
30
|
npm install -g mulmoterminal
|
|
31
31
|
mulmoterminal
|
|
@@ -36,7 +36,7 @@ prints a one-line notice when a newer version is available (`npm i -g mulmotermi
|
|
|
36
36
|
to update). Disable with `MULMOTERMINAL_NO_UPDATE_CHECK=1` (or `NO_UPDATE_NOTIFIER=1`).
|
|
37
37
|
|
|
38
38
|
Options: `--cwd <dir>` (working directory — relative paths allowed; defaults to the
|
|
39
|
-
directory you run the command from), `--port <n>` (default
|
|
39
|
+
directory you run the command from), `--port <n>` (default 34567), `--no-open`,
|
|
40
40
|
`--version`, `--help`.
|
|
41
41
|
|
|
42
42
|
```bash
|
|
@@ -96,8 +96,11 @@ server, and opens the browser. For local development from a clone, see
|
|
|
96
96
|
- **Script commands** (`yarn dev`, tests, …), launched from a cell's directory
|
|
97
97
|
picker, run in their own ephemeral PTY over a separate WebSocket (`/ws/run`);
|
|
98
98
|
they are not Claude sessions. See [Scripts (Run menu)](#scripts-run-menu).
|
|
99
|
-
-
|
|
100
|
-
|
|
99
|
+
- In dev (`yarn dev`) the Vite dev server runs on its own port (`CLIENT_PORT`,
|
|
100
|
+
default `6856`) and proxies `/ws` (covers `/ws/run`), `/ws/pubsub`, and `/api` to
|
|
101
|
+
the backend (`PORT`, default `34567`) — so you open the Vite port (e.g.
|
|
102
|
+
`http://localhost:6856`). In production the backend serves the built client from
|
|
103
|
+
`dist/` on `PORT`, and you open that.
|
|
101
104
|
|
|
102
105
|
---
|
|
103
106
|
|
|
@@ -139,7 +142,8 @@ the server runs without one.
|
|
|
139
142
|
|
|
140
143
|
| Variable | Default | Description |
|
|
141
144
|
| ------------ | -------------- | ----------- |
|
|
142
|
-
| `PORT`
|
|
145
|
+
| `PORT` | `34567` | Backend HTTP/WebSocket port (prod: the URL you open). |
|
|
146
|
+
| `CLIENT_PORT` | `6856` | Vite dev-server port (dev only: the URL you open with `yarn dev`). |
|
|
143
147
|
| `CLAUDE_BIN` | `claude` | The Claude Code binary to spawn. |
|
|
144
148
|
| `CLAUDE_CWD` | current dir | Working directory each `claude` PTY runs in; determines which project's sessions the sidebar lists. Via `npx mulmoterminal` it defaults to the directory you ran the command from (override with `--cwd <dir>`, relative allowed); when the server is run directly it falls back to `~/mulmoclaude`. A value read from `.env` must be an absolute path (`~` is not expanded). |
|
|
145
149
|
|
|
@@ -166,6 +170,37 @@ chime) or in the config file; the server streams that file at `GET /api/sound` a
|
|
|
166
170
|
the client decodes it (falling back to the chime if it's missing or not audio). It's
|
|
167
171
|
your own local file referenced by absolute path — nothing is added to the package.
|
|
168
172
|
|
|
173
|
+
### Per-directory settings (`<project>/.mulmoterminal.json`)
|
|
174
|
+
|
|
175
|
+
Drop a `.mulmoterminal.json` in a project directory to give terminals opened **in
|
|
176
|
+
that directory** their own look and sound. It applies per terminal (per grid cell) —
|
|
177
|
+
the rest of the app keeps your chosen theme — and a directory's theme overrides your
|
|
178
|
+
manual theme pick for that terminal only. Every field is optional; a missing or
|
|
179
|
+
malformed file is ignored.
|
|
180
|
+
|
|
181
|
+
```jsonc
|
|
182
|
+
{
|
|
183
|
+
"name": "PROD · payments", // badge shown on this directory's terminals
|
|
184
|
+
"badgeColor": "#cf222e", // badge color (hex #rrggbb)
|
|
185
|
+
"theme": "nord", // terminal palette: midnight | nord | daylight | solarized
|
|
186
|
+
"colors": { "background": "#190a23", "cursor": "#ff2e63" }, // per-key palette overrides
|
|
187
|
+
"sound": "./.mulmoterminal/alert.mp3" // attention sound, RELATIVE to this directory
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Field | Meaning |
|
|
192
|
+
| ------------ | ------- |
|
|
193
|
+
| `name` | Label shown as a badge in the terminal/cell header. |
|
|
194
|
+
| `badgeColor` | Badge background color (`#rrggbb`); text auto-contrasts. |
|
|
195
|
+
| `theme` | xterm palette for terminals in this directory (one of the built-in theme ids). |
|
|
196
|
+
| `colors` | Per-key xterm palette overrides applied on top of `theme` (or the app theme when `theme` is unset). Keys are xterm `ITheme` names (`background`, `foreground`, `cursor`, `selectionBackground`, the 16 ANSI colors, …); values are hex (`#rgb` / `#rrggbb` / `#rrggbbaa`). Unknown keys / bad values are dropped. |
|
|
197
|
+
| `sound` | Attention sound for this directory's sessions, a path **relative to the directory** (served at `GET /api/dir-sound`). |
|
|
198
|
+
|
|
199
|
+
**Security.** `sound` is a directory-relative path only — absolute paths and any
|
|
200
|
+
`../` that escapes the directory are rejected, and the path is never taken from the
|
|
201
|
+
HTTP request, so an opened project can't point the player at arbitrary files.
|
|
202
|
+
Changes take effect when the terminal is next opened (no live file watch).
|
|
203
|
+
|
|
169
204
|
---
|
|
170
205
|
|
|
171
206
|
## Running
|
|
@@ -173,14 +208,14 @@ your own local file referenced by absolute path — nothing is added to the pack
|
|
|
173
208
|
```bash
|
|
174
209
|
yarn install # postinstall fixes node-pty prebuilt binary perms
|
|
175
210
|
|
|
176
|
-
yarn dev #
|
|
211
|
+
yarn dev # backend (:34567) + Vite UI (:6856), concurrently — open http://localhost:6856
|
|
177
212
|
# or individually:
|
|
178
213
|
yarn dev:server # backend only (node --import tsx --env-file-if-exists=.env server/index.ts)
|
|
179
214
|
yarn dev:client # Vite dev server only
|
|
180
215
|
|
|
181
216
|
yarn build # type-check (vue-tsc) + vite build -> dist/
|
|
182
217
|
yarn typecheck:server # type-check the server (tsconfig.server.json)
|
|
183
|
-
yarn server # run backend; serves dist/ + the APIs on :
|
|
218
|
+
yarn server # run backend; serves dist/ + the APIs on :34567
|
|
184
219
|
yarn test # vitest run
|
|
185
220
|
```
|
|
186
221
|
|
|
@@ -189,8 +224,8 @@ type-checked separately through `tsconfig.server.json` (`strict`), kept out of
|
|
|
189
224
|
the main `build` so the two type-check independently.
|
|
190
225
|
|
|
191
226
|
In dev, open the Vite URL; its proxy forwards `/ws`, `/ws/pubsub`, and `/api` to
|
|
192
|
-
`:
|
|
193
|
-
`http://localhost:
|
|
227
|
+
`:34567`. In production, run `yarn build` then `yarn server` and open
|
|
228
|
+
`http://localhost:34567`.
|
|
194
229
|
|
|
195
230
|
---
|
|
196
231
|
|
|
@@ -245,7 +280,7 @@ command, so the file is the allowlist of what can run.
|
|
|
245
280
|
|
|
246
281
|
## Server API specification
|
|
247
282
|
|
|
248
|
-
Base URL: `http://localhost:$PORT` (default `http://localhost:
|
|
283
|
+
Base URL: `http://localhost:$PORT` (default `http://localhost:34567`).
|
|
249
284
|
|
|
250
285
|
### HTTP: `GET /api/sessions`
|
|
251
286
|
|
|
@@ -468,6 +503,12 @@ Key rules:
|
|
|
468
503
|
- **Reattach over respawn**: selecting a session that still has a live background
|
|
469
504
|
PTY reattaches to it (replaying a ≤ 64 KB output tail) instead of spawning a
|
|
470
505
|
duplicate `claude`.
|
|
506
|
+
- **One live viewer per session**: a session is bound to a single socket. Opening
|
|
507
|
+
it in a second place (another tab, or another grid cell pointed at the same dir)
|
|
508
|
+
reattaches there and **supersedes** the first, which detaches. To avoid doing
|
|
509
|
+
this by accident, a grid launcher's resume list **flags rows already open in
|
|
510
|
+
another terminal** (`● open`) and **asks for confirmation** before taking one
|
|
511
|
+
over.
|
|
471
512
|
- Brand-new sessions appear in the sidebar **immediately** (before their `.jsonl`
|
|
472
513
|
exists) via the in-memory `knownSessions` registry + a `created` push; an
|
|
473
514
|
unused one disappears when its PTY is reaped.
|
|
@@ -534,9 +575,10 @@ src/
|
|
|
534
575
|
Sidebar.vue Session list; working dot + waiting bold; pub/sub driven
|
|
535
576
|
Sidebar.spec.ts Vitest component tests
|
|
536
577
|
Terminal.vue xterm.js terminal; /ws (or /ws/run); single-view ▶ Run menu
|
|
537
|
-
|
|
578
|
+
AppToolbar.vue Shared header (single + grid); grid-only + Terminal + ⇅/↔ cell-order toggle
|
|
579
|
+
GridView.vue Grid view: auto-layout, pages, manual/auto cell order; runs handed-off scripts
|
|
538
580
|
RunMenu.vue ▶ Run dropdown: lists a dir's script.json, emits the pick
|
|
539
|
-
TerminalCell.vue A cell: Claude launcher (dir picker + resume + run-a-script)
|
|
581
|
+
TerminalCell.vue A cell: Claude launcher (dir picker + resume + run-a-script); ◀▶ to reorder
|
|
540
582
|
TerminalGrid.vue Grid of cells; auto-sizes by count; zoom lines up every tab
|
|
541
583
|
CommandCell.vue A grid cell that runs a script.json command (ephemeral)
|
|
542
584
|
composables/
|
package/bin/mulmoterminal.js
CHANGED
|
@@ -17,7 +17,7 @@ import { fetchLatestVersion, isNewerVersion } from "./update-check.js";
|
|
|
17
17
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
18
|
const PKG_DIR = join(__dirname, "..");
|
|
19
19
|
const SERVER_ENTRY = join(PKG_DIR, "server", "index.ts");
|
|
20
|
-
const DEFAULT_PORT =
|
|
20
|
+
const DEFAULT_PORT = 34567;
|
|
21
21
|
const READY_TIMEOUT_MS = 15_000;
|
|
22
22
|
const MAX_BIND_RETRIES = 5;
|
|
23
23
|
// Server exit code meaning "port taken at bind time" — keep in sync with
|