@super-repo/cli
v0.2.0
Published
CLI tool to link external repos via git clone with optional Claude API summaries
Maintainers
Readme
@super-repo/cli
super — CLI for linking external repos via git clone into a .super/ folder, running commands across the stack, and shipping properly-formatted Conventional Commits across every repo at once.
Install
pnpm add -D @super-repo/cli
# Or globally:
pnpm add -g @super-repo/cliInstalling @super-repo/cli exposes three bins on your PATH:
| Bin | What it runs |
| ------- | ---------------------------------------------------------------------------------- |
| super | The cross-repo CLI itself (this package). |
| rune | The @super-repo/rune script orchestrator — equivalent to super rune .... |
| czar | The @super-repo/czar Conventional Commits CLI — equivalent to super czar .... |
So super rune build, rune build, and pnpm exec rune build all do the same thing. The cli ships rune and czar as bundled bin shims — you don't need to install @super-repo/rune or @super-repo/czar separately. If you do install them standalone, the bins resolve to whichever copy your package manager links last.
Commands
| Command | Purpose |
| ---------------------- | ------------------------------------------------------------- |
| super init | Set up super.config.ts in the current directory |
| super pull | Clone or pull all configured repos |
| super status | Show repo states |
| super list | List configured repos by type |
| super run <name> | Run a configured command across stack repos |
| super dev | build | test | lint | Aliases for the common run commands |
| super commit -m | Validate, commit, and push a Conventional Commits message |
| super summary | Generate AI summaries of linked repos |
| super factory <sub> | Autonomous loop (run, status, backlog, propose, onboard, show) |
super commit
super commit is how you ship one structured commit across every stack repo at once. Under the hood it uses @super-repo/czar for parsing and validation — you don't need to install czar separately.
Flow
- Validate the message via czar's parser + validator. Errors abort; warnings are printed (and abort under
--strict). - Reformat to canonical form (whitespace collapsed, trailing newlines normalized).
- Per stack repo: stage all changes, commit with the canonical message, push the current branch to
origin. - Report a per-repo summary:
pushed,committed,skipped(no changes / not cloned), orfailed.
Usage
super commit -m "feat(auth): rotate session tokens"
super commit -m "fix(api)!: drop deprecated /v1 endpoints"
super commit --no-push -m "chore: bump deps"
super commit --filter api,web -m "refactor: extract shared auth"
super commit --strict -m "feat: enforce style" # warnings become errors
super commit --allow-empty -m "chore: tag release"Wire into package.json
{
"scripts": {
"commit": "super commit -m",
"commit:strict": "super commit --strict -m",
"release:tag": "super commit --allow-empty -m"
}
}pnpm commit "feat(auth): rotate session tokens"Flags
| Flag | Default | Description |
| ---------------- | ------- | ------------------------------------------------------------ |
| -m, --message | — | Conventional Commits message (required) |
| --filter | all | Comma-separated repo names to include |
| --push | true | Push after commit (use --no-push to skip) |
| --allow-empty | false | Include repos with no changes (commits with --allow-empty) |
| --strict | false | Treat validation warnings as errors |
Conventional Commits format
<type>[(<scope>)][!]: <description>
[<body>]
[<footer-key>: <footer-value>]<type> is one of: feat, fix, docs, style, refactor, perf, test, chore, build, ci, revert. The ! after type/scope marks a breaking change. See the czar README for the full validation rules.
Programmatic API
The cli package re-exports czar's data layer so you can validate / format messages without depending on @super-repo/czar directly:
import {
formatCommitMessage,
parseCommitMessage,
validateCommitMessage,
type CommitMessage,
} from '@super-repo/cli'Plus the git, catalog, vault, and run primitives — see src/index.ts for the full surface.
Subpath exports
The cli also re-exports each sibling package's full surface under a dedicated subpath. This is the cleanest way to use a sibling's defineConfig without a second dependency:
| Subpath | What it re-exports |
| ----------------------------- | ----------------------------------------------------------- |
| @super-repo/cli/czar | Everything from @super-repo/czar (incl. defineConfig) |
| @super-repo/cli/rune | Everything from @super-repo/rune (incl. defineConfig) |
| @super-repo/cli/factory | Everything from @super-repo/factory (state, runLoop, etc.) |
Use a sibling's defineConfig from anywhere just by importing through the cli:
// czar.config.ts
import { defineConfig } from '@super-repo/cli/czar'
export default defineConfig({
shortcuts: [
{ key: 'g', label: 'quick chore', message: 'chore: quick commit' },
],
})// rune.config.ts
import { defineConfig } from '@super-repo/cli/rune'
export default defineConfig({
scripts: {
build: 'tsc -b',
test: 'vitest run',
},
})The cli's own defineConfig (for super.config.ts) lives at the root export — import { defineConfig } from '@super-repo/cli' — and is unchanged.
Global flags
| Flag | Description |
| ---------------- | ---------------------------------------------------- |
| -c, --config | Path to config file (default: super.config.ts) |
| -d, --dir | Override output directory for cloned repos |
| -v, --verbose | Show verbose output |
| --version | Print version |
Config
super.config.ts (or .js/.mjs) at the project root:
import { defineConfig } from '@super-repo/cli'
export default defineConfig({
outputDir: '.super',
repos: [
// Cloned: super manages the checkout under .super/<name>
{ name: 'client', url: 'https://github.com/org/client.git', branch: 'main', type: 'stack' },
// Linked: existing local checkout used in place — no clone
{ name: 'core', path: '~/work/core', type: 'stack' },
],
summary: { model: 'claude-sonnet-4-20250514' },
})Linked repos
Each entry in repos[] declares either url (cloned to <outputDir>/<name>) or path (existing local checkout, used in place). Mutually exclusive.
path accepts:
- Absolute paths (
/Users/me/work/core) ~/...(expanded viaos.homedir())- Relative paths (resolved against the project root)
Linked repos appear with a [linked] tag in super status and super list. All commands (status, commit, factory, run, script) treat linked and cloned repos identically — they just read/edit in place instead of from .super/.
Config discovery
Super resolves its config in this order:
-c <path>if passed on the command line.super.config.{ts,js,mjs}in the current working directory.- The closest
package.jsonwalking up from cwd — read itssuperfield.
The package.json fallback accepts three shapes (matching czar and rune):
// (a) Single config file
{ "super": { "config": "./super.config.ts" } }
// (b) Array of config files — loaded in order, merged left-to-right
// (later overlays earlier; repos merged by name; each entry may have its own `extends`)
{ "super": { "config": ["./shared/base.config.ts", "./local/overrides.ts"] } }
// (c) Inline config (with optional `extends`, resolved relative to package.json)
{
"super": {
"extends": "./shared/base.config.ts",
"outputDir": ".linked",
"repos": [{ "name": "core", "path": "~/work/core", "type": "stack" }]
}
}Because the cli wraps czar and rune (proxied via super czar / super rune), a single package.json can hold all three blocks side-by-side — one canonical place for super, czar, and rune config:
{
"name": "my-app",
"super": { "outputDir": ".super", "repos": [/* … */] },
"czar": { "shortcuts": [/* … */] },
"rune": { "scripts": { "build": "tsc -b", "test": "vitest run" } }
}Each tool walks up to find this same package.json and reads its own field. They're independent — adding one doesn't pollute the others.
Extending configs
Any super config (file or package.json inline) can declare an extends field. Relative paths resolve against the config file's directory (or package.json's directory for inline blocks). Pass a single path or an array; later overlays earlier.
import { defineConfig } from '@super-repo/cli'
export default defineConfig({
extends: './shared/base.config.ts',
// or: extends: ['./shared/base.config.ts', './local/overrides.ts'],
outputDir: '.local',
repos: [
{ name: 'extra', url: 'https://github.com/org/extra.git', type: 'stack' },
],
})Merge semantics: repos are keyed by name (overlay replaces same-named base entries; novel names appended); summary and commands shallow-merged; outputDir last-defined wins. Circular extends chains throw ConfigError.
