Sync, observe, and operate on all your repositories with progress bars, unified filters, and concurrency built in.
Warning
Work in progress. minifleet is under active development. APIs, commands, and behavior may change.
- Features
- Quick Start
- Installation
- Commands
- Fleet directories
- Filters
- Shallow clones (
--shallow) - Plan files (
--plan) - Manifest File
- Configuration
- Concurrency
- Development
- Discover: Fetch repositories from the GitHub API, apply filters, and create or update a
fleet.ymlmanifest. No cloning: separate API concerns from local operations. - Sync: Clone missing repos and pull existing ones based on the
fleet.ymlmanifest. Purely local: no network calls, no token needed, works offline. - Run across repos:
run -- "<command>"executes a shell command in every repository directory (or a filtered subset), with summary or live block output. - Local-first listing:
listshows repos from the manifest when available, with an API fallback when no manifest exists. Output as table or JSON. - Local status dashboard: See the state of all cloned repos: current branch, commits ahead/behind remote, uncommitted changes, stashed changes.
- Cross-repo PR dashboard: List open pull requests across all repos with CI status (success/pending/failure) and review status (approved/changes/pending). Repo list comes from the manifest; PR data from the API.
- Unified filters: Metadata filters (name, topic, language, labels, groups) apply to all commands. Local filters (file existence, git status) apply to
status,run, andfetch. - Plan files: Save filter presets and command options to a YAML file with
--plan. CLI flags override plan values, making it easy to define and reuse common workflows. - Per-directory fleets: A
fleet.ymllives alongside the repos it describes. Known fleets are registered in minifleet's configuration unless instructed otherwise. - Target directory:
--path <dir>sets the working directory for all operations; disables known fleets lookups and overrides--all. - GitHub Enterprise:
--github.host <host>retargets the API and clone URLs at a GHE instance. - Concurrency built-in: Parallel goroutines with a bounded worker pool, context-cancellable.
- Interactive & non-interactive modes: Progress bars and live blocks in terminals (
--interactive auto|always|never); structured slog output with--interactive neveror--json. - Single binary: Written in Go, only
giton$PATHis required.
export GITHUB_TOKEN=ghp_xxxxxxxxxxxxA token with repo scope is needed for private repos; public repos work unauthenticated at lower rate limits.
minifleet init --token ghp_xxxx
# or: minifleet init -s # show current configurationminifleet discover depado
# Filter with flags:
minifleet discover depado --visibility public --language goFetches repositories from the GitHub API, writes fleet.yml to the current directory, and registers the fleet in config.yml. Does not clone anything.
minifleet sync depado
# or, from anywhere if the fleet is known:
minifleet syncRepos listed in fleet.yml are cloned into the fleet directory (~/dev/github.com/depado/<repo>). Existing repos are pulled (git fetch + git rebase --autostash). Ignored repos (see manifest) are skipped. No API calls: works offline.
minifleet status┏━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓
┃ Repo ┃ Behind ┃ Ahead ┃ Dirty ┃ Untracked ┃ Stash ┃ Branch ┃ Remote ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩
│ svc-api │ 0 │ 3 │ no │ 0 │ 0 │ main │ git@github.com:org/a │
│ svc-auth │ 5 │ 0 │ yes │ 2 │ 0 │ dev │ git@github.com:org/b │
│ web-app │ 0 │ 0 │ no │ 0 │ 0 │ main │ git@github.com:org/c │
└──────────────┴────────┴───────┴───────┴───────────┴───────┴────────┴──────────────────────┘
status picks up the fleet in the current directory when invoked inside a fleet directory, or iterates all known fleets otherwise. Branches are highlighted yellow when they differ from the remote default.
minifleet prs depado┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ Repo ┃ Pull Request ┃ Author ┃ CI ┃ Review ┃
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━┩
│ svc-api │ feat: add payment endpoint │ alice │ ✓ │ approved │
│ svc-api │ fix: handle null pointer │ bob │ ✗ │ pending │
└──────────────┴──────────────────────────────┴──────────┴──────────┴────────────┘
go install github.com/depado/minifleet@latestgit clone https://github.com/depado/minifleet.git
cd minifleet
make build
sudo cp minifleet /usr/local/bin/Prerequisites: git on $PATH.
Every command accepts the global flags. Commands that talk to the API or filter repos accept filter flags.
minifleet discover <owner> [flags]
Fetch repositories from the GitHub API, apply filters, and create or update fleet.yml for the given owner. Merges with any existing manifest, preserving user-set fields (labels, protocol, ignored, groups). Does not clone or pull repositories: use sync for that.
Flags:
--no-register do not register this fleet in config (fleets)
--include-regex string regex to match repo names
--exclude-regex string regex to exclude repo names
--include stringArray include repo by exact name (repeatable)
--exclude stringArray exclude repo by exact name (repeatable)
--topic stringArray filter by topic (repeatable)
--include-archived include archived repos
--include-forks include forked repos
--visibility string all, public, private (default: all)
--language string filter by primary language
--label stringArray filter by manifest label (key=value or key, repeatable)
--group string filter by manifest group
Examples:
# Discover all public Go repos
minifleet discover depado --visibility public --language go
# Discover with a custom path
minifleet --path ~/work/depado discover depado
# Refresh an existing manifest (re-fetch, re-apply filters, merge)
minifleet discover depado
# Discover without registering in global config
minifleet discover depado --no-registerRun discover again at any time to pick up new repos or refresh API-tracked metadata (topics, language, archived, etc.).
minifleet fetch [owner] [flags]
Run git fetch origin --prune --tags in every cloned repository. Purely local: no API calls. Without an owner, operates on the fleet in the current directory (or all known fleets). With an owner, fetches repositories for that specific fleet. Accepts local filter flags.
Flags:
--force force fetch, overwriting diverged local tags
--include-regex string regex to match repo names
--exclude-regex string regex to exclude repo names
--include stringArray include repo by exact name (repeatable)
--exclude stringArray exclude repo by exact name (repeatable)
--has-file stringArray require file to exist in repo dir (repeatable, AND)
--dirty only repos with uncommitted changes
--ahead int only repos with at least N ahead commits
--behind int only repos with at least N behind commits
--wip only repos with any uncommitted, unpushed, or unpulled changes
Examples:
# Fetch all repos in the current fleet
minifleet fetch
# Fetch a specific fleet
minifleet fetch depado
# Fetch only repos ahead of remote
minifleet fetch --ahead 1
# Fetch with a target directory
minifleet --path ~/work/depado fetchminifleet sync [owner] [flags]
Clone missing repos and pull existing ones from the fleet.yml manifest. Purely local: no API calls. When no owner is given, syncs the fleet in the current directory (or all known fleets if not in one). Errors if no manifest exists (run discover first).
Fleet directory resolution (first match wins):
--path <dir>: explicit directory override (takes precedence over --all)- Current working directory
fleets[owner]inconfig.yml
After a successful sync, fleets[owner] is updated in config.yml so the fleet is discoverable from any directory.
Examples:
# Sync a single fleet
minifleet sync depado
# Sync all known fleets at once
minifleet sync
# GitHub Enterprise
minifleet --github.host github.example.com sync my-org
# Shallow clones
minifleet --shallow sync depadominifleet list [owner] [flags]
List repositories. Uses the local manifest when available; falls back to fetching from the GitHub API if no manifest exists. Without an owner, lists repos from the fleet in the current directory (or all known fleets). Output as table (default) or JSON.
Flags:
--include-regex string regex to match repo names
--exclude-regex string regex to exclude repo names
--include stringArray include repo by exact name (repeatable)
--exclude stringArray exclude repo by exact name (repeatable)
--topic stringArray filter by topic
--include-archived include archived repos
--include-forks include forked repos
--visibility string all, public, private (default: all)
--language string filter by primary language
--label stringArray filter by manifest label
--group string filter by manifest group
--limit int max repos to list (0 = unlimited, default: 0)
# List from manifest (in a fleet directory)
minifleet list
# List from API fallback (no manifest exists)
minifleet list depado --language go
# JSON output
minifleet list --json | jq '.[] | .name'minifleet status [flags]
Show git status for repos in the fleet. Uses the manifest as the source of truth for which repos to check; falls back to scanning the filesystem if no manifest exists. Operates on the fleet in the current directory when one is present, otherwise iterates all known fleets. Repos not yet cloned are skipped.
Flags:
--include-regex string regex to match repo names
--exclude-regex string regex to exclude repo names
--include stringArray include repo by exact name (repeatable)
--exclude stringArray exclude repo by exact name (repeatable)
--topic stringArray filter by topic (via manifest)
--include-archived include repos flagged as archived in manifest
--include-forks include repos flagged as fork in manifest
--language string filter by language (via manifest)
--label stringArray filter by manifest label
--group string filter by manifest group
--has-file stringArray require file to exist in repo dir (repeatable, AND)
--if string shell command; exit 0 = include repo
--dirty only repos with uncommitted changes
--ahead int only repos with at least N ahead commits
--behind int only repos with at least N behind commits
--wip only repos with any uncommitted, unpushed, or unpulled changes
minifleet prs [owner] [flags]
List open pull requests across repositories with CI and review status. Repo list comes from the manifest when available (API fallback if none exists). PR data is always fetched from the API. Without an owner, shows PRs for the fleet in the current directory (or all known fleets).
Flags:
--state string open, closed, all (default: open)
--author, -a string filter by PR author
--no-draft exclude draft PRs
--include-regex string regex to match repo names
--exclude-regex string regex to exclude repo names
--include stringArray include repo by exact name (repeatable)
--exclude stringArray exclude repo by exact name (repeatable)
--topic stringArray filter by topic
--include-archived include archived repos
--include-forks include forked repos
--visibility string filter by visibility
--language string filter by primary language
--label stringArray filter by manifest label
--group string filter by manifest group
minifleet run -- <command> [flags]
Run a shell command in every local repository directory (or a filtered subset). Uses the manifest as the source of truth; falls back to filesystem scan if none exists. Repos not yet cloned are skipped. Operates on the fleet in the current directory or all known fleets (same discovery as status).
Flags:
--include-regex string regex to match repo names
--exclude-regex string regex to exclude repo names
--include stringArray include repo by exact name (repeatable)
--exclude stringArray exclude repo by exact name (repeatable)
--topic stringArray filter by topic (via manifest)
--include-archived include archived repos
--include-forks include forked repos
--language string filter by primary language (via manifest)
--label stringArray filter by manifest label
--group string filter by manifest group
--has-file stringArray require file to exist in repo dir (repeatable, AND)
--if string shell command; exit 0 = include repo
--dirty only repos with uncommitted changes
--ahead int only repos with at least N ahead commits
--behind int only repos with at least N behind commits
--wip only repos with any uncommitted, unpushed, or unpulled changes
--block-lines int output lines per repo block in live mode (default: 3)
--dry-run print what would run; do not execute
--shell string shell to invoke (default: sh)
--json is a persistent global flag. Use --interactive to control display mode (auto/always/never).
Use -- to separate flags from the command itself.
Examples:
# Run Go tests across the fleet
minifleet run -- "go test ./..."
# Lint only backend repos
minifleet run --group backend -- "make lint"
# Stream output of a build
minifleet run --block-lines 5 --language go -- "make build"
# Cross-repo code search
minifleet run -- "grep -r 'TODO' ."
# Only repos with specific files
minifleet run -H go.mod -H Dockerfile -- "make build"
# Only repos where a dependency check passes
minifleet run --if 'grep -q "go 1.22" go.mod' -- "go vet ./..."
# Dry-run a destructive bulk change
minifleet run --dry-run --include-regex "^old-" -- "rm -f .env.local"
# Load filters and command from a plan file
minifleet run --plan plan.yml
# JSON output
minifleet run --json -- "git rev-parse HEAD"
# Non-interactive (slog output)
minifleet run --interactive never -- "make test"Live block mode (TTY default): when stdout is a terminal, each repo gets a growing block that updates in place:
→ articles
3354578 chore: remove drone config...
26742bf Bump github.com/gin-gonic/gin...
→ bfplus
53c117a chore(deps): update go toolchain...
5ed469d fix(deps): update module...
When a repo finishes, its header flips to ✓ repo (elapsed) (or ✗ exit N repo (elapsed) on failure) and the last --block-lines output lines stay visible underneath. New blocks are appended as repos are picked up. Older blocks scroll off the top when the display exceeds terminal height. In a non-terminal (piped, CI, --interactive never), per-repo status and captured output is written to stderr via slog.
minifleet init [flags]
Write ~/.config/minifleet/config.yml with defaults, or show the current configuration including registered fleets.
Flags:
-t, --token string GitHub personal access token to write
-s, --show print current configuration
A fleet directory is any directory that contains a fleet.yml. It typically also contains the cloned repos it describes, side-by-side. The directory IS the fleet.
~/dev/github.com/depado/
├── fleet.yml ← manifest for the depado fleet
├── articles/ ← cloned repo
├── buoy/ ← cloned repo
├── minifleet/ ← cloned repo
└── ...
config.yml records fleet directories in fleets so commands run from outside a fleet dir can still find them:
fleets:
depado: /home/depado/dev/github.com/depado
work-org: /home/depado/work/github.com/work-orgCommands discover the active fleet(s) in this order:
--path <dir>(explicit override, takes precedence over --all)- The current directory has a
fleet.yml(use it) - all known fleets (iterate)
discover <owner> creates the manifest and registers the fleet in fleets. sync <owner> additionally consults fleets[owner] as a fallback and re-registers the directory on success. Pass --no-register to discover to prevent registration: the fleet will only be found when running from its directory.
Pass --path <dir> to operate on a specific directory as the fleet target, overriding the current-directory and known fleets lookups. When --path is set, --all is ignored:
minifleet --path ~/scratch/my-org discover depado --visibility public
minifleet --path ~/scratch/my-org sync depado
minifleet --path ~/scratch/my-org status
minifleet --path ~/scratch/my-org run -- "git log --oneline -1"All commands treat <dir> as the fleet directory: a fleet.yml is read if present, repos are discovered/scanned directly inside it. discover and sync register the directory in fleets on success (unless --no-register is used).
Filters fall into two categories. Every command that queries the API or filters repos accepts the metadata filters. The local filters are only available on commands that operate on cloned repositories (status, run, fetch).
These filters work against API responses or manifest data, so they apply both online and offline:
| Flag | Type | Behavior |
|---|---|---|
--include-regex |
regex | Match on repo name |
--exclude-regex |
regex | Exclude repos whose name matches (wins over includes) |
--include |
stringArray | Include repo by exact name (repeatable) |
--exclude |
stringArray | Exclude repo by exact name (repeatable, wins over includes) |
--topic |
stringArray | Match if repo has any of the given topics (OR) |
--include-archived |
bool | Include archived repos (excluded by default) |
--include-forks |
bool | Include forked repos (excluded by default) |
--visibility |
string | all (default), public, private — API-only, ignored by local commands |
--language |
string | Match on repo primary language (e.g. go, python) |
--label |
stringArray | Match on manifest labels: tier=1 (exact) or tier (any value). AND across labels. |
--group |
string | Limit to repos in a manifest group |
These inspect the local checkout and are ignored by commands that work against the API:
| Flag | Type | Behavior |
|---|---|---|
--has-file |
stringArray | Include only repos with given file (e.g. go.mod). AND logic. |
--if |
string | Shell command; exit 0 = include, non-zero = exclude. Runs in parallel |
--dirty |
bool | Only repos with uncommitted changes to tracked files |
--ahead |
int | Only repos with at least N ahead commits |
--behind |
int | Only repos with at least N behind commits |
--wip |
bool | Only repos with uncommitted changes, ahead/behind commits, or off-default branch |
sync does not accept filters: it always operates on all repos in the manifest.
Filters compose freely and can also be declared in a plan file.
# Metadata: discover Go services in the backend group
minifleet discover depado --language go --group backend
# Metadata: status of repos with tier=1 label
minifleet status --group backend --label tier=1
# Local: only repos with go.mod and ahead commits
minifleet run -H go.mod --ahead 1 -- "go test ./..."
# Local: check repos with unpushed work
minifleet status --ahead 1--shallow toggles git clone --depth 1 --filter=blob:none for speed:
minifleet --shallow sync depadoShallow clones are smaller and faster but lack full history. They cannot push most commits without unshallowing. Use for one-shots, dashboards, or large fleets where you only need the latest tree. The default (full clone) is recommended for fleets you intend to push from.
Pass --plan / -p <file> to load filters, command options, and fleet targeting from a YAML file instead of (or in addition to) CLI flags. CLI flags override plan values, so you can reuse a plan as a default and tweak it per-run.
Any command that accepts filters supports --plan. Fields unrelated to a command are silently ignored: a plan written for run works with status too (the command and shell fields are ignored).
# Fleet targeting (optional: falls back to context)
fleet: my-org # target a specific fleet from fleets
all: true # operate on all known fleets
json: true # output as JSON
# run-specific (optional: ignored by other commands)
shell: bash # shell to invoke (default: sh)
command: "make test" # command to execute (no -- args needed)
block_lines: 5 # output lines per block in live mode
dry_run: false # print what would run; don't execute
interactive: never # auto, always, never
# Filters (optional: all 15 filter fields are supported)
filters:
include_regex: "^svc-"
exclude_regex: "legacy"
include: [repo1, repo2]
exclude: [repo3]
topics: [go, rust]
include_archived: false
include_forks: false
visibility: public
language: Go
labels: ["tier=1"]
group: backend
has_files: [go.mod, Dockerfile]
if_cmd: "test -f go.mod"
dirty: false# Define a reusable plan
cat > go-checks.yml << 'EOF'
shell: bash
command: "go vet ./... && go build ./... && go test -race -count=1 ./..."
block_lines: 8
filters:
if_cmd: "test -f go.mod"
EOF
# Run it (no CLI args needed: command comes from the plan)
minifleet run --plan go-checks.yml
# Override a filter: only the backend group, not all Go repos
minifleet run --plan go-checks.yml --group backend
# Same plan, dry-run to see what would happen
minifleet run --plan go-checks.yml --dry-run
# Use the same filters with status (command & shell are ignored)
minifleet status --plan go-checks.yml --json
# Plan targeting a specific fleet
minifleet run --plan go-checks.yml # resolves fleet from context
# vs: plan has fleet: "work-org" → targets that fleet specifically--plan <file>is a persistent flag on every command (like--jsonand--all)- The YAML is loaded once in the pre-run hook and stored in context
- For each filter, command option, or fleet targeting field: the plan provides a default that CLI flags can override
cmd.Flags().Changed("flag-name")determines whether the user set the flag: if not, the plan value is used
This makes it easy to define and version-control standard workflows (CI-like checks, lint passes, bulk refactors) without remembering long flag combinations.
A fleet.yml lives at the root of a fleet directory. It is the source of truth for which repos belong to the fleet and carries metadata that GitHub's API doesn't track. Create one with discover and edit it to add groups, labels, protocols, and ignored repos.
minifleet discover depado --visibility publicThen edit the generated fleet.yml:
version: "1"
owner: depado
groups:
backend:
- depado/svc-api
- depado/svc-auth
frontend:
- depado/web-app
repos:
- full_name: depado/svc-api
protocol: ssh
labels:
tier: "1"
language: go
- full_name: depado/web-app
protocol: https
labels:
tier: "2"
- full_name: depado/old-prototype
ignored: true
labels:
status: deprecated| Category | Fields | Owner |
|---|---|---|
| API-tracked | topics, language, archived, fork, private, updated_at |
discover overwrites from API |
| User-set | labels, protocol, ignored |
User: preserved across discover runs |
| User-set | groups |
User: never touched by discover |
Use groups to scope filters:
minifleet status --group backend
minifleet run --group frontend -- "make lint"
minifleet discover depado --group backendEach repo can declare protocol: ssh or protocol: https. sync reads this when cloning. Without a saved protocol, sync tries SSH first and falls back to HTTPS.
Set ignored: true to skip a repo in all bulk operations. Useful for archived or experimental repos you keep locally but don't want synced.
All settings can be set via CLI flags, environment variables, or a config file. Precedence: Flags > Env > Config File > Defaults.
github:
token: "" # GitHub PAT (or use GITHUB_TOKEN env)
host: github.com # Use a custom host for GitHub Enterprise
concurrent: 0 # max concurrent operations (defaults to number of CPUs)
fleets: # owner → directory of registered fleets
depado: /home/depado/dev/github.com/depado
log:
level: info # debug, info, warn, error
format: text # json or text
source: false
color: auto # auto, always, never
interactive: auto # auto, always, never| Key | Env | Default | Description |
|---|---|---|---|
github.token |
GITHUB_TOKEN |
- | GitHub personal access token |
github.host |
MINIFLEET_GITHUB_HOST |
github.com |
GitHub host (GHE: github.example.com) |
path |
MINIFLEET_PATH |
- | Fleet directory override (bypasses known fleets, even with --all) |
concurrent |
MINIFLEET_CONCURRENT |
CPU count | Max concurrent operations |
fleets |
- | - | Map of owner → fleet directory (managed by discover/sync) |
log.level |
MINIFLEET_LOG_LEVEL |
info |
debug, info, warn, error |
log.format |
MINIFLEET_LOG_FORMAT |
text |
json or text |
log.source |
MINIFLEET_LOG_SOURCE |
false |
Include source file in logs |
log.color |
MINIFLEET_LOG_COLOR |
auto |
auto, always, never |
interactive |
MINIFLEET_INTERACTIVE |
auto |
auto, always, never |
Every bulk operation uses the same bounded-goroutine executor. Configure it globally or per-command:
# Clone with 10 concurrent git processes
minifleet --concurrent 10 sync depado
# Fetch PRs with 3 concurrent API calls (staying under secondary rate limits)
minifleet --concurrent 3 prs depado- A bounded goroutine pool processes tasks from a channel.
- Each task runs independently; one failure doesn't block others.
Ctrl+Cstops new tasks but lets in-flight operations complete.- Results are collected as succeeded, skipped, and failed with per-repo error messages.
Rate limits: GitHub's secondary rate limit allows ~100 concurrent requests and ~900 points/minute. For API-heavy commands like prs, keep --concurrent at 5 or lower. For local git operations (sync, status), higher values (10+) are fine: they're I/O-bound.
go mod tidy
make build # compile the binary
make test # run tests with race detector
make lint # run golangci-lint
make dev # run with OTLP enabled
make docker # build Docker image
make release # create a GitHub release via goreleaser
make clean # remove binary and coverage outputminifleet/
├── main.go # Entrypoint
├── cmd/
│ ├── root.go # Setup, config caching via context, command registration
│ ├── conf.go # Conf struct, NewConf, NewLogger (viper-backed)
│ ├── config.go # init command, SaveConf, RegisterFleet, printConfig
│ ├── flags.go # Persistent flag definitions
│ ├── filters.go # Filters struct + Apply: shared by every command
│ ├── plan.go # Plan file (--plan): YAML schema, LoadPlan, ApplyPlan
│ ├── fleet.go # fleetTarget discovery (current dir / fleets / --path), manifestToTasks, reposForTarget
│ ├── discover.go # discover command: API → fleet.yml
│ ├── shared.go # printBulkSummary helper
│ ├── sync.go # clone+pull from manifest; syncFromManifest
│ ├── list.go
│ ├── status.go
│ ├── prs.go
│ ├── run.go # execute shell command across repos + gorich live block display
│ └── version.go
├── internal/
│ ├── provider/ # Provider interface (Host, CloneURL, ListRepos, ...)
│ │ └── github/ # GitHub REST API client
│ ├── git/ # System git operations (clone, pull, status)
│ ├── fleet/ # Executor (bounded concurrency) + Scanner (flat)
│ ├── manifest/ # Single-owner YAML manifest (load/save/merge/generate)
│ └── ui/ # gorich table helpers
- Local-first: repos live next to
fleet.yml; the directory IS the fleet. No central registry needed. - API / local separation:
discovertalks to the API;sync,status, andrunare purely local. The manifest is the explicit bridge. - Discoverable:
fleetsinconfig.ymllets commands run from anywhere; the current directory is checked first. - DRY: every command is short. Filters, executor, and discovery are shared via
manifestToTasksandreposForTarget. - LEAN: one interface (
Provider) for platform abstraction; function types elsewhere. - No global state: configuration flows from
PersistentPreRunE→ context → commandRunE. - Concurrency by default: the
Executorhandles parallelism for every command. - Continue on error: one repo failing never aborts the whole operation.
make build
./minifleet version
# Build: 9a3b2c1
# Version: 0.1.0-dev
# Build Date: 2026-07-12T08:54:45ZMIT: see LICENSE.
