publishorder
README.md
# publishorder
You are about to publish a monorepo release and the packages
have to go out in the right sequence: nothing can ship before
the packages it depends on. publishorder takes the package
graph — every package's name and the names of the packages
that must publish before it — and works out the plan:
- **Publish order** — a topological order of the included
packages, computed with Kahn's algorithm. Whenever more
than one package is ready to go, the alphabetically
smallest is picked first, so the same graph always yields
exactly the same order.
- **Levels** — the packages grouped by depth. Level 0 holds
the packages with no included dependencies; every other
package sits at one level above its deepest included
dependency. Everything in a level can publish together,
once the levels below it are out.
- **Changed-set plans** — pass the names of the packages that
changed and the plan covers exactly those packages plus
everything that depends on them, directly or transitively.
The remaining packages are reported as `excluded`, and
dependencies pointing at them do not constrain the order —
they are already published.
- **Cycle detection** — when the included packages cannot be
ordered, publishorder does not error out or guess. It
reports `ok: false` with the exact cycle: a depth-first
search over names and dependencies in ascending order
returns the first cycle it finds as the list of packages
forming it (a package that depends on itself reports as a
one-name cycle). A cycle that lives entirely among excluded
packages does not block a changed-set plan.
The graph must be closed: a dependency or a changed entry
naming a package that was not supplied is a validation
error, as are a missing or duplicate package name and any
wrongly typed field. Errors name the offending path (for
example `packages[1].dependencies[0] references unknown
package "core"`) and no partial plan is produced. The
computation is pure and local: no network, no configuration,
no files read beyond the input you pass in.
## CLI
```bash
npx @reneturcios/publishorder plan --input args.json
npx @reneturcios/publishorder --version
```
`args.json` contains the full arguments object:
```json
{
"packages": [
{ "name": "core", "version": "1.4.1" },
{ "name": "lib", "dependencies": ["core"] },
{ "name": "app", "dependencies": ["lib"] }
],
"changed": ["core"]
}
```
`dependencies` defaults to `[]` per package, `version` is
optional and carried without affecting the order, and
`changed` is optional overall. The plan is printed as JSON:
```json
{
"ok": true,
"order": ["core", "lib", "app"],
"levels": [["core"], ["lib"], ["app"]],
"cycle": [],
"included": ["app", "core", "lib"],
"excluded": []
}
```
Exit codes: `0` on success, `1` on a runtime error (including
an unreadable or invalid input file, or invalid input), `2`
on a usage error.
## MCP server
```bash
npx -y @reneturcios/publishorder mcp
```
MCP client config:
```json
{
"mcpServers": {
"publishorder": {
"command": "npx",
"args": ["-y", "@reneturcios/publishorder", "mcp"]
}
}
}
```
### Tools
- `plan_publish_order` — Plan a monorepo publish order from
the dependency graph.
- `packages` (array, required, at least one) — packages as
`{name, dependencies?, version?}` objects; `name` is
unique across the set and each `dependencies` entry names
another supplied package
- `changed` (array of strings, optional) — when given, the
plan covers these packages plus everything that
transitively depends on them
Returns `{ok, order, levels, cycle, included, excluded}`.
## Docker
```bash
docker run -i ghcr.io/cloudcorprecords/publishorder
docker run --rm -v "$PWD:/w" ghcr.io/cloudcorprecords/publishorder plan --input /w/args.json
```
## Development
```bash
npm install
npm run build # tsc -> dist/
npm test # tsx --test test/*.test.ts (pure local, no network)
npm run dev # run the CLI from source
```
## License
MIT — Copyright (c) 2026 Rene Turcios
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues