This guide is the practical "how to operate abstack" document for local development, CI pipelines, and lightweight Docker runtime workflows.
Build the binary:
cmake --preset native
cmake --build --preset nativeThe resulting executable is typically:
./build/native/abstack
Runtime dependencies by command family:
build,sync,fmt: no Docker dependency.compose,docker: require Docker CLI and daemon access.tui: requires build with curses support (ABSTACK_ENABLE_TUI=ON).- CLI callbacks log to
.abstack/logs/abstack-cli.log.
abstack is compiler-first:
- Input is
.abssource. - Output is generated artifacts (
Dockerfile.<service>, compose YAML). - Runtime helpers (
compose,docker) are optional wrappers, not orchestration replacements.
When to use each command:
build: one source file.sync: many source files from a directory tree with regex selection.fmt: canonical source formatting.compose: optionally generate, then rundocker compose.docker: minimal container inspection/operations helper.stdlib: list bundled stdlib profiles.tui: minimal interactive entrypoint forbuild/fmt/sync.
- Parsing is strict: unknown options fail immediately.
- Regex arguments use C++ regex syntax.
- Paths may be relative or absolute.
- Errors are surfaced as non-zero exit with explicit messages.
- Backward compatibility is preserved:
abstack <file.abs> ...maps toabstack build <file.abs> .... - Stdlib linkage is explicit and opt-in through
--stdlib-profile. - Spinner feedback is shown for wait-heavy non-interactive shell calls (disable with
ABSTACK_NO_SPINNER=1).
abstack is built and tested natively on Windows in CI.
Practical notes:
- Presets use Ninja for cross-platform consistency.
- Docker helper commands use Windows-safe shell quoting.
- Optional TUI may remain unavailable if curses support is not present.
Default generation behavior:
- Dockerfiles are emitted under
generated/asDockerfile.<service>. - Compose is emitted as
generated/docker-compose.generated.yml.
Path controls:
--out-dir <dir>changes Dockerfile output base and default compose location.--compose-file <file>sets explicit compose output path.
Cleanup behavior:
--cleanremoves existingDockerfile.*in--out-dir.--cleanalso removes the default compose output file in--out-dirwhen--compose-fileis not explicitly set.
Syntax:
abstack build <file.abs> [options]Options:
--out-dir <dir>--compose-file <file>--service-regex <pattern>--clean--dry-run--stdlib-profile <name>--list-stdlib-profiles
Typical usage:
abstack build samples/unified.abs --out-dir generated --cleanSelective service generation:
abstack build samples/unified.abs --service-regex '^(api|db)$'Validation-only plus compose preview:
abstack build samples/unified.abs --dry-run
abstack build samples/stdlib_stack.abs --stdlib-profile default --out-dir generated --clean--dry-run writes no files and prints compose output to stdout after successful parse/validate/lower.
Syntax:
abstack sync --input-dir <dir> [options]Options:
--input-dir <dir>(required)--file-regex <pattern>(default.*\\.abs$)--service-regex <pattern>--out-dir <dir>--compose-file <file>--clean--stdlib-profile <name>--list-stdlib-profiles
Processing behavior:
- Files are discovered recursively and sorted.
- Each source file is namespaced to avoid template/service name collisions.
depends_onentries inside each file are remapped to the namespaced service IDs.- Service filtering matches both namespaced and original base service names.
Example:
abstack sync \
--input-dir samples \
--file-regex '.*\\.abs$' \
--service-regex '^(api|worker|db)$' \
--out-dir generated \
--cleanThe bundled stdlib is linked before semantic validation/lowering only when explicitly requested.
List available profiles:
abstack stdlib list
abstack build --list-stdlib-profilesEnable stdlib in generation commands:
abstack build samples/stdlib_stack.abs --stdlib-profile default --out-dir generated
abstack sync --input-dir samples --stdlib-profile core-v1 --out-dir generatedCurrent bundled profile aliases:
core-v1default(alias tocore-v1)
Syntax:
abstack fmt <file-or-dir> [options]Options:
--file-regex <pattern>(directory mode only, default.*\\.abs$)--check--stdout(single-file mode only)
Behavior:
- Formatting is semantic/canonical (AST-based), not token-preserving.
- Comments are currently not preserved.
- In
--checkmode, exit status is1if any file requires formatting.
Examples:
abstack fmt samples/unified.abs
abstack fmt samples --file-regex '.*\\.abs$' --check
abstack fmt samples/unified.abs --stdoutSyntax:
abstack compose [generation options] -- <docker compose args...>Generation choices:
--abs <file.abs>for single-file generation.--input-dir <dir>plus sync options for multi-file generation.- Omit both to run against an existing compose file.
--stdlib-profile <name>is supported when generation inputs are present.
Important rules:
--is required before compose arguments.--absand--input-dirare mutually exclusive.- If generation options are omitted, compose file must already exist.
--stdlib-profilerequires--absor--input-dirin compose mode.
Examples:
abstack compose --abs samples/unified.abs -- up -d
abstack compose --abs samples/stdlib_stack.abs --stdlib-profile default -- up -d
abstack compose --compose-file generated/docker-compose.generated.yml -- ps
abstack compose --input-dir samples --file-regex '.*\\.abs$' -- downGoal: provide lightweight container operations directly in abstack while staying close to native Docker behavior.
Subcommands:
abstack docker ls [--all] [--filter <regex>] [--watch <seconds>]abstack docker inspect <container>abstack docker logs <container> [--tail <lines>] [--follow]abstack docker shell <container> [--shell <command>] [--user <user>]abstack docker stats [--all]
Examples:
abstack docker ls --all --filter 'api|db'
abstack docker ls --watch 2
abstack docker inspect api-container
abstack docker logs api-container --tail 300 --follow
abstack docker shell api-container --shell bash --user root
abstack docker stats --allScope boundaries:
- This is not a replacement for Docker Desktop or a full orchestration UI.
- It is intended for fast terminal-native inspection and debugging loops.
Run:
abstack tuiAvailability:
- Present only when built with curses support.
- Otherwise exits with a clear enablement hint.
Current key actions:
b: build one filef: format one files: sync one directoryq: quit
Common patterns:
- All abs files:
.*\\.abs$ - Only under a domain folder:
^services/payments/.*\\.abs$ - Core service names:
^(api|worker|db)$ - Match suffixed variants:
api(-.*)?$
Remember:
- Escape
\for shell when needed. - Test patterns on small scopes first.
syncfile matching is evaluated against source paths relative to--input-dir.
Minimal validation pipeline:
abstack fmt samples --file-regex '.*\\.abs$' --check
abstack build samples/unified.abs --out-dir generated --clean
abstack build samples/stdlib_stack.abs --stdlib-profile default --out-dir generated --cleanMonorepo-style generation:
abstack sync --input-dir samples --file-regex '.*\\.abs$' --out-dir generated --cleanCompose smoke workflow (when Docker is available in CI):
abstack compose --abs samples/unified.abs -- config- Invalid regex: command reports which option/pattern failed.
- Missing required args: command reports missing option/value.
- No service match: check
--service-regexand namespacing assumptions. - Missing compose file: generate via
build/syncor provide--compose-file. - Docker access errors: confirm daemon availability and user permissions.
- Unknown stdlib profile: run
abstack stdlib listor--list-stdlib-profiles. - Shell command visibility and callback history: inspect
.abstack/logs/abstack-cli.log.
- "I changed one file and want artifacts now":
build. - "I have many
.absfiles and want one merged output":sync. - "I want bundled reusable templates without local declarations":
--stdlib-profile. - "I need style consistency checks":
fmt --check. - "I want compose lifecycle from generated artifacts":
compose. - "I need fast container inspection/logs/shell":
docker.