procdeck 1.1.0 → 2.0.0-rc.1
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/CHANGELOG.md +277 -0
- package/bin/procdeck.js +50 -0
- package/package.json +13 -46
- package/readme.md +40 -25
- package/schema.json +38 -73
- package/dist/chunk-SIAA4J6H.js +0 -21
- package/dist/cli.js +0 -48462
- package/dist/public.d.ts +0 -82
- package/dist/public.js +0 -7
- package/ui/dist/apple-touch-icon.png +0 -0
- package/ui/dist/assets/index-BkSDVPyT.css +0 -32
- package/ui/dist/assets/index-Co81BEum.js +0 -95
- package/ui/dist/icon-192.png +0 -0
- package/ui/dist/icon-512.png +0 -0
- package/ui/dist/icon-alert.svg +0 -25
- package/ui/dist/icon.svg +0 -22
- package/ui/dist/index.html +0 -33
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# procdeck
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- procdeck is one native binary now — rewritten in Go, the web UI embedded.
|
|
8
|
+
`npx procdeck` and `pnpm add -D procdeck` keep working: the npm package is a
|
|
9
|
+
small launcher, and the binary for your machine arrives as an optional
|
|
10
|
+
dependency (`@procdeck/<os>-<arch>`), with no install scripts. Node is no
|
|
11
|
+
longer needed to run procdeck. Outside npm there is a Homebrew tap, an
|
|
12
|
+
`install.sh`, and a tarball, `.deb` or `.rpm` per platform on every GitHub
|
|
13
|
+
release; `go install github.com/kondaurovDev/procdeck@latest` builds it from
|
|
14
|
+
source.
|
|
15
|
+
|
|
16
|
+
Breaking, against what 1.0 promised:
|
|
17
|
+
|
|
18
|
+
- **Configs are JSON** — `procdeck.config.json`, or `procdeck.config.jsonc`
|
|
19
|
+
with comments and trailing commas. A `procdeck.config.ts` / `.js` is
|
|
20
|
+
reported with a pointer to move it; `defineConfig` is gone with it.
|
|
21
|
+
- **Unknown config keys are errors**, instead of being silently ignored — a
|
|
22
|
+
typo like `"need"` no longer quietly does nothing.
|
|
23
|
+
- **Regexes are RE2** (`alerts`, `preflight.expect`, `--grep`, `--path`,
|
|
24
|
+
`--pattern`): no lookaround or backreferences, and linear time on any
|
|
25
|
+
output.
|
|
26
|
+
- **MCP tool problems** (no deck, unknown proc) come back as tool errors
|
|
27
|
+
(`isError`) rather than `{error}` values; read-only tools are annotated as
|
|
28
|
+
such.
|
|
29
|
+
- The global `--log-level` and `--completions` flags are gone; `procdeck
|
|
30
|
+
completion <shell>` prints completions.
|
|
31
|
+
|
|
32
|
+
### Minor Changes
|
|
33
|
+
|
|
34
|
+
- `envFile` (one path or a list) layers dotenv files under every proc's `env`
|
|
35
|
+
and every preflight. The files are read at each spawn, so a refreshed `.env`
|
|
36
|
+
reaches a proc on its next restart — no deck restart, no
|
|
37
|
+
`node --env-file` wrapper.
|
|
38
|
+
- `procdeck logs <proc> -f` follows a proc's output (it used to follow only
|
|
39
|
+
`--self`).
|
|
40
|
+
- A detached deck's own log rotates past 4 MB instead of growing forever.
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- The HTTP observer forwards standard proxy headers: `x-forwarded-host` carries
|
|
45
|
+
the original Host (an outer proxy's value wins), so frameworks that CSRF-check
|
|
46
|
+
Origin against it — Next.js Server Actions — accept mutating requests;
|
|
47
|
+
`x-forwarded-proto` and `x-forwarded-for` are set too. A client abort cancels
|
|
48
|
+
the upstream request, and an upstream dying mid-body cuts the client
|
|
49
|
+
connection instead of hanging it or appending an error note.
|
|
50
|
+
- A relative `cwd` resolves against the config's directory, also for
|
|
51
|
+
`up --fg` from a subdirectory.
|
|
52
|
+
- A `\r\n` split across two reads of a process's output no longer loses the
|
|
53
|
+
line.
|
|
54
|
+
- Start/stop/restart of an unknown proc answers 404 with a message, not 500.
|
|
55
|
+
- A proc's `cmd` is looked up in the proc's own `PATH`, and `PROCDECK_DETACHED`
|
|
56
|
+
no longer leaks into proc environments.
|
|
57
|
+
- A preflight that times out is killed with its whole process group.
|
|
58
|
+
- Port detection runs one `ps` and one `lsof` per poll for the whole deck,
|
|
59
|
+
instead of a pair per proc.
|
|
60
|
+
|
|
61
|
+
## 1.1.1
|
|
62
|
+
|
|
63
|
+
### Patch Changes
|
|
64
|
+
|
|
65
|
+
- c1a0400: HTTP observer forwards standard proxy headers and propagates connection failures faithfully:
|
|
66
|
+
|
|
67
|
+
- `x-forwarded-host` now carries the original Host (an outer proxy's value wins), so frameworks that CSRF-check Origin against the forwarded host — Next.js Server Actions — no longer reject mutating requests. `x-forwarded-proto` and `x-forwarded-for` are set too.
|
|
68
|
+
- A client abort (closed tab, cancelled fetch) now destroys the upstream request instead of letting it stream to completion unseen.
|
|
69
|
+
- An upstream dying mid-body truncates the client response by cutting the connection, instead of hanging the client or corrupting the payload with an appended error note.
|
|
70
|
+
|
|
71
|
+
## 1.1.0
|
|
72
|
+
|
|
73
|
+
### Minor Changes
|
|
74
|
+
|
|
75
|
+
- dace5bb: A proc can pin its assigned `${port}` to a fixed public number: `port: 8787`
|
|
76
|
+
on the spec. The public side stays exactly that number — dotenv files, mobile
|
|
77
|
+
simulators and teammates' scripts keep their hardcoded `localhost:8787` —
|
|
78
|
+
while an observed proc still binds a hidden internal port behind the HTTP
|
|
79
|
+
observer, so the traffic gets captured with no wiring changes anywhere.
|
|
80
|
+
Conflicting pins (duplicate, on the UI's port, or on a proc that never uses
|
|
81
|
+
`${port}`) are config errors; a pin whose port is already taken parks just
|
|
82
|
+
that proc in `blocked` — naming the port and the likely holder — while the
|
|
83
|
+
rest of the deck runs, and Start retries the bind. A pinned proc with no
|
|
84
|
+
`url` also gets its UI link derived from the pin.
|
|
85
|
+
|
|
86
|
+
## 1.0.0
|
|
87
|
+
|
|
88
|
+
### Major Changes
|
|
89
|
+
|
|
90
|
+
- 2364ad0: procdeck 1.0.0. Nothing breaks in this release — the version says the surface
|
|
91
|
+
is settled and will not move under you without a major bump.
|
|
92
|
+
|
|
93
|
+
What 1.0 promises to keep stable:
|
|
94
|
+
|
|
95
|
+
- **The config**, both formats: every field of the schema (and therefore
|
|
96
|
+
`schema.json`), the `${port}` / `${port:id}` templating, `needs` /
|
|
97
|
+
`readyWhen` readiness, `preflight`, `alerts`, `observe`, and the
|
|
98
|
+
`defineConfig` export.
|
|
99
|
+
- **The CLI**: the verbs (`up`, `down`, `restart`, `status`, `ls`, `open`,
|
|
100
|
+
`init`, `logs`, `mark`, `wait-for`, `errors`, `http`, `agents`, `mcp`),
|
|
101
|
+
their flags, and the shape of every `--json` payload. `wait-for` keeps exit
|
|
102
|
+
2 for a timeout.
|
|
103
|
+
- **The MCP tools**: names and parameters of `deck_status`, `get_logs`,
|
|
104
|
+
`get_http`, `get_errors`, `set_mark`, `wait_for`, `timeline`, and the
|
|
105
|
+
`--mutations` trio.
|
|
106
|
+
- **The addresses**: `<id>.localhost:<ui-port>` for every proc, the UI on
|
|
107
|
+
4820 by default, loopback-only unless `host` says otherwise.
|
|
108
|
+
|
|
109
|
+
Internals stay internal: the deck's HTTP API, the registry files under
|
|
110
|
+
`~/.procdeck/`, the SSE event shapes and everything under `src/` are free to
|
|
111
|
+
change.
|
|
112
|
+
|
|
113
|
+
The readme is now the pitch and the docs live in `docs/` — config reference,
|
|
114
|
+
the agent harness, the traffic observer and the architecture notes.
|
|
115
|
+
|
|
116
|
+
### Minor Changes
|
|
117
|
+
|
|
118
|
+
- 6ef989d: `procdeck restart --all` restarts every deck on this machine — stop, then detach again
|
|
119
|
+
from each deck's own registry entry (foreground decks are skipped). The version a deck
|
|
120
|
+
actually runs now shows in `status`, `ls` and the UI's deck switcher, and `status`/`up`
|
|
121
|
+
say so out loud when it differs from the CLI — the answer to "did my update reach this
|
|
122
|
+
deck?".
|
|
123
|
+
|
|
124
|
+
## 0.5.0
|
|
125
|
+
|
|
126
|
+
### Minor Changes
|
|
127
|
+
|
|
128
|
+
- 10b557f: procdeck is now a harness for coding agents, not just a dashboard for humans.
|
|
129
|
+
New CLI verbs, all bounded and `--json`-able: `status --json` grows an
|
|
130
|
+
`attention` list (crashed / blocked / alerting procs with reasons — the
|
|
131
|
+
cheapest first question); `logs [proc]` returns pane output as plain
|
|
132
|
+
timestamped lines (ANSI stripped, `\r` progress bars keep only their final
|
|
133
|
+
state), filterable with `--grep`, `--since`, `--lines` — no proc means every
|
|
134
|
+
proc interleaved with `[id]` prefixes, and the old daemon-log behaviour moved
|
|
135
|
+
to `logs --self [-f]`; `mark [name]` drops a named marker in every proc's
|
|
136
|
+
stream and `--since-mark` shows only what happened after it — the verify
|
|
137
|
+
loop (mark → edit → restart → check) in four commands; `wait-for <proc>
|
|
138
|
+
[--pattern RE]` blocks until a listening port or a matching line, failing
|
|
139
|
+
fast with the log tail if the proc crashes instead (exit 2 on timeout);
|
|
140
|
+
`errors [proc]` parses stack traces out of recent output and deduplicates
|
|
141
|
+
them by signature ("same TypeError, 41×, last 3s ago"); `restart <proc>`
|
|
142
|
+
restarts a single process. `procdeck mcp` serves the same verbs over MCP
|
|
143
|
+
(stdio) — `claude mcp add procdeck -- procdeck mcp` once, globally, and the
|
|
144
|
+
instance registry finds the right deck per project; read-only by default,
|
|
145
|
+
`--mutations` adds restart/stop/start, plus `since_last` cursors and a
|
|
146
|
+
`timeline` tool. `procdeck agents` (and `procdeck init`) plant the discovery:
|
|
147
|
+
a `## procdeck` section in CLAUDE.md / AGENTS.md and a Claude Code skill
|
|
148
|
+
teaching the loop.
|
|
149
|
+
- 10b557f: procdeck sees the traffic now, not just the logs. Procs that use `${port}`
|
|
150
|
+
get an HTTP observer interposed on their assigned port: the proc binds a
|
|
151
|
+
hidden internal port, procdeck listens on the public one and forwards — so
|
|
152
|
+
requests between processes (`${port:api}`) and into them are captured
|
|
153
|
+
transparently, statuses and bodies included, with zero app changes
|
|
154
|
+
(`"observe": false` opts a proc out; the `*.localhost` proxy captures for
|
|
155
|
+
opted-out procs). WebSocket connections are captured per-message with
|
|
156
|
+
direction and text — compression is stripped at the handshake so frames stay
|
|
157
|
+
readable. Bodies are text-only and truncated (16 KB); `authorization`,
|
|
158
|
+
`cookie` and friends are redacted before anything is stored. Three surfaces
|
|
159
|
+
over the same per-proc rings: `procdeck http [proc] [--status 5xx|422|error]
|
|
160
|
+
[--path RE] [--since-mark] [--ws] [--body] [--digest] [--json]` — `--digest`
|
|
161
|
+
groups 4xx/5xx by route with path params collapsed (`/users/:id`); a
|
|
162
|
+
`get_http` MCP tool with `since_last` cursors (and `timeline` now carries
|
|
163
|
+
the window's exchanges); and a traffic view in the UI — the ⇄ position of
|
|
164
|
+
the layout switch — with kind/proc/errors filters, click-to-expand bodies,
|
|
165
|
+
pause and clear. Marks span both streams, so mark → act →
|
|
166
|
+
`http --since-mark` shows exactly which requests a change caused and what
|
|
167
|
+
they returned.
|
|
168
|
+
|
|
169
|
+
## 0.4.0
|
|
170
|
+
|
|
171
|
+
### Minor Changes
|
|
172
|
+
|
|
173
|
+
- 8e4b627: procdeck runs in the background now. `procdeck up` (and bare `procdeck`) starts the
|
|
174
|
+
deck detached, opens the UI and returns — no terminal tab kept hostage; `up --fg` is
|
|
175
|
+
the old foreground mode. New commands, all working from anywhere inside the project:
|
|
176
|
+
`down` (terminates every process tree), `restart`, `status`, `ls` (every running deck
|
|
177
|
+
on the machine), `open` and `logs [-f]`. Running decks register in
|
|
178
|
+
`~/.procdeck/instances/` (stale entries pruned by pid; `PROCDECK_HOME` relocates it);
|
|
179
|
+
a detached deck's own output goes to `~/.procdeck/logs/`. `up` refuses a port already
|
|
180
|
+
held by another deck — naming it — or simply busy, before anything spawns; a bad
|
|
181
|
+
config is reported in the terminal, not in a log file. In the UI: ⏻ shuts the deck
|
|
182
|
+
down (with a confirm), the page says so instead of "reconnecting" and revives itself
|
|
183
|
+
when `procdeck up` runs again; the deck name in the bar lists the other running decks
|
|
184
|
+
as links. The CLI moved to `effect/unstable/cli` — `--help` per command, shell
|
|
185
|
+
completions via `--completions`.
|
|
186
|
+
- f2abc61: Three things for the first real release. **Loopback only:** the server binds
|
|
187
|
+
`127.0.0.1` by default — the UI types into real terminals, so it is not something to
|
|
188
|
+
put on the LAN by accident; `"host": "0.0.0.0"` in the config opens it up for
|
|
189
|
+
devcontainers and VMs. **Per-proc backlog:** each proc keeps its last 256 KB of output
|
|
190
|
+
and a new tab gets every pane's history plus a `synced` marker before live events — a
|
|
191
|
+
chatty ticker can no longer evict a quiet server's startup lines, a deck that has run
|
|
192
|
+
for days still opens with every pane populated, the UI knows exactly which chunks are
|
|
193
|
+
news, and a reconnect replays into freshly reset panes instead of appending history to
|
|
194
|
+
itself. **`procdeck init`:** writes a first `procdeck.config.json` from what is already there —
|
|
195
|
+
a Procfile, workspace packages with `dev` scripts (via the package manager your lockfile
|
|
196
|
+
points at), plain `backend/` + `frontend/` subdirectories (each its own package.json or
|
|
197
|
+
a Django / Go / Rust / Rails / compose project, with `cwd` set), or the root itself.
|
|
198
|
+
|
|
199
|
+
### Patch Changes
|
|
200
|
+
|
|
201
|
+
- 9f944e5: The deck tells you when it needs you. Procs that crashed, are blocked on a preflight,
|
|
202
|
+
carry an alert or have unread error lines count into the tab title (`(2) garage ·
|
|
203
|
+
procdeck`) and put a red dot on the favicon — visible from the tab strip and the Dock.
|
|
204
|
+
A bell in the global bar turns on system notifications: a crash, a block or a new alert
|
|
205
|
+
while the tab is hidden or the window unfocused shows one (click brings the deck back);
|
|
206
|
+
replayed history on reconnect never notifies. The bell state persists with the UI state;
|
|
207
|
+
the browser permission is asked for on the first click.
|
|
208
|
+
- 1db7f78: Grid pinning. Pin a proc (📌 in its pane header or sidebar row, ⌥P on the active one) and
|
|
209
|
+
the grid shows only pinned procs; the rest collapse into a tray strip under the tiles —
|
|
210
|
+
status dot, id, badges — where a click peeks at one and the pin puts it back. Nothing
|
|
211
|
+
pinned = everyone tiled, as before. ⌥Z zooms the active tile in and out of single. The
|
|
212
|
+
grid now sizes its columns from the tile count (near-square, at most 4) so the deck fits
|
|
213
|
+
the screen when it can and scrolls only when tiles would drop under 180 px. Pins persist
|
|
214
|
+
with the rest of the UI state.
|
|
215
|
+
- e90a08c: Polish before publishing, part one.
|
|
216
|
+
|
|
217
|
+
- URLs in pane output are clickable (`Local: http://localhost:5173/` from every dev
|
|
218
|
+
server opens in a new tab).
|
|
219
|
+
- Exit status reads like a human wrote it: `exit 1 · 2m ago`, `killed (SIGTERM) · 5s ago`
|
|
220
|
+
— signal names instead of numbers, and no more `signal 0` on a plain non-zero exit.
|
|
221
|
+
Running procs that were respawned show a restart count (`↻3`), so crash loops are
|
|
222
|
+
visible from the status line. The sidebar shows the same exit summary where uptime sits
|
|
223
|
+
while running.
|
|
224
|
+
- Grid tile headers keep the `*.localhost` address whole instead of clipping it to `:61`:
|
|
225
|
+
compact tiles show only the primary address (raw ports in its tooltip) and the status
|
|
226
|
+
text is what gives way first.
|
|
227
|
+
- The assigned port no longer also counts as "internal" when it lands in the ephemeral
|
|
228
|
+
range.
|
|
229
|
+
|
|
230
|
+
- a85d537: Light theme. A System · Light · Dark switch in the global bar; System follows the OS
|
|
231
|
+
(`prefers-color-scheme`) and tracks it live. The terminals switch palette too — light gets
|
|
232
|
+
its own ANSI set (GitHub Light), since xterm's defaults are unreadable on white. The choice
|
|
233
|
+
is stored with the rest of the UI state and painted before the first frame, so there is
|
|
234
|
+
no flash on reload.
|
|
235
|
+
- 512e814: The UI remembers itself across reloads, and says when it has lost the server.
|
|
236
|
+
|
|
237
|
+
Layout (single/grid) and the selected pane are kept in localStorage — per origin, so per
|
|
238
|
+
deck — and restored on the next load; a stored pane that is no longer in the config falls
|
|
239
|
+
back to the first one. While the event stream is down (a `procdeck restart`, a killed
|
|
240
|
+
server) a "reconnecting" banner sits over the panes instead of the UI silently showing
|
|
241
|
+
stale state; when the stream is back the proc snapshot is refetched so statuses that
|
|
242
|
+
changed in the meantime catch up. A stream the browser gave up on (server answered with
|
|
243
|
+
something other than an event stream) is retried every 2 s.
|
|
244
|
+
|
|
245
|
+
## 0.3.0
|
|
246
|
+
|
|
247
|
+
### Minor Changes
|
|
248
|
+
|
|
249
|
+
- a1ced2e: Cut the install from 116 MB to 1.8 MB, and remove every reason for it to fail.
|
|
250
|
+
|
|
251
|
+
`node-pty` is replaced by `@lydell/node-pty` — the same upstream sources and the same API,
|
|
252
|
+
but the binaries ship as per-platform optional dependencies instead of one tarball carrying
|
|
253
|
+
every platform's prebuilds. Upstream runs an install script and has no Linux prebuild at
|
|
254
|
+
all, so Linux users needed a C++ toolchain and pnpm ≥ 10 / Bun users needed
|
|
255
|
+
`pnpm approve-builds` (or `trustedDependencies`) on every platform or spawning failed at
|
|
256
|
+
runtime. The replacement runs no install script and compiles nothing, anywhere — which also
|
|
257
|
+
retires the startup hack that repaired the darwin `spawn-helper` execute bit.
|
|
258
|
+
|
|
259
|
+
`effect` is no longer installed either: it is bundled into the CLI, where tree-shaking takes
|
|
260
|
+
it from 48 MB on disk to under 1 MB of shipped code. The package's public entry point
|
|
261
|
+
(`defineConfig` and the config types) is now a standalone module with no effect types in its
|
|
262
|
+
declarations, so a `procdeck.config.ts` typechecks against a package that has none of
|
|
263
|
+
procdeck's own dependencies installed.
|
|
264
|
+
|
|
265
|
+
## 0.2.0
|
|
266
|
+
|
|
267
|
+
### Minor Changes
|
|
268
|
+
|
|
269
|
+
- 212de8d: Accept `procdeck.config.json` next to the TypeScript config, validated by the same schema.
|
|
270
|
+
A JSON deck needs nothing from the project's toolchain — no TypeScript, and procdeck itself
|
|
271
|
+
does not have to be a dependency, so `npx procdeck` works in any repo. Point `$schema` at
|
|
272
|
+
`https://unpkg.com/procdeck/schema.json` (generated from the Effect schema at build time and
|
|
273
|
+
shipped with the package) for completion and validation in the editor.
|
|
274
|
+
|
|
275
|
+
Started without an argument, the CLI now looks for `procdeck.config.json`, `.ts`, `.js` and
|
|
276
|
+
`.mjs` in that order, and reports a missing or unreadable config against the file instead of
|
|
277
|
+
crashing. `port` is validated as an integer in 1–65535.
|
package/bin/procdeck.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict"
|
|
3
|
+
|
|
4
|
+
// procdeck's npm entry. The binary for this machine ships as an optional
|
|
5
|
+
// dependency — @procdeck/<os>-<arch> — so the package manager installs only
|
|
6
|
+
// the one that fits, with no install scripts. This launcher finds it and runs
|
|
7
|
+
// it with the same arguments, terminal and exit code.
|
|
8
|
+
|
|
9
|
+
const { spawn } = require("node:child_process")
|
|
10
|
+
|
|
11
|
+
const supported = ["darwin-arm64", "darwin-x64", "linux-arm64", "linux-x64"]
|
|
12
|
+
const target = `${process.platform}-${process.arch}`
|
|
13
|
+
|
|
14
|
+
const fail = (message) => {
|
|
15
|
+
console.error(`procdeck: ${message}`)
|
|
16
|
+
process.exit(1)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const binary = () => {
|
|
20
|
+
// A binary built from source, for trying a change through this launcher.
|
|
21
|
+
if (process.env.PROCDECK_BINARY) return process.env.PROCDECK_BINARY
|
|
22
|
+
if (!supported.includes(target)) {
|
|
23
|
+
fail(`no binary for ${target} — supported: ${supported.join(", ")}`)
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return require.resolve(`@procdeck/${target}/bin/procdeck`)
|
|
27
|
+
} catch {
|
|
28
|
+
fail(
|
|
29
|
+
`@procdeck/${target} is missing — it carries the procdeck binary for this machine. ` +
|
|
30
|
+
"Reinstall without --no-optional / --omit=optional."
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const child = spawn(binary(), process.argv.slice(2), { stdio: "inherit" })
|
|
36
|
+
|
|
37
|
+
// Pass signals on rather than dying of them: the binary decides how to stop
|
|
38
|
+
// (a deck tears its processes down first). A Ctrl-C reaches the binary from
|
|
39
|
+
// the terminal as well; it reads a repeat within a moment as the same press.
|
|
40
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
|
|
41
|
+
process.on(signal, () => child.kill(signal))
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
child.on("error", (cause) => fail(cause.message))
|
|
45
|
+
child.on("exit", (code, signal) => {
|
|
46
|
+
if (signal === null) process.exit(code ?? 1)
|
|
47
|
+
// Die of the same signal, so the caller sees what the binary saw.
|
|
48
|
+
process.removeAllListeners(signal)
|
|
49
|
+
process.kill(process.pid, signal)
|
|
50
|
+
})
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "procdeck",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0-rc.1",
|
|
4
|
+
"description": "Dev-process multiplexer with a web UI: terminal panes in a browser tab, declarative dependencies, assigned ports, a *.localhost proxy and captured HTTP traffic. One native binary.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
7
7
|
"dev-server",
|
|
@@ -22,56 +22,23 @@
|
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
24
24
|
"url": "https://github.com/kondaurovDev/procdeck",
|
|
25
|
-
"directory": "
|
|
25
|
+
"directory": "npm/procdeck"
|
|
26
26
|
},
|
|
27
27
|
"bin": {
|
|
28
|
-
"procdeck": "
|
|
28
|
+
"procdeck": "bin/procdeck.js"
|
|
29
29
|
},
|
|
30
30
|
"files": [
|
|
31
|
-
"
|
|
31
|
+
"bin",
|
|
32
32
|
"schema.json",
|
|
33
|
-
"
|
|
33
|
+
"CHANGELOG.md"
|
|
34
34
|
],
|
|
35
|
-
"type": "module",
|
|
36
|
-
"exports": {
|
|
37
|
-
".": {
|
|
38
|
-
"types": "./dist/public.d.ts",
|
|
39
|
-
"import": "./dist/public.js"
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
"publishConfig": {
|
|
43
|
-
"access": "public"
|
|
44
|
-
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"@lydell/node-pty": "1.2.0-beta.15"
|
|
47
|
-
},
|
|
48
|
-
"devDependencies": {
|
|
49
|
-
"@effect/platform-browser": "4.0.0-beta.106",
|
|
50
|
-
"@effect/platform-node-shared": "4.0.0-beta.106",
|
|
51
|
-
"@types/node": "^22.10.1",
|
|
52
|
-
"@xterm/addon-fit": "^0.11.0",
|
|
53
|
-
"@xterm/addon-search": "^0.16.0",
|
|
54
|
-
"@xterm/addon-web-links": "^0.12.0",
|
|
55
|
-
"@xterm/xterm": "^6.0.0",
|
|
56
|
-
"effect": "4.0.0-beta.106",
|
|
57
|
-
"foldkit": "^0.141.2",
|
|
58
|
-
"tsup": "^8.5.1",
|
|
59
|
-
"typescript": "^7.0.2",
|
|
60
|
-
"vite": "^6.2.0",
|
|
61
|
-
"vitest": "^3.2.4"
|
|
62
|
-
},
|
|
63
35
|
"engines": {
|
|
64
|
-
"node": ">=
|
|
36
|
+
"node": ">=18"
|
|
65
37
|
},
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"build:ui": "vite build ui",
|
|
72
|
-
"build:js": "tsup",
|
|
73
|
-
"build:types": "tsc -p tsconfig.build.json",
|
|
74
|
-
"check:types": "tsc --noEmit && tsc -p ui --noEmit",
|
|
75
|
-
"test": "vitest run"
|
|
38
|
+
"optionalDependencies": {
|
|
39
|
+
"@procdeck/linux-arm64": "2.0.0-rc.1",
|
|
40
|
+
"@procdeck/linux-x64": "2.0.0-rc.1",
|
|
41
|
+
"@procdeck/darwin-x64": "2.0.0-rc.1",
|
|
42
|
+
"@procdeck/darwin-arm64": "2.0.0-rc.1"
|
|
76
43
|
}
|
|
77
|
-
}
|
|
44
|
+
}
|
package/readme.md
CHANGED
|
@@ -7,7 +7,7 @@ Run your whole dev stack with one command — and actually see what it's doing.
|
|
|
7
7
|
|
|
8
8
|

|
|
9
9
|
|
|
10
|
-
procdeck is four tools in one
|
|
10
|
+
procdeck is four tools in one binary — the process runner, the port
|
|
11
11
|
allocator, the log viewer and the network tab of your dev environment:
|
|
12
12
|
|
|
13
13
|
- **Runs everything.** Every proc is a real terminal in a browser tab — and
|
|
@@ -28,20 +28,29 @@ npx procdeck # starts the deck in the background and opens the UI
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
The UI opens at <http://localhost:4820> and your terminal is free again.
|
|
31
|
-
`procdeck down` stops everything.
|
|
31
|
+
`procdeck down` stops everything. macOS or Linux.
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
procdeck is a single native binary with the web UI inside — nothing else to
|
|
36
|
+
install, no runtime to match. Pick the channel that fits:
|
|
34
37
|
|
|
35
38
|
```sh
|
|
36
|
-
|
|
39
|
+
brew install kondaurovDev/tap/procdeck # macOS, with shell completions
|
|
40
|
+
curl -fsSL https://raw.githubusercontent.com/kondaurovDev/procdeck/main/install.sh | sh
|
|
41
|
+
pnpm add -D procdeck # npm i -D procdeck · bun add -d procdeck — pins the version for the whole team
|
|
42
|
+
go install github.com/kondaurovDev/procdeck@latest
|
|
37
43
|
```
|
|
38
44
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
>
|
|
44
|
-
>
|
|
45
|
+
or a tarball, `.deb` or `.rpm` for your platform from the
|
|
46
|
+
[releases](https://github.com/kondaurovDev/procdeck/releases). On Windows,
|
|
47
|
+
install inside WSL.
|
|
48
|
+
|
|
49
|
+
> **What npm installs.** A small launcher, plus exactly one
|
|
50
|
+
> `@procdeck/<os>-<arch>` package with the binary for your machine — picked by
|
|
51
|
+
> the package manager through `optionalDependencies`. No install script runs,
|
|
52
|
+
> so there is no `pnpm approve-builds` detour and nothing compiles. Node runs
|
|
53
|
+
> the launcher; the deck itself does not need it.
|
|
45
54
|
|
|
46
55
|
## What you get
|
|
47
56
|
|
|
@@ -157,31 +166,37 @@ for a devcontainer or a VM. No telemetry, no service worker.
|
|
|
157
166
|
}
|
|
158
167
|
```
|
|
159
168
|
|
|
160
|
-
|
|
161
|
-
|
|
169
|
+
Comments and trailing commas are welcome — name the file
|
|
170
|
+
`procdeck.config.jsonc` if your editor wants a hint. Unknown keys are errors,
|
|
171
|
+
so a typo never silently does nothing. `"envFile": ".env"` hands every proc the
|
|
172
|
+
variables of a dotenv file. Full field reference:
|
|
173
|
+
[docs/config.md](https://github.com/kondaurovDev/procdeck/blob/main/docs/config.md).
|
|
174
|
+
|
|
175
|
+
## Upgrading from 1.x
|
|
162
176
|
|
|
163
|
-
|
|
164
|
-
|
|
177
|
+
2.0 is the same tool rewritten in Go — the CLI verbs, their flags and `--json`
|
|
178
|
+
shapes, the MCP tools and the addresses stay. What changes:
|
|
165
179
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
180
|
+
- **Configs are JSON.** A `procdeck.config.ts` becomes `procdeck.config.jsonc`:
|
|
181
|
+
quote the keys, drop the `import` and `defineConfig(…)`, keep the comments.
|
|
182
|
+
- **Regexes are RE2** (Go's): no lookaround or backreferences.
|
|
183
|
+
- **Unknown config keys are errors.**
|
|
184
|
+
- **No `node --env-file` wrapper** needed — use `envFile` in the config.
|
|
170
185
|
|
|
171
|
-
|
|
172
|
-
|
|
186
|
+
A 1.x deck and the 2.0 CLI understand each other (same registry, same API), so
|
|
187
|
+
`procdeck restart` moves a running deck over.
|
|
173
188
|
|
|
174
189
|
## Try the example
|
|
175
190
|
|
|
176
|
-
In a clone of this repo:
|
|
191
|
+
In a clone of this repo, with Go ≥ 1.26 and pnpm:
|
|
177
192
|
|
|
178
193
|
```sh
|
|
179
194
|
pnpm install
|
|
180
|
-
pnpm dev # builds the UI,
|
|
195
|
+
pnpm dev # builds the UI, embeds it, runs the example stack on the Go procdeck
|
|
181
196
|
```
|
|
182
197
|
|
|
183
|
-
Then open <http://localhost:
|
|
184
|
-
<http://web.localhost:
|
|
198
|
+
Then open <http://localhost:4840> for the panes, and
|
|
199
|
+
<http://web.localhost:4840> / <http://api.localhost:4840> — the example's
|
|
185
200
|
servers found each other, and their own ports, entirely through `${port}`
|
|
186
201
|
templates. See [`example/`](https://github.com/kondaurovDev/procdeck/tree/main/example).
|
|
187
202
|
|
|
@@ -197,7 +212,7 @@ templates. See [`example/`](https://github.com/kondaurovDev/procdeck/tree/main/e
|
|
|
197
212
|
|
|
198
213
|
## Status
|
|
199
214
|
|
|
200
|
-
**macOS and Linux.** Port discovery asks the OS through `
|
|
215
|
+
**macOS and Linux.** Port discovery asks the OS through `ps` + `lsof`, and
|
|
201
216
|
a whole-tree restart signals the process group (`kill(-pid)`) — both POSIX.
|
|
202
217
|
Windows works through WSL, not natively.
|
|
203
218
|
|