Metadata-Version: 2.4
Name: proctide
Version: 0.1.0
Summary: Run every process in your Procfile at once in one terminal, each output line prefixed with a colored process name; a clean Ctrl-C shuts them all down. Like foreman/overmind but zero-dependency and dual-runtime — no Ruby, no tmux.
Author: yyfjj
License: MIT
Project-URL: Homepage, https://github.com/jjdoor/proctide-py
Project-URL: Repository, https://github.com/jjdoor/proctide-py
Project-URL: Issues, https://github.com/jjdoor/proctide-py/issues
Keywords: procfile,foreman,overmind,process,process-manager,concurrent,runner,dev,devtools,cli,monorepo
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX
Classifier: Operating System :: MacOS
Classifier: Operating System :: Unix
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# proctide

**Run every process in your `Procfile` together, in one terminal.** Each output
line is prefixed with a colored process name so you can tell `web` from `worker`
from `css` at a glance — and a single Ctrl-C takes the whole lot down cleanly.

Zero dependencies (pure Python stdlib). No Ruby. No tmux.

```bash
pipx run proctide
```

```
web    | listening on http://localhost:3000
worker | polling jobs queue…
css    | rebuilt app.css in 42ms
web    | GET /  200  11ms
worker | processed job #1841
^C
proctide: SIGINT received, shutting down…
web    | exited (signal SIGTERM)
worker | exited (signal SIGTERM)
css    | exited (signal SIGTERM)
```

## Why another Procfile runner?

[foreman](https://github.com/ddollar/foreman) is the classic, but it's a **Ruby
gem** — one more runtime to install on a Node/Python box.
[overmind](https://github.com/DarthSim/overmind) is great but needs **tmux**.
[`concurrently`](https://www.npmjs.com/package/concurrently) is excellent and
mature — but it's an npm dependency, and you spell your processes out on the
command line instead of in a checked-in `Procfile`.

`proctide` is the small middle ground: a real `Procfile`, prefixed interleaved
output, clean shutdown — and **nothing to install but the tool itself**, on
whichever of Python or Node you already have.

## Install

```bash
pipx run proctide          # no install, run on demand
pip install proctide       # or install the `proctide` command
```

There's an identical Node build too: `npx proctide` / `npm i -g proctide`
(see [proctide](https://github.com/jjdoor/proctide)). Both ports parse the same
Procfile and print the same prefix format — their pure cores are tested against
the same vectors.

## The Procfile

One process per line, `name: command`. Blank lines and `#` comments are ignored.
The command runs through your shell, so pipes, `&&`, env vars, and globs all work.

```Procfile
# Procfile
web:    python server.py
worker: python worker.py
css:    npx tailwindcss -i app.css -o public/app.css --watch
```

```bash
proctide                 # runs ./Procfile
proctide -f Procfile.dev # or point somewhere else
```

## Usage

```bash
proctide [options]
```

| Option | Description |
| --- | --- |
| `-f, --file <path>` | Procfile to read (default: `./Procfile`). |
| `--no-color` | Disable the colored name prefixes (e.g. when piping to a file). |
| `-h, --help` | Show help. |
| `-v, --version` | Print version. |

### Behavior

- **Concurrent.** Every process starts at once; their stdout *and* stderr are
  merged into one stream, each line tagged `name | …`. The name column is padded
  to the longest process name so the `|` separators line up.
- **Clean shutdown.** Ctrl-C (SIGINT) — or SIGTERM — forwards SIGTERM to every
  child's process group, waits briefly, then exits. A child that ignores SIGTERM
  gets SIGKILL as a backstop.
- **One dies, all stop.** If any process exits on its own, the rest are shut down
  too — that's the foreman/overmind contract for a dev stack.
- **Honest exit code.** `proctide` exits non-zero if any child exited non-zero,
  so it behaves in CI and `Makefile`s.

## Design notes

- **A pure core, an IO shell.** `parse_procfile`, `color_for`, and `prefix_line`
  are pure functions — no spawn, no clock, no signals — which is what lets the
  Python and Node ports be proven identical against one shared vector table. The
  spawning/streaming/signal-forwarding lives in a separate runner module and is
  covered by an integration smoke test instead (live output is nondeterministic).
- **Prefixes align by construction.** The name is padded to `width` *before* any
  ANSI color is applied, so the escape codes never throw off the columns.
- **Zero dependencies.** Python uses `subprocess.Popen` + one reader thread per
  process behind a shared lock so prefixed lines never interleave mid-line; Node
  uses `child_process.spawn` + `readline`.

## License

MIT
