Build orchestration, semantic versioning, and local infrastructure management for repository workspaces.
octo build · octo bump · octo up · octo down · octo status
Managing a workspace with multiple repositories, microservices and shared packages means dealing with:
- Manual build ordering — services depend on shared packages that must be built first
- Version drift — bumping a shared SDK requires updating every consumer by hand
- Infrastructure sprawl — each service has its own
docker-compose.ymlwith overlapping containers
Octo solves all three with a single CLI that understands your dependency graph.
# Install globally
npm install -g octo-dev
# Initialize in your workspace
octo init
# Build everything in dependency order
octo build
# Bump a shared package and propagate
octo bump @myorg/shared-lib minor --install
# Spin up all infrastructure
octo up| Tool | Version |
|---|---|
| Node.js | >= 25 |
| Docker | Latest |
| Git | >= 2.x |
| pnpm | >= 11 |
Scans the workspace, discovers services (directories with Dockerfile) and packages, and generates octo.yaml.
octo init # Recursive scan, generates root manifest
octo init --standalone # Current directory onlyDisplays the dependency graph as an indented adjacency list.
$ octo graph
api-gateway
@myorg/shared-lib
@myorg/config
user-service
@myorg/shared-lib
@myorg/shared-lib
@myorg/configOrchestrates Docker builds respecting topological order with maximum parallelism.
octo build # Build all services
octo build api-gateway # Build api-gateway + modified dependencies
octo build --affected # Build only changed services since last buildFeatures:
- Parallel execution limited by available CPUs
- Failure propagation — if a dependency fails, dependents are cancelled
- Independent services continue building
- Real-time progress reporting (updated every 1s)
- Affected detection via file mtime comparison
Increments a package version following Semantic Versioning 2.0.0.
octo bump @myorg/shared-lib # patch (default)
octo bump @myorg/shared-lib minor # minor
octo bump @myorg/shared-lib major # major
octo bump @myorg/shared-lib --install # also runs pnpm install in consumersPipeline:
pre-bump hooks → version increment → build verification → changelog → git commit → propagation
Safety guarantees:
- Uncommitted changes trigger interactive confirmation
- Build failure triggers automatic rollback (byte-for-byte)
- Incompatible version ranges are skipped with conflict report
Merges all docker-compose.yml files and starts infrastructure containers.
octo up # All infrastructure
octo up user-service # Only user-service's dependenciesFeatures:
- Smart merge via local LLM (Phi-4/Ollama) for deduplication
- Deterministic fallback when LLM is unavailable
- Healthcheck polling (60s timeout per container)
- Automatic log tail on healthcheck failure
Stops and removes infrastructure containers.
octo down # Stop containers, preserve volumes
octo down --volumes # Also remove persistent volumesDisplays container state in tabular format.
$ octo status
NAME IMAGE STATE PORT
my-postgres postgres:16 running 5432:5432
my-redis redis:7-alpine running 6379:6379
my-nats nats:2.10 running 4222:4222# Pre-validation hooks (run before build/bump)
hooks:
pre-build:
- name: lint
command: pnpm run lint
- name: type-check
command: pnpm run type-check
pre-bump:
- name: lint
command: pnpm run lint
# Services — directories with Dockerfile
services:
- api-gateway
- user-service
- billing-service
# Shared packages — libraries consumed by services
packages:
- "@myorg/shared-lib"
- "@myorg/config"By default, Octo resolves paths automatically by searching for a directory whose package.json name field matches the entry. To override:
services:
- api-gateway:
path: ./custom/gateway-dirDependencies are resolved automatically from package.json fields (dependencies + devDependencies). Only internal packages (those declared in the manifest) create graph edges. External npm packages are ignored.
| Mode | Trigger | Behavior |
|---|---|---|
| Standalone | Single octo.yaml in CWD |
Operates on local manifest only |
| Aggregated | Multiple octo.yaml in subdirectories |
Discovers all manifests, builds unified dependency graph with cross-project resolution |
In aggregated mode, if a root octo.yaml exists alongside sub-manifests, the root takes priority.
Octo handles SIGINT (Ctrl+C) and SIGTERM gracefully:
- Cancels builds in progress
- Reports partial state (completed / in-progress / pending)
- Exits with code 130
All errors follow a consistent format:
[ERRO] <category>: <descriptive message>
→ <additional context (path, line, column)>
→ <suggested fix when applicable>
| Category | Behavior | Exit Code |
|---|---|---|
| Configuration error | Reports all problems at once | 1 |
| Dependency cycle | Reports cycle path A -> B -> ... -> A |
1 |
| Hook failure | Aborts operation, shows hook output | 1 |
| Build failure | Cancels dependents, continues independents | 1 |
| Version rollback | Automatic on build failure post-bump | 1 |
| Infrastructure timeout | Shows last 20 log lines | 1 |
| Unknown YAML keys | Warning on stderr, continues | 0 |
MIT