termdeck-cli 1.0.2

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 ADDED
@@ -0,0 +1,233 @@
1
+ # termdeck
2
+
3
+ A terminal dashboard (TUI) for juggling your local dev projects.
4
+
5
+ One screen lists your projects with a colour-coded status and blurb, and gives
6
+ each one three actions:
7
+
8
+ | CTA | What it does |
9
+ | --- | --- |
10
+ | **Dev Server** | runs `npm run dev` **inside termdeck** — stdout/stderr stream into the scrollable log pane below (no extra terminal window), then the localhost URL is detected and opened in your default browser |
11
+ | **Editor** | opens a **brand new OS terminal window**, `cd`s into the project and runs `code .` |
12
+ | **Agent** | opens a **brand new OS terminal window**, `cd`s into the project and runs `opencode` (placeholder — configurable) |
13
+
14
+ Everything is keyboard driven *and* mouse driven: the three CTAs are clickable
15
+ buttons, the project list is click-selectable, and the mouse wheel scrolls the
16
+ logs.
17
+
18
+ ```
19
+ +----------------------------------------------------------------------+
20
+ | termdeck 4 projects · /home/you/Projects ● 2 dev servers running
21
+ +------------------------+---------------------------------------------+
22
+ | projects | selected project |
23
+ | ● api [Live] | alpha ● Working |
24
+ | ● alpha [Working] | /home/you/Projects/alpha |
25
+ | ○ blog [Pending] | marketing site |
26
+ | ○ lab [Experiment]| editor: code . agent: opencode |
27
+ | | ● dev server running (pid 8123) → localhost |
28
+ +------------------------+---------------------------------------------+
29
+ | | [d] Dev Server [e] Editor [a] Agent |
30
+ | +---------------------------------------------+
31
+ | | dev server logs |
32
+ | | 12:04:11 alpha [termdeck] $npm run dev |
33
+ | | 12:04:12 alpha ➜ Local: http://localhost:51 |
34
+ +------------------------+---------------------------------------------+
35
+ | ↑/↓ select d dev e editor a agent x stop r reload q quit |
36
+ +----------------------------------------------------------------------+
37
+ ```
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ npm install -g termdeck
43
+ termdeck
44
+ ```
45
+
46
+ Requires Node.js 16+ and a real terminal (macOS/Linux Terminal, Windows
47
+ Terminal, iTerm, …). No Docker, no daemon, no background service.
48
+
49
+ ## First run
50
+
51
+ The first launch asks a few questions and remembers the answers in
52
+ `~/.termdeck-config.json`:
53
+
54
+ 1. **Which directory holds your projects?** — pick from suggestions (common
55
+ folders like `~/Projects`, plus every drive letter on Windows) or type a path.
56
+ 2. **Which folders are projects?** — multi-select with <kbd>space</kbd>, confirm
57
+ with <kbd>enter</kbd>.
58
+ 3. **Status + description per folder** — `Experimental`, `Live`, `Working` or
59
+ `Pending`, plus a one line blurb.
60
+
61
+ Every later launch skips straight to the dashboard. Re-run it any time with
62
+ `termdeck --setup` (existing answers are pre-filled as defaults).
63
+
64
+ ## Keys
65
+
66
+ | Key | Action |
67
+ | --- | --- |
68
+ | <kbd>↑</kbd>/<kbd>↓</kbd>, <kbd>j</kbd>/<kbd>k</kbd> | select a project (or click it) |
69
+ | <kbd>d</kbd> | start the dev server for the selection (or click **Dev Server**) |
70
+ | <kbd>e</kbd> | open the editor in a new terminal window (or click **Editor**) |
71
+ | <kbd>a</kbd> | open the agent in a new terminal window (or click **Agent**) |
72
+ | <kbd>x</kbd> | stop the selected project's dev server |
73
+ | <kbd>r</kbd> | reload the config file from disk |
74
+ | <kbd>PgUp</kbd>/<kbd>PgDn</kbd>, wheel | scroll the log pane (pauses following, shows how many lines arrived) |
75
+ | <kbd>shift</kbd>+<kbd>G</kbd>, <kbd>end</kbd> | jump back to live logs |
76
+ | <kbd>home</kbd> | jump to the start of the log history |
77
+ | <kbd>q</kbd>, <kbd>ctrl</kbd>+<kbd>c</kbd> | quit — every dev server termdeck started is stopped first |
78
+
79
+ Quitting while dev servers are running asks for a second <kbd>q</kbd> press.
80
+
81
+ ## CLI
82
+
83
+ ```
84
+ termdeck launch the dashboard (runs setup on first use)
85
+ termdeck --setup re-run the setup wizard
86
+ termdeck --reset delete the config file, then run setup again
87
+ termdeck --list print the configured projects and exit (no TUI)
88
+ termdeck --no-open never auto-open the browser
89
+ termdeck --help
90
+ termdeck --version
91
+ ```
92
+
93
+ ## Config file
94
+
95
+ `~/.termdeck-config.json` (override the path with the `TERMDECK_CONFIG`
96
+ environment variable):
97
+
98
+ ```json
99
+ {
100
+ "version": 1,
101
+ "root": "/home/you/Projects",
102
+ "devCommand": "npm run dev",
103
+ "editorCommand": "code .",
104
+ "agentCommand": "opencode",
105
+ "openBrowser": true,
106
+ "projects": [
107
+ {
108
+ "name": "alpha",
109
+ "path": "/home/you/Projects/alpha",
110
+ "status": "Working",
111
+ "info": "marketing site with a Next.js frontend"
112
+ }
113
+ ]
114
+ }
115
+ ```
116
+
117
+ The same keys can be set **per project** inside a `projects[]` entry
118
+ (`devCommand`, `editorCommand`, `agentCommand`, `port`), which is handy when one
119
+ repo needs `pnpm dev`, `npm start` or a fixed port. Editing the file by hand is
120
+ fine — press <kbd>r</kbd> in the dashboard to reload it.
121
+
122
+ | Field | Meaning |
123
+ | --- | --- |
124
+ | `devCommand` | command run for the Dev Server CTA (default `npm run dev`) |
125
+ | `editorCommand` | command run in the new editor terminal (default `code .`) |
126
+ | `agentCommand` | command run in the new agent terminal (default `opencode`) |
127
+ | `openBrowser` | set to `false` (or pass `--no-open`) to keep the browser closed |
128
+ | `port` | fallback port used if the dev server never prints a URL (default `3000`) |
129
+ | `status` | `Experimental` · `Live` · `Working` · `Pending` |
130
+
131
+ ## How each CTA works
132
+
133
+ **Dev Server (in-app logs).** `cross-spawn` runs the dev command with `cwd` set
134
+ to the project, `stdio: ['ignore','pipe','pipe']` and `FORCE_COLOR=0`, so nothing
135
+ is attached to a terminal. Each stream is split into lines and pushed into the
136
+ blessed-contrib `log` widget in the dashboard (batched every 120 ms — dev
137
+ servers can emit hundreds of lines per second). Every line is scanned for a
138
+ localhost URL (`http://localhost:5173/`, `0.0.0.0:3000`, `listening on port
139
+ 4200`, …); the first hit is normalised, and after a short delay the `open`
140
+ package launches your default browser. If no URL shows up within ~9 seconds,
141
+ termdeck assumes `http://localhost:<port || 3000>` and says so in the log pane.
142
+ Processes are spawned detached on macOS/Linux and killed as a tree
143
+ (`process.kill(-pid)` / `taskkill /T /F`), so a quit never leaves an orphaned
144
+ Vite/Next server behind.
145
+
146
+ **Editor / Agent (new terminal windows).** `cross-spawn` launches the OS
147
+ terminal:
148
+
149
+ - **macOS** — `osascript -e 'tell application "Terminal" … do script "cd … && code ."'`
150
+ - **Windows** — `wt.exe -d "<dir>" cmd /k "code ."`, falling back to
151
+ `cmd /c start "" /D "<dir>" cmd.exe /k "code ."` when Windows Terminal is not
152
+ installed
153
+ - **Linux** — the first emulator found on `PATH` out of `gnome-terminal`,
154
+ `konsole`, `xfce4-terminal`, `kitty`, `alacritty`, `wezterm`,
155
+ `x-terminal-emulator`, `xterm` (each gets `--working-directory`/`-e` with
156
+ `bash -lc` and `exec bash` so the window stays open)
157
+
158
+ On Linux you can force a specific emulator with the `TERMDECK_TERMINAL`
159
+ environment variable.
160
+
161
+ ## Linking locally (test before publishing)
162
+
163
+ From the project folder:
164
+
165
+ ```bash
166
+ npm install # install dependencies
167
+ npm test # unit + end-to-end dev server tests (no TUI needed)
168
+ npm run smoke # headless TUI smoke test: renders the dashboard, clicks a CTA
169
+
170
+ npm link # symlinks this package into your global node_modules
171
+ termdeck # now runs from anywhere with your edits live
172
+
173
+ # when you are done
174
+ npm unlink -g termdeck
175
+ ```
176
+
177
+ `npm link` creates a global `termdeck` shim that points at this directory, so
178
+ code changes take effect immediately — no republishing. If you would rather not
179
+ touch the global install, these work too:
180
+
181
+ ```bash
182
+ npm install -g . # real global install from the folder
183
+ node bin/termdeck.js # run the entry point directly
184
+ npm exec -- termdeck # run via the local package
185
+ ```
186
+
187
+ Two tips while testing:
188
+
189
+ - Keep your real config safe by pointing at a throwaway one:
190
+ `TERMDECK_CONFIG=./scratch-config.json termdeck` (on Windows Git Bash use
191
+ `TERMDECK_CONFIG=./scratch-config.json node bin/termdeck.js`).
192
+ - `termdeck --list` prints the parsed config without starting the TUI, which is
193
+ the quickest way to check that setup wrote what you expected.
194
+
195
+ When you are ready to publish:
196
+
197
+ ```bash
198
+ npm pack --dry-run # inspect exactly which files would be uploaded
199
+ npm publish # needs an npm account; the package name must be free
200
+ ```
201
+
202
+ The `bin` field in `package.json` plus the `#!/usr/bin/env node` shebang in
203
+ `bin/termdeck.js` are what make the global `termdeck` command work.
204
+
205
+ ## Troubleshooting
206
+
207
+ | Symptom | Fix |
208
+ | --- | --- |
209
+ | `termdeck needs an interactive terminal` | first-run setup and the dashboard need a TTY. Use a real terminal, or `termdeck --list` |
210
+ | Browser opens too early / too late | tune the port: the URL is only opened once it appears in the output. Silence your dev server's URL banner and termdeck falls back after ~9s |
211
+ | "no terminal emulator found" | install one of the Linux terminals above or set `TERMDECK_TERMINAL` |
212
+ | `opencode` not found in the new window | change `agentCommand` to whatever you use (`cursor .`, `claude`, `aider`, …) |
213
+ | Log colours look plain | intentional: ANSI codes are stripped so the log pane stays readable in a terminal multiplexer |
214
+ | Nothing appears when clicking | make sure you are *inside* the TUI window and the terminal reports mouse events (Windows Terminal, iTerm2, GNOME Terminal, VS Code all do) |
215
+
216
+ ## Development
217
+
218
+ ```
219
+ bin/termdeck.js shebang shim -> src/index.js
220
+ src/index.js CLI flags, setup-or-dashboard decision
221
+ src/config.js ~/.termdeck-config.json + the inquirer wizard
222
+ src/dashboard.js the blessed/blessed-contrib TUI
223
+ src/devServer.js spawn + log streaming + URL detection + browser open
224
+ src/terminal.js OS-specific "new terminal window" plans
225
+ src/logView.js scrollable, follow-the-tail log pane
226
+ src/util.js ANSI stripping, URL parsing, which(), killTree()
227
+ test/run.js npm test — unit tests + a real npm run dev lifecycle
228
+ test/smoke.js npm run smoke — headless render + real mouse click on a CTA
229
+ ```
230
+
231
+ ## License
232
+
233
+ MIT
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * termdeck binary entry point.
6
+ *
7
+ * The shebang above (plus the `bin` field in package.json) is what makes
8
+ * `npm i -g termdeck` give you a global `termdeck` command.
9
+ */
10
+
11
+ const { main } = require('../src/index.js');
12
+
13
+ main(process.argv.slice(2))
14
+ .then((code) => {
15
+ // The dashboard keeps the process alive; only surface real exit codes.
16
+ if (typeof code === 'number' && code !== 0) process.exitCode = code;
17
+ })
18
+ .catch((err) => {
19
+ const message = err && err.message ? err.message : String(err);
20
+ process.stderr.write(`termdeck: ${message}\n`);
21
+ process.exitCode = 1;
22
+ });
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "termdeck-cli",
3
+ "version": "1.0.2",
4
+ "description": "A terminal dashboard for your local dev projects: start dev servers with in-app logs, open your editor, or launch a coding agent in a fresh terminal window.",
5
+ "keywords": [
6
+ "cli",
7
+ "tui",
8
+ "dashboard",
9
+ "blessed",
10
+ "blessed-contrib",
11
+ "dev-server",
12
+ "projects"
13
+ ],
14
+ "license": "MIT",
15
+ "main": "src/index.js",
16
+ "bin": {
17
+ "termdeck": "bin/termdeck.js"
18
+ },
19
+ "files": [
20
+ "bin",
21
+ "src",
22
+ "README.md"
23
+ ],
24
+ "engines": {
25
+ "node": ">=16"
26
+ },
27
+ "scripts": {
28
+ "start": "node bin/termdeck.js",
29
+ "test": "node test/run.js",
30
+ "smoke": "node test/smoke.js"
31
+ },
32
+ "dependencies": {
33
+ "blessed": "^0.1.81",
34
+ "blessed-contrib": "^4.11.0",
35
+ "cross-spawn": "^7.0.3",
36
+ "inquirer": "^8.2.6",
37
+ "open": "^8.4.2"
38
+ }
39
+ }