diff --git a/README.md b/README.md index 971e44c..b0d677e 100644 --- a/README.md +++ b/README.md @@ -2,30 +2,31 @@ [![CI](https://github.com/AniTrend/stackctl/actions/workflows/ci.yml/badge.svg)](https://github.com/AniTrend/stackctl/actions/workflows/ci.yml) -A Deno-powered CLI for managing local Docker Compose stacks across multi-service repositories, with config-driven profiles, overrides, secrets, and render pipelines. +A Deno-powered CLI for managing local Docker Compose stacks across multi-service repositories, with +config-driven profiles, overrides, secrets, and render pipelines. -Status: **Active development** -- 14 of 15 commands implemented (see table below). +Status: **Active development** -- 14 top-level commands implemented (see table below). --- ## Commands -| Command | Status | Description | -|---|---|---| -| `stackctl init` | Implemented | Generate commented `.stackctl` config | -| `stackctl generate` | Implemented | Generate `stacks/*.yml` from per-service sources | -| `stackctl render` | Implemented | Resolve `${VAR}` placeholders in stack files | -| `stackctl up` | Implemented | Deploy stacks to Docker Swarm | -| `stackctl down` | Implemented | Tear down stacks | -| `stackctl status` | Implemented | Show service status | -| `stackctl logs` | Implemented | Follow service logs | -| `stackctl sync` | Implemented | Validate generated stacks match committed files (CI drift detection) | -| `stackctl doctor` | Implemented | Check system and project health | -| `stackctl reload` | Implemented | Re-render and reconcile without teardown | -| `stackctl secrets` | Implemented | Encrypt/decrypt/deploy/clean/check with SOPS+age | -| `stackctl env` | Implemented | Scaffold `.env` files from examples | -| `stackctl plan` | Implemented | Dry-run summary of all operations | -| `stackctl completions` | Implemented | Generate shell completions (bash/zsh/fish) | +| Command | Status | Description | +| ---------------------- | ----------- | -------------------------------------------------------------------- | +| `stackctl init` | Implemented | Generate commented `.stackctl` config | +| `stackctl generate` | Implemented | Generate `stacks/*.yml` from per-service sources | +| `stackctl render` | Implemented | Resolve `${VAR}` placeholders in stack files | +| `stackctl up` | Implemented | Deploy stacks to Docker Swarm | +| `stackctl down` | Implemented | Tear down stacks | +| `stackctl status` | Implemented | Show service status | +| `stackctl logs` | Implemented | Follow service logs | +| `stackctl sync` | Implemented | Validate generated stacks match committed files (CI drift detection) | +| `stackctl doctor` | Implemented | Check system and project health | +| `stackctl reload` | Implemented | Re-render and reconcile without teardown | +| `stackctl secrets` | Implemented | Encrypt/decrypt/deploy/clean/check with SOPS+age | +| `stackctl env` | Implemented | Scaffold `.env` files from examples | +| `stackctl plan` | Implemented | Dry-run summary of all operations | +| `stackctl completions` | Implemented | Generate shell completions (bash/zsh/fish) | Override merging is integrated into `generate`, `render`, and `up` via the `--override` flag. @@ -45,14 +46,15 @@ stackctl init stackctl generate # See what would happen -stackctl plan +stackctl plan all ``` --- ## Features -- Config-driven profiles with layered overrides (`.stackctl`, `.stackctl.`, `.stackctl.local`) +- Config-driven profiles with layered overrides (`.stackctl`, `.stackctl.`, + `.stackctl.local`) - SOPS + age encrypted secrets management - `${VAR}` render pipeline with service-local env resolution - Docker Swarm deploy with dry-run planning @@ -61,23 +63,38 @@ stackctl plan ### Secrets Subcommands -| Subcommand | Description | -|---|---| -| `encrypt` | Encrypt `.env` files using SOPS + age | -| `decrypt` | Decrypt `.env.enc` files back to plaintext | -| `deploy` | Decrypt env files and deploy stacks | -| `clean` | Remove decrypted `.env` files securely (shred + rm) | -| `check` | Check secrets tooling availability (sops, age) | +| Subcommand | Description | +| ---------- | --------------------------------------------------- | +| `encrypt` | Encrypt `.env` files using SOPS + age | +| `decrypt` | Decrypt `.env.enc` files back to plaintext | +| `deploy` | Decrypt env files and deploy stacks | +| `clean` | Remove decrypted `.env` files securely (shred + rm) | +| `check` | Check secrets tooling availability (sops, age) | ### Env Subcommands -| Subcommand | Description | -|---|---| -| `list` | List `.env` files with status (present/missing/outdated) | -| `create` | Create `.env` from `.env.example` | -| `diff` | Compare `.env` against `.env.example` | -| `materialize` | Copy profile-specific env to `.env` | -| `audit` | Check for plaintext `.env` files with encrypted counterparts | +| Subcommand | Description | +| ------------- | ------------------------------------------------------------ | +| `list` | List `.env` files with status (present/missing/outdated) | +| `create` | Create `.env` from `.env.example` | +| `diff` | Compare `.env` against `.env.example` | +| `materialize` | Copy profile-specific env to `.env` | +| `audit` | Check for plaintext `.env` files with encrypted counterparts | + +## AI agent skill + +Agents can install the `stackctl-cli` skill for source-valid stackctl CLI guidance: + +```bash +npx skills add anitrend/stackctl --skill stackctl-cli +npx skills add anitrend/stackctl --skill stackctl-cli -g -y +``` + +This installs only the AI agent skill. It does not install the `stackctl` CLI, add runtime +dependencies, or make this repository a Node or npm project. `stackctl` remains a Deno 2.x project +with dependencies resolved from JSR. + +Restart or reload OpenCode after installing new skills so the skill is discovered. ## GitHub Actions diff --git a/skills/stackctl-cli/SKILL.md b/skills/stackctl-cli/SKILL.md new file mode 100644 index 0000000..4d97ef8 --- /dev/null +++ b/skills/stackctl-cli/SKILL.md @@ -0,0 +1,41 @@ +--- +name: stackctl-cli +description: Use this skill when helping agents answer stackctl CLI usage questions, choose source-valid stackctl commands, or avoid stale documented examples. +--- + +# stackctl CLI + +Use this skill when a task involves the `stackctl` command line interface, its install context, +command behavior, flags, examples, or agent-facing guidance. + +## Ground rules + +- Treat `src/cli/mod.ts` as authoritative for commands, arguments, flags, and behavior. +- If a command, flag, install mode, workflow, or Homebrew behavior is not verified in source or + accepted research, say it is unknown or check the source. +- Do not invent aliases, planned commands, positional arguments, deployment workflows, or Homebrew + post-install behavior. +- This is a Deno 2.x project published as `@anitrend/stackctl`. Do not treat it as a Node or npm + project. + +## Hard CLI facts + +- `sync` is drift validation only. Do not describe it as deploy. +- Do not show bare `stackctl plan`. Use an operation such as `stackctl plan all` or + `stackctl plan up`. +- `up` and `down` select stacks with `--stacks`, not positional stack names. +- `secrets deploy` accepts positional stack names. +- `logs` accepts positional service names and also supports `--stacks`. +- `doctor --fix-volumes` currently reports a stub check, not an implemented repair. +- Homebrew post-install messaging is not implemented in this repository. + +## Quick command map + +- Setup and generation: `init`, `generate`, `render`, `plan `. +- Stack lifecycle: `up`, `down`, `reload`, `status`, `logs`, `sync`, `doctor`. +- Secrets: `secrets encrypt`, `decrypt`, `deploy`, `clean`, `check`. +- Env files: `env list`, `create`, `diff`, `materialize`, `audit`. +- Shell integration: `completions`. + +For full command facts, read `references/commands.md`. For source hierarchy, runtime facts, and +known stale docs, read `references/truth-model.md`. diff --git a/skills/stackctl-cli/references/commands.md b/skills/stackctl-cli/references/commands.md new file mode 100644 index 0000000..4fb5762 --- /dev/null +++ b/skills/stackctl-cli/references/commands.md @@ -0,0 +1,98 @@ +# stackctl command reference + +This reference is based on `src/cli/mod.ts`. When this file conflicts with source, use source and +update the skill. + +## Global command + +| Command | Description | Options | +| ---------- | -------------------------------------- | ---------------------------- | +| `stackctl` | Shows help when no subcommand matches. | `--debug`, `--config ` | + +## Top-level commands + +| Command | Arguments | Description | Options and caveats | +| ---------------------- | --------------------------------------- | -------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `stackctl init` | None | Generate a commented `.stackctl` configuration file. | `--detect`, `--preset `, `--profile `, `--write-gitignore`, `--force`, `--dry-run`. There is no verified `--project` flag. | +| `stackctl generate` | None | Generate canonical stack files from per-service Compose sources. | `--dry-run`, `--stacks `, `--output-dir `, `--profile `, `--override `. Stack and override values are comma-separated. | +| `stackctl render` | None | Resolve `${VAR}` placeholders in generated stack files using service-local env values. | `--stacks `, `--profile `, `--strict`, `--output-dir `, `--override `, `--dry-run`. Stack and override values are comma-separated. | +| `stackctl up` | None | Generate, render, and deploy stacks to Docker Swarm. | `--follow-logs`, `--dry-run`, `--detach`, `--prune`, `--stacks `, `--profile `, `--override `. Stack names are selected with `--stacks`; do not document positional stack args. | +| `stackctl down` | None | Remove Docker Swarm stacks from the cluster. | `--yes`, `--dry-run`, `--stacks `, `--profile `. Stack names are selected with `--stacks`; do not document positional stack args. This is destructive unless `--dry-run` is used. | +| `stackctl status` | None | Show stack service status. | `--json`, `--stacks `, `--profile `. | +| `stackctl logs` | `[services...]` | Follow service logs. | `--stacks `, `--profile `, `--follow`, `--tail `. Positional arguments are service names. Without service names, discovered stack services are used, optionally filtered by `--stacks`. | +| `stackctl sync` | None | Validate that generated stacks match committed stack files. | `--quiet`, `--non-interactive`, `--profile `, `--stacks `. This is drift validation only, not deploy. | +| `stackctl doctor` | None | Check system and project health. | `--fix-volumes`, `--check-secrets`, `--profile `. `--fix-volumes` currently reports `External volumes: not yet implemented`; it is not an implemented repair. | +| `stackctl reload` | None | Re-render and redeploy stacks without tearing down. | `--skip-generate`, `--skip-unchanged`, `--force-service-update`, `--no-force-service-update`, `--follow-logs`, `--stacks `, `--profile `, `--config `, `--override `, `--dry-run`. Reload never schedules stack, network, or volume removal in source comments. | +| `stackctl plan` | `` | Produce a deterministic plan of what an operation would do. | `--profile `, `--stacks `, `--override `, `--json`. The operation argument is required. Do not show bare `stackctl plan`. | +| `stackctl completions` | Provided by Cliffy completions command. | Generate shell completions. | Source wires `new CompletionsCommand()`. Check generated help for shell-specific usage. | + +## `plan` operations + +Use `stackctl plan `. Do not use bare `stackctl plan`. + +| Operation | Notes | +| ---------- | --------------------------------------------------------------------------------------------------------------------------------- | +| `up` | Preview stack deployment. | +| `down` | Preview stack removal. | +| `sync` | Preview the operation registered as `sync`. Do not describe live `stackctl sync` as deploy; live `sync` is drift validation only. | +| `generate` | Preview stack generation only. | +| `render` | Preview rendering only. | +| `reload` | Preview config-first reload. | +| `env` | Preview env file scaffolding. | +| `secrets` | Preview secrets workflow. | +| `all` | Preview everything. | + +Source examples include: + +```bash +stackctl plan sync +stackctl plan up --profile staging +stackctl plan generate --stacks api,web +stackctl plan all --json +``` + +## Secrets commands + +| Command | Arguments | Description | Options and caveats | +| -------------------------- | ------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| `stackctl secrets encrypt` | `[files...]` | Encrypt `.env` files to `.env.enc` using SOPS and age. | `--dry-run`. If files are omitted, source discovers `.env` files without encrypted counterparts. | +| `stackctl secrets decrypt` | `[files...]` | Decrypt `.env.enc` files to `.env` using SOPS and age. | `--dry-run`. If files are omitted, source discovers encrypted env files. | +| `stackctl secrets deploy` | `[stacks...]` | Decrypt env files and deploy stacks. | `--profile `, `--dry-run`. Stack names are positional arguments here. | +| `stackctl secrets clean` | None | Remove decrypted `.env` files securely with shred and rm. | `--dry-run`. | +| `stackctl secrets check` | None | Check secrets tooling availability. | No subcommand options are registered in source. | + +## Env commands + +| Command | Arguments | Description | Options and caveats | +| -------------------------- | --------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `stackctl env list` | None | List discovered `.env.example` files and their status. | `--profile `, `--paths `, `--json`, `--list`. Paths are comma-separated. | +| `stackctl env create` | `[name]` | Create `.env` files from `.env.example` templates. | `--profile `, `--paths `, `--force`, `--dry-run`, `--json`. | +| `stackctl env diff` | `[name]` | Show differences between `.env.example` and `.env` files. | `--profile `, `--paths `, `--json`. | +| `stackctl env materialize` | None | Materialize profile preset env values into `.env` files. | `--from-profile ` is required. Also supports `--paths `, `--force`, `--dry-run`, `--json`. | +| `stackctl env audit` | None | Check `.env` files for sensitive plaintext issues. | `--paths `, `--dry-run`, `--json`, `--suggest`. Suggestions are enabled unless disabled by the boolean option handling. | + +## Stack argument rules + +| Workflow | Valid stack selection | +| -------------------------- | ----------------------------------- | +| Deploy with `up` | `stackctl up --stacks api,web` | +| Remove with `down` | `stackctl down --stacks api,web` | +| Deploy with secrets | `stackctl secrets deploy api web` | +| Logs for explicit services | `stackctl logs api_web worker` | +| Logs for stacks | `stackctl logs --stacks api,web` | +| Plan for stacks | `stackctl plan up --stacks api,web` | + +## Safe examples + +```bash +stackctl init +stackctl generate --stacks api,web +stackctl render --strict --stacks api +stackctl up --stacks api,web --dry-run +stackctl down --stacks api --dry-run +stackctl sync --non-interactive +stackctl reload --stacks api --skip-unchanged +stackctl secrets deploy api web --dry-run +stackctl env materialize --from-profile staging --dry-run +stackctl plan all +``` diff --git a/skills/stackctl-cli/references/truth-model.md b/skills/stackctl-cli/references/truth-model.md new file mode 100644 index 0000000..2be6cb0 --- /dev/null +++ b/skills/stackctl-cli/references/truth-model.md @@ -0,0 +1,78 @@ +# stackctl truth model + +Use this file to avoid hallucinating command facts or install behavior. + +## Source hierarchy + +1. `src/cli/mod.ts` is authoritative for CLI commands, subcommands, flags, arguments, and command + behavior. +2. `src/config/types.ts`, `src/config/load.ts`, and `src/config/defaults.ts` are authoritative for + config shape, profile handling, defaults, and exit-code meaning. +3. `deno.json`, `src/main.ts`, and `src/version.ts` are authoritative for package metadata, runtime, + tasks, entrypoint, version, and Deno permissions. +4. `README.md` is public guidance. It can be stale and does not override source files. +5. `docs/migration.md` is draft migration documentation. Treat examples there as potentially stale + unless confirmed in source. +6. Homebrew formula behavior must be checked in `AniTrend/homebrew-tap`. This repository does not + implement Homebrew post-install messaging. + +If a command, flag, argument, install mode, workflow, or Homebrew behavior is not verified in the +source hierarchy or accepted research, say it is unknown or check the source. + +## Runtime facts + +| Fact | Verified value | +| ------------------- | ------------------------------------------------------------------------------------------------------- | +| Runtime | Deno 2.x | +| Package | `@anitrend/stackctl` | +| Entrypoint | `src/main.ts` | +| Source of CLI truth | `src/cli/mod.ts` | +| Node project files | Not part of this project. Do not add `package.json`, `node_modules`, npm config, or Node project files. | +| Dependency source | JSR imports in `deno.json` | + +The `npx skills add` commands install only the AI agent skill. They do not install stackctl, do not +add runtime dependencies to stackctl, and do not make this repository a Node or npm project. + +## Config and profiles + +Config resolution order, where later layers win: + +1. Built-in defaults. +2. `.stackctl`. +3. `.stackctl.`. +4. `.stackctl.local`. +5. `.stackctl.local.`. +6. Explicit `--override` files where a command supports them, applied after config layers but before + rendering. + +Profile selection precedence is `--profile` over `STACKCTL_PROFILE`. + +## Exit codes + +| Code | Meaning | +| ---- | ----------------------------- | +| 0 | Success. | +| 1 | Drift or validation failure. | +| 2 | User config error. | +| 3 | Missing dependency. | +| 4 | Unexpected or internal error. | + +## Hard anti-hallucination controls + +- `sync` is drift validation only. It is not deploy. +- Bare `stackctl plan` is invalid because `plan` requires an operation argument. +- `up` and `down` use `--stacks` for stack selection. +- `secrets deploy` accepts positional stack names. +- `logs` accepts positional service names and supports `--stacks`. +- `doctor --fix-volumes` is a stub that reports external volumes as not yet implemented. +- Homebrew post-install messaging is not implemented in this repository. +- `init` has no verified `--project` flag. + +## Known stale or sensitive areas + +- README command examples must be checked against `src/cli/mod.ts` before reuse. +- Migration documentation can contain draft or stale syntax. +- Install permission examples can differ between docs and `src/main.ts`. Prefer current source for + executable behavior. +- Homebrew availability and formula output are outside this repository. Check the tap before making + claims.