gh-optivem

command module
v1.6.60 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 53 Imported by: 0

README

gh Commit Stage gh Acceptance Stage gh Release Stage gh Post-Release Stage gh Local Stage

gh-optivem

A GitHub CLI extension for scaffolding pipeline projects.

Prerequisites

GitHub CLI

GitHub CLI is required to install this extension.

Check your version:

gh --version

If the command isn't found or the version is too old, install or upgrade:

  • Install: winget install GitHub.cli (Windows), brew install gh (macOS), or sudo apt install gh / your distro's package manager (Linux)
  • Upgrade: winget upgrade GitHub.cli (Windows), brew upgrade gh (macOS), or sudo apt upgrade gh / your distro's package manager (Linux)
GitHub CLI authentication

You must be logged in to GitHub via the CLI before installing this extension.

Verify you're logged in:

gh auth status

If the command reports you're not logged in, log in:

gh auth login
actionlint

actionlint — used by the Verify scaffolded workflows step.

Check your version:

actionlint -version

If the command isn't found or the version is too old, install or upgrade to the latest v1 release:

go install github.com/rhysd/actionlint/cmd/actionlint@v1

Installation

gh extension install optivem/gh-optivem

Verify the install:

gh optivem --version

Upgrade:

gh extension upgrade optivem

Uninstall:

gh extension remove optivem

Claude Code setup

gh optivem ships the Optivem Claude slash commands and global configuration rules embedded in the binary. One command installs them into your ~/.claude/ directory.

Install commands

Copy the embedded slash commands to ~/.claude/commands/:

gh optivem claude install

Files already up to date are skipped. Changed files are overwritten. A summary of what changed is printed.

Configure settings

Merge the Optivem settings.json permissions and CLAUDE.md rules into your ~/.claude/ directory (non-destructive — never removes entries you added yourself):

gh optivem claude configure
Setup (install + configure)

Run both in one step:

gh optivem claude setup

Re-run any time after upgrading the extension to pick up new or updated commands and configuration rules.

Environment Variables

Provide these credentials one of two ways:

  • OS environment variables — set them on your machine the usual way. After setting them, restart your IDE / terminal for the changes to take effect (the env snapshot is taken when the process launches).

  • A portable .env file (no restart needed) — copy .env.example, fill in the values, and drop it at the user-level path gh optivem loads at startup:

    • Windows: %AppData%\gh-optivem\.env
    • Linux/macOS: ~/.config/gh-optivem/.env
    • Or keep it in a synced folder (Dropbox/OneDrive) and point at it with GH_OPTIVEM_ENV_FILE=/abs/path/to/.env.

    Edit the file any time — already-open shells pick up the new values on the next gh optivem run, with no terminal restart. A real exported environment variable always wins; the file only fills variables that are currently unset. Your filled-in copy is never committed (.env is gitignored; only the .env.example template is tracked).

The credentials, either way:

These three back cron-scheduled pipelines (e.g. acceptance-stage-legacy.yml, which runs hourly) that keep running indefinitely once scaffolded — a classic PAT with an expiration date will eventually lapse and start failing the schedule silently, with no scaffold-time signal. gh optivem environment verify warns when a classic PAT's expiration is within 7 days, but "No expiration" avoids the rotation chore entirely for these specific tokens.

These are read from your local environment at scaffold time and then propagated as variables and secrets onto the GitHub repos that gh optivem init creates, so the pipelines it generates can pull base images from Docker Hub under the authenticated rate limit (rather than the much lower anonymous one), publish and pull pipeline images to/from GHCR, send analysis to SonarCloud, and dispatch cross-repo workflows — all without you having to set each secret in the GitHub UI afterwards.

Tokens are read from env vars rather than passed as CLI flags so they don't end up in shell history or ps output, so a single set persists across init, environment show/verify, and re-runs, and so the local input contract matches how GitHub Actions exposes the same secrets to the generated pipelines.

To confirm what your shell is actually exporting (token values masked):

gh optivem environment show

To live-check each token is also accepted by its provider before scaffolding:

gh optivem environment verify
gh optivem environment verify --lang typescript,dotnet,java  # also check compilers for the listed languages
gh optivem environment verify --deploy docker                # also check the docker CLI is on PATH

--lang (comma-separated or repeated; values: java, dotnet, typescript) opts in to per-language compiler-presence checks. --deploy (value: docker) opts in to the deploy-target-conditional tool check. Both are opt-in so a CI preflight job can pin one matrix combo without coupling this command to the project-config schema.

Scaffolding

gh optivem init

Project-stable values — prompted on first run and written to gh-optivem.yaml (or passed as flags for non-interactive runs):

  • --owner — GitHub owner (user or org) for the scaffolded repo(s).
  • --repo — repo name (or monorepo root name for multi-repo layouts).
  • --system-name — human-readable system name (e.g. "Page Turner").
  • --arch — system architecture: monolith or multitier.
  • --repo-strategymonorepo or multirepo.
  • Implementation language — which flag applies depends on --arch:
    • --monolith-lang — system language when --arch monolith: java, dotnet, or typescript.
    • --backend-lang — backend language when --arch multitier: java, dotnet, or typescript.
    • --frontend-lang — frontend language when --arch multitier (currently only typescript).
  • --test-lang — system-test language: java, dotnet, or typescript. Independent of the system language(s).
  • --project-url — URL of the GitHub Project board to attach. When omitted, init auto-creates the board and writes the URL back into gh-optivem.yaml.
  • --license — SPDX-like license key: mit (default), apache-2.0, gpl-3.0, bsd-2-clause, bsd-3-clause, or unlicense. Drives the scaffolded LICENSE file and README badge.
  • --deploy — deployment target: docker (default). cloud-run is in development and not yet usable.
  • Tier paths — --system-path, --system-test-path, --backend-path, --frontend-path. Repo-relative paths to the corresponding tier. Pass these only to point the YAML at a non-flat existing repo; the flat scaffold layout init itself produces is the default.

Per-invocation flags — not written to gh-optivem.yaml; pass them on each init run:

  • --verify-levelnone, local, commit, acceptance, qa, or release (default release). Each level runs every step up to and including its named stage.
  • --no-legacy — exclude legacy from local tests and acceptance stage.
  • --no-local-tests — skip the local-test verification step.
  • --no-local-sonar — skip the local SonarCloud scan step.
  • --no-project — skip the Ensure project board step entirely (no auto-create, no status-ensure on a supplied --project-url).
  • --no-atdd — no-op retained for backward compatibility; ATDD assets are sourced from the per-user sync (see Methodology assets), not installed per-repo.
  • --shop-ref — pin optivem/shop to a specific ref (tag, SHA, or branch). Default: latest meta-v* release.
  • --workdir — working directory for local clones (default: temp dir).
  • --keep-local — keep the local scaffolded clone dir on success instead of deleting it.
  • --report-bug — on failure, auto-create a GitHub issue in optivem/gh-optivem with scaffold config. Off by default.
  • --yes / -y — skip all interactive confirmations (existing-repo prompt, bug-report confirmation). Expected for CI/unattended runs.
  • --log-file — override path for the plain-text log mirror (default: $TEMP/gh-optivem-<timestamp>.log; always written).
  • --verbose / -v — enable debug output (retry/wait chatter, diagnostics).
  • --quiet / -q — suppress info-level output (warnings and errors still shown).
Where gh-optivem.yaml lands
  • Default path (no --config, no $GH_OPTIVEM_CONFIG): gh optivem init writes gh-optivem.yaml only inside the scaffolded repo on GitHub. Nothing is materialized in the current working directory.
  • Explicit path (--config /some/path.yaml or $GH_OPTIVEM_CONFIG=/some/path.yaml): init writes/updates the YAML at the path you named, and the scaffolded repo still gets its own copy (rendered with the auto-created Project URL).
  • Pre-existing <CWD>/gh-optivem.yaml: respected as operator-authored input. Loaded and used as-is; the scaffolded repo still gets its own rendered copy.
Managing gh-optivem.yaml standalone

gh optivem config reads or writes gh-optivem.yaml outside of a full init run — useful for retrofitting a hand-rolled repo, validating a hand-edited file, or migrating an older config to the current schema.

gh optivem config init       # write a fresh gh-optivem.yaml from CLI flags (or interactive prompt on a TTY)
gh optivem config validate   # parse the YAML and validate it against the schema
gh optivem config preflight  # validate + check every declared repo and tier path exists on disk
gh optivem config migrate    # idempotently back-fill required fields (project.provider, repos:) on a pre-schema-bump file

config init accepts the same YAML-affecting flags as gh optivem init (--owner, --repo, --system-name, --arch, --repo-strategy, --monolith-lang / --backend-lang / --frontend-lang, --test-lang, --project-url, --license, --deploy, plus the --system-path / --system-test-path / --backend-path / --frontend-path tier-path overrides). On a TTY with no required flags set, it drops into the same interactive prompt the init command uses. Extra flags: --force (overwrite an existing file) and --dir <dir> (target directory; ignored when --config is set).

config preflight accepts --workspace <dir> to point at a non-default workspace root (default: parent directory of CWD). config validate and config migrate take no flags beyond the root-level --config.

gh optivem config init --owner acme --repo page-turner \
    --arch monolith --repo-strategy monorepo --monolith-lang java \
    --test-lang java --project-url https://github.com/orgs/acme/projects/1
gh optivem -c ./gh-optivem.myrepo.yaml config validate
gh optivem config preflight --workspace /abs/path/to/workspace

Usage

gh optivem provides runner subcommands to build the system, run the system, and run the tests.

System
Compile system

Source-level compile of the system tier (dotnet build / ./gradlew compileJava / npx tsc --noEmit), dispatched per-tier by the lang: field in gh-optivem.yaml.

gh optivem system compile                 # system tier only
gh optivem compile                        # shortcut: system + test tiers (halts on first failure)

compile is the source-level build — distinct from system build (docker compose build / container image build). The two must not be conflated.

Build system

docker compose build for every entry in systems.yaml.

gh optivem system build
gh optivem system build --rebuild         # force full rebuild (no layer cache reuse)
Start system

docker compose up + wait for health.

gh optivem system start
gh optivem system start --restart         # force tear-down + restart
gh optivem system start --log-lines 200   # lines of compose logs to dump on health-probe failure (default 50)
gh optivem system start --up-timeout 10m  # per-attempt timeout for `docker compose up -d` (default 5m)
Probe system status

Snapshot probe of every component + external-system URL in systems.yaml. Prints OK or DOWN per entry and exits non-zero if any are DOWN, so it can be used in shell pipelines.

gh optivem system status
gh optivem system status --timeout 5s    # per-URL probe timeout (default 2s)

No retries, no waiting — pair with system start for the lifecycle ("did it come up?"). After a successful gh optivem implement --issue N, the same block is printed automatically as an === System endpoints === banner.

Stop system

docker compose down + container cleanup.

gh optivem system stop
Clean system

docker compose down -v --rmi local — delete volumes + locally-built images. Analog of dotnet clean / ./gradlew clean: deletes build outputs without touching the dependency cache (registry-pulled images are kept). Chain it explicitly for a fresh start: gh optivem system clean && gh optivem test run.

gh optivem system clean
System tests
Setup tests

Run setupCommands from tests.yaml (npm ci, restore, compile test sources, ...).

gh optivem test setup
Compile tests

Source-level compile of the test tier only.

gh optivem test compile
Run tests

[!WARNING] The system must already be running (gh optivem system start). test run health-probes every entry in systems.yaml first; if any aren't up, it errors out with "start it first with gh optivem system start" rather than silently starting them.

Run all tests:

gh optivem test run                       # run every suite against the already-running system

Run specific suites:

gh optivem test run --suite smoke         # run only the suite with this id
gh optivem test run --suite acceptance-api --suite acceptance-ui   # multiple suites, repeatable
gh optivem test run --suite acceptance-api,acceptance-ui           # ...or comma-separated
gh optivem test run --list                # print suite ids from tests.yaml and exit

Run specific tests:

gh optivem test run --test "MyTest"       # narrow execution to one test name (substituted into the suite's testFilter)
gh optivem test run --test T1 --test T2   # multiple names, repeatable
gh optivem test run --test T1,T2          # ...or comma-separated
gh optivem test run --sample              # use each suite's sampleTest field as the test name

Multi-test semantics depend on the suite's testFilter in tests.yaml. The runner combines multiple --test values per testFilterJoin: "or" (default) joins names with | and substitutes once — works for playwright/jest (--grep 'T1|T2') where | is alternation at the value level; "repeat" substitutes the whole testFilter once per name and concatenates — required for gradle (--tests T1 --tests T2) where the flag itself must repeat; "fragment-or" (for &-prefixed injection fragments) substitutes per name, joins with |, wraps in ( ... ), and injects as one expression — required for dotnet (&(DisplayName~T1|DisplayName~T2)) whose --filter parser ORs full property terms, not bare values. Practical ceiling on Windows is ~600 typical test names per invocation (the OS caps each command line at 32K characters).

Cross-repo operations

gh optivem commit, sync, and actions status infer scope from the environment. The cascade resolves to one of three modes:

  • Workspace — a *.code-workspace file is reachable (via the --workspace <dir> flag, the $GH_OPTIVEM_WORKSPACE env var, or a walk-up from the current directory); the verb iterates every folder in the workspace file.
  • Project — no workspace file is reachable, but CWD walks up to a gh-optivem.yaml with a non-empty repos: list; the verb iterates every listed local repo (used for multitier projects whose tiers live in sibling clones).
  • Single repo — neither of the above; the verb acts on the cwd repo only.

rate-limit is a single API call with no scope.

gh optivem commit "Update settings"                                     # stage, commit, pull, push every dirty repo in scope
gh optivem commit --repo myrepo "Fix bug"                               # only operate on the named repo (workspace mode)
gh optivem commit --repo myrepo --paths "system/monolith/java" "fix"    # stage only the listed space-separated paths (requires --repo) — surgical, no sweep
gh optivem commit --yes --all "Sync .claude"                            # skip the y/N confirmation; --all opts in to the blanket git add -A sweep
gh optivem commit --yes "Sync .claude"                                  # ERROR: --yes refuses a blanket stage without --all (use --paths or --all)
gh optivem sync                                                         # pull + push every repo in scope (no commit)
gh optivem actions status                                               # latest run of every workflow in every repo in scope
gh optivem rate-limit                                                   # current GitHub API rate limits and reset times

Each run prints a Mode: banner showing the resolved scope — Mode: workspace (5 repos from page-turner.code-workspace), Mode: project (3 repos from gh-optivem.yaml), or Mode: single repo (shop).

commit --yes refuses to stage untracked (??) files unless --include-untracked is also passed — the stray-file foot-gun is opt-in for scripted callers.

Auto-approve

gh optivem prompts on every confirmation by default. To run unattended, opt into auto-approve policy with --auto:

gh optivem --auto implement --issue 42          # skip everything except commit + fix (default exclusion)
gh optivem --auto --confirm= implement          # truly autonomous: prompt only on human STOP nodes
gh optivem --auto --confirm=fix implement       # narrower: prompt only on fix-agent dispatch (and human)

--auto is a root-level persistent flag. When set, every confirmation auto-yeses except the categories listed in --confirm:

Category Covers
commit git commit confirmations (lands on GitHub history)
fix ATDD approve nodes wrapping fix-* agent dispatch (recovery flow)
release ATDD release confirmer
prompt low-stakes interactive prompts (init walks, doctor, bug-report, ATDD non-fix approve)
human ATDD agent: human STOP nodes — always confirmed, cannot be auto-yes'd

Default --confirm when --auto is set and --confirm is omitted: commit,fix (plus implicit human). This protects the two expensive failure modes (publishing the wrong commit; auto-rewriting files in a recovery flow) by default. Override with an explicit --confirm=<categories> to narrow or broaden.

Environment variables:

  • GH_OPTIVEM_AUTO=true — same as --auto.
  • GH_OPTIVEM_CONFIRM=<categories> — same as --confirm=<categories>.

Flag overrides env; both override default. A one-line banner is emitted to stderr at command start showing the resolved policy and where each part came from:

Auto: true (auto-source: flag, confirm-source: default → commit,fix)

The per-command --yes flag on commit skips the per-repo confirmation directly, independent of --auto. The two compose: gh optivem --auto commit "msg" also commits without prompting unless commit is in the confirm set (it is, by default). Because --yes removes the human review of the staged file list, it refuses a blanket git add -A unless you opt in with --all (or scope the stage with --paths) — and refuses untracked files unless you add --include-untracked. This keeps unrelated working-tree changes (e.g. parallel-agent WIP) from being swept into a scripted commit.

Cleanup

gh optivem cleanup <verb> bulk-deletes remote artifacts. Each subcommand pre-flights gh api rate_limit before every destructive call and sleeps --delay-seconds (default 10) after each delete to stay under GitHub's 80-mutating-calls/minute secondary limit. Always pass --dry-run first to preview.

gh optivem cleanup releases optivem/greeter-java --dry-run
gh optivem cleanup releases optivem/greeter-java optivem/greeter-dotnet
gh optivem cleanup packages myorg/myrepo --before-date 2026-01-01
gh optivem cleanup repos valentinajemuovic --prefix course-tester- --dry-run
gh optivem cleanup sonar-projects myorg --prefix myorg_course-tester- --dry-run

cleanup releases and cleanup packages take one or more positional owner/repo slugs; cleanup repos and cleanup sonar-projects take a single positional <owner> (or <organization>) followed by either --prefix <prefix>, explicit names/keys, or both. cleanup sonar-projects requires $SONAR_TOKEN (the same token the scaffolder reads).

Running the implementation pipeline

Once a scaffolded project carries a valid gh-optivem.yaml and the sibling repos are cloned next to it, the implement subcommand walks the configured process-flow state machine for one ticket:

gh optivem implement --issue 42                                # walk the pipeline for a specific issue
gh optivem implement --issue https://github.com/myorg/myrepo/issues/42
gh optivem implement                                           # pick the top Ready ticket and walk the pipeline from START

implement accepts the same per-invocation flags whether or not --issue was passed:

... --headless            # run the claude subprocess headless (claude -p); structured JSON envelope captured for the exit banner
... --autonomous          # [Deprecated] alias for --auto --headless; will be removed in a future release
... --manual-agents       # v1 fallback: pause at each user-task node and let the operator launch the agent manually
... --log-file run.log    # mirror everything stdout/stderr emit during the run to this file (always Detail = firehose by default)
... --log-level phase     # narrow the --log-file capture to phase only (BPMN trace + prompts); pairs with --log-file
... --verbose / -v        # stream the full firehose to the terminal (subprocess output, agent body, prompt-prep banners). Default: terminal shows only BPMN trace, agent enter/exit banners, and prompts
... --keep-runs 10        # max prompt-log run dirs to keep under .gh-optivem/runs/ (0 = never prune; default 10)
... --show-prompt         # dump each agent's full rendered prompt before dispatch (default: summary banner only)
... --workspace <path>    # override the default workspace root (parent directory of CWD; each clone dir must be named after the repo-name component of its slug)
Output levels

implement separates terminal output from --log-file content via two levels:

  • Phase[phase] start / end … boundary banners, BPMN trace lines ([trace …] > NODE_ID …), approval / STOP prompts, errors, [agent] enter / exit / FAIL … lines. The headline channel the operator needs to follow the run.
  • Detail — subprocess byte streams (gradle, docker, gh CLI, agent body), [agent] prep summary, the $ <command> echo, internal banners. The firehose used for forensic dig.

Each sink subscribes to a maximum level. Defaults: terminal = Phase (clean), --log-file = Detail (firehose). Independently configurable via --verbose (terminal up to Detail) and --log-level=phase|detail (log file).

For skipping confirmation prompts during a pipeline run (or any other gh optivem invocation), see Auto-approvegh optivem --auto implement --headless is the typical unattended invocation.

Project-stable overrides (process_flow:, task_prompts:, node_extras:, node_replacements:) live in gh-optivem.yaml and are read at startup.

Process diagram

To inspect the configured process-flow Mermaid diagram without running the pipeline:

gh optivem process show                            # print the canonical Mermaid markdown to stdout
gh optivem process show > docs/process-diagram.md  # regenerate the committed diagram

Trunk-based development helpers

gh optivem doctor, branch, pr, and hooks encapsulate the trunk-based development rituals from docs/tbd.md so the operator runs one command instead of three.

gh optivem doctor                              # verify the three global git config keys docs/tbd.md mandates
gh optivem doctor --fix                        # set any missing or wrong keys to the required values
gh optivem branch start feature/payments       # checkout main, pull --rebase, checkout -b <name> off latest origin/main
gh optivem branch refresh                      # fetch origin, rebase current branch onto origin/main, push --force-with-lease (refuses on main)
gh optivem pr merge                            # squash-merge a PR via `gh pr merge` (TBD-safe: never a merge commit)
gh optivem pr merge 123 --rebase               # rebase-merge instead
gh optivem pr merge --auto --squash --delete-branch
gh optivem hooks install                       # install a pre-push hook that refuses non-fast-forward pushes to main

pr merge defaults to --squash; --rebase is opt-in and the two are mutually exclusive. The --merge mode is intentionally not exposed because merge commits on main break the linear-trunk invariant. Pass any other gh pr merge flags directly to the underlying CLI.

Methodology assets

gh optivem ships its ATDD methodology assets (the per-phase agent prompts and the shared preamble) embedded in the binary. They are fed to the claude -p subprocess via argv at dispatch time and are never written to disk in consumer repos — scaffolded projects hold zero ATDD assets locally, and updates propagate simply by upgrading the gh-optivem binary.

Further reading

  • Trunk Based Development (TBD) — how to work with main in this repo (and the repos it scaffolds), the role of pull --rebase, when to use short-lived PRs, and why the version-bump bot is just another committer.
  • Process diagram — committed Mermaid diagram of the configured implementation process flow (regenerate with gh optivem process show).
  • BPMN process design — the why behind the five-level process model (TOP / CYCLE / HIGH / MID / LOW): primitives, doctrine decisions, and the ticket-to-cycle mapping.

Documentation

Overview

aggregate_commands.go wires the bare `gh optivem test` aggregate verb — the for-all counterpart to the bare `compile` aggregate (compile_commands.go).

`test` is no longer a tier (that ambiguity is resolved by the `system-test` / `component-test` level nouns — plan 20260624-1221). The bare word is now the run-everything verb: it runs every test level in cheap→expensive pyramid order, halting on first failure —

component-test suites  →  system start  →  system-test run  →  system stop

and manages the system lifecycle itself by default. CI, which already starts and stops the system explicitly around its acceptance stage, opts out of the start/stop with --assume-running so the aggregate does not double-manage the system. Bare = for-all, qualified (`system-test` / `component-test`) = scoped: the `make` / `make test` mental model. Bare `compile` has no lifecycle analog — it is a pure source build, so it carries no such flag.

architecture_commands.go wires the `gh optivem architecture` parent and its children. Mirrors `process_commands.go` — same "view, don't generate" principle: consumers and CI alike read the same artifact gh-optivem produces, with no per-repo tooling.

gh optivem architecture show           # render the Mermaid architecture diagram
gh optivem architecture show > docs/architecture-diagram.md

The rendered output describes the layered ATDD architecture every scaffolded student repo follows. Keeping the canonical copy in gh-optivem's `docs/` (alongside `docs/process-diagram.md`) avoids drift between scaffolded repos and the source-of-truth template.

branch_commands.go wires the `gh optivem branch` subtree. Encapsulates the Scaled-TBD branch primitives documented in docs/tbd.md so the operator runs one command instead of three. Today the only child is `start <name>`, which freshens local `main` against origin before forking the new branch — preventing the common foot-gun of branching off a stale local `main`.

branch_refresh.go wires the `gh optivem branch refresh` subcommand. It encapsulates the Scaled-TBD "main moved while my PR was open" ritual from docs/tbd.md:75-81 — fetch origin, rebase the current feature branch onto origin/main, then push with --force-with-lease.

--force-with-lease is hardcoded; plain --force is not exposed so the operator cannot accidentally pick the unsafe variant. The command also refuses to run on `main` — refresh is for feature branches only.

claude_commands.go implements `gh optivem claude` subcommands for managing Claude Code commands and configuration globally.

install — writes embedded command files to ~/.claude/commands/ configure — merges embedded settings.json and CLAUDE.md into ~/.claude/ non-destructively setup — runs install then configure check — reports drift between embedded assets and ~/.claude/ (read-only)

cleanup_commands.go wires the `gh optivem cleanup <verb>` subtree. The cleanup noun spans bulk-destructive operations against remote systems (GitHub releases/packages/repos, SonarCloud projects). The Go ports replace the bash scripts in academy/github-utils/scripts/ — see plans/20260514-0914-migrate-workspace-scripts-to-gh-optivem.md.

The DRY_RUN env var idiom from bash becomes a `--dry-run` flag here (consistent with the rest of gh-optivem). Each subcommand pre-flights `gh api rate_limit` before each destructive call via internal/shell.

compile_commands.go wires the bare `gh optivem compile` aggregate verb and the tier-level helpers (compileSystem, compileComponentTests, compileSystemTests, monolithTier, loadProjectConfigOrExit) shared with the noun-scoped forms (`gh optivem system compile` in system_commands.go, `gh optivem component-test compile` in component_commands.go, and `gh optivem system-test compile` in test_commands.go).

Naming: `compile` is source-level build (dotnet build / gradlew compileJava / npx tsc). `build` is reserved for `docker compose build` (system_commands.go, under the `system` noun). The two are distinct enough to coexist; they must not be conflated.

`compile` is a bare "for-all" aggregate verb (no parent noun): it spans every tier, running `system compile` → `component-test compile` → `system-test compile` in sequence, halting on first failure. Bare = for-all, qualified = scoped — the `make` / `make test` mental model. This shortcut is the dominant use case (the structural-cycle compile_all action shells out to it as a single command). Same category as `gh browse` / `gh status` in gh's own surface: cross-resource, no single noun to slot under. The noun-scoped forms stay available for scoped local use.

compile_summary.go collects per-tier outcomes during a `gh optivem compile` run and prints a compact tail summary, so the user can scan success/failure without scrolling the (often long) compile output.

One row per `compiler.Compile` call (i.e. per tier). Per-command timing inside the compiler package is deliberately not threaded through — the compile_commands.go level is the right granularity, and keeping the `compiler` package's `error`-only API intact preserves its testable seam.

component_commands.go wires the `gh optivem component-test <verb>` subtree — the component-test pyramid level. It is a flat sibling of `gh optivem system-test` (test_commands.go), NOT nested under a `component` noun: `component-test` and `system-test` are parallel test-pyramid *levels* (like unit / integration / e2e), each carrying the same `run | setup | compile` verb set. Component-level tests are in-process, white-box, with no running system; system tests drive a deployed system (compose, channels, external stub/real) from outside. Keeping the two level namespaces flat and symmetric is exactly the taxonomy plan 20260624-1221 establishes.

Working-dir contract: every verb runs against the user's cwd and discovers the components from the active gh-optivem.yaml — monolith system.path, or multitier system.backend.path / system.frontend.path. Each component carries its own component-tests.yaml (by convention, in the component directory), holding its setup / compile / suite commands. An alternate gh-optivem.yaml is selected via --config / -c.

config_commands.go wires the `gh optivem config …` subcommands into the root Cobra command. The `config` namespace owns operations that read or write gh-optivem.yaml — the central per-project config file produced by `gh optivem init` and consumed by `gh optivem implement`.

gh optivem config init      — write a fresh gh-optivem.yaml from CLI flags
gh optivem config validate  — parse <CWD>/gh-optivem.yaml and validate it
gh optivem config preflight — validate + check on-disk layout exists
gh optivem config migrate   — back-fill required fields onto a pre-schema-bump config

`config init` reuses the same render path as `gh optivem init` (steps.WriteOptivemYAMLToPath / config.ValidateAndDeriveForYAML) so a new YAML-affecting flag flows to both surfaces with no per-command duplication.

cross_repo_commands.go wires the cross-repo verbs that live at the root of `gh optivem` — commit, sync, actions status, rate-limit, and the hidden TBD-discipline reports (lint-history, stale-branches).

The verbs share the same scope-resolution cascade (workspace.Resolve in internal/workspace): when a *.code-workspace file is reachable, every declared folder is iterated; otherwise the scope shrinks to the CWD's git repo. The resolved scope is announced on every invocation via the "Mode: …" banner so the operator always sees what's about to happen.

The --workspace flag is registered at root (main.go); its value lands in workspaceFlagValue below and is passed to workspace.Resolve as the highest-priority cascade input.

doctor_commands.go wires the `gh optivem doctor` command. It verifies local state invariants the rest of the binary depends on:

  • global git config keys docs/tbd.md requires for trunk-based development (the original scope; --fix sets them).
  • orphan claude.exe subprocesses left behind by crashed `gh optivem implement` runs, surfaced via --orphans and recovered from the per-dispatch PID markers internal/userstate owns. See doctor_orphans.go for the recovery logic.

Broader repo-health checks belong in their own command; this one stays focused on "the things gh-optivem itself needs in order to work."

doctor_orphans.go adds the `gh optivem doctor --orphans` recovery path: scan the user-level state dir for PID marker files left behind by crashed `gh optivem implement` runs, classify each as stale / live-dispatch / orphan, and prompt the operator to kill the orphans.

The PID marker schema and the state-dir resolver are owned by internal/userstate so the runtime writer side (driver, clauderun) and this reader side share one source of truth.

environment_commands.go wires the `gh optivem environment` subtree. The `environment` noun owns read-only operations on the local shell environment the gh-optivem CLI reads from — credentials and other inputs alike (e.g. DOCKERHUB_USERNAME is an account name, not a token, but is still required from the environment).

gh optivem environment show   — print each env var, with token values
                                 masked, so you can confirm what your
                                 shell is exporting without leaking the
                                 secret to terminal scrollback.
gh optivem environment verify — check every credential and required
                                 local tool (gh CLI auth, actionlint),
                                 returning non-zero on any missing or
                                 rejected value.

`verify` is designed to be invoked from a CI preflight job so a single broken input surfaces once, before a scaffolding matrix fans out and burns runner minutes failing the same way N times. `show` is the local counterpart — judgment-free output for humans debugging their setup.

hooks_commands.go wires the `gh optivem hooks` subtree. Today the only child is `install`, which drops a pre-push hook into the current repo that refuses non-fast-forward pushes to `main`. Belt-and-suspenders for the "never force-push main" rule (docs/tbd.md) — the in-tool guard in workspace_commands.go covers tool-mediated pushes; the hook covers raw `git push --force` invocations the tool never sees.

implement_commands.go wires the `gh optivem implement` subcommand into the root Cobra command. The `implement` verb walks the configured pipeline against a specific issue identified by --issue.

gh optivem implement --issue 42     # walk the pipeline for a specific issue

The handler is deliberately thin: it translates Cobra flags into internal/atdd/runtime/* calls and surfaces their errors via exitOnError (defined in runner_helpers.go) for consistency with the rest of the `optivem` binary.

Why "implement" as a top-level verb (not under a methodology noun): the pipeline orchestrated here is the stable concept; *which* methodology runs (ATDD today, TDD/DDD or compositions later) is configuration read from `gh-optivem.yaml` (process_flow:, task_prompts:, node_extras:, node_replacements:). Hoisting `implement` to the root keeps the muscle memory ("implement an issue") even when a second methodology lands.

gh-optivem: A gh CLI extension for pipeline project management.

Usage:

Monolith:
  gh optivem init --owner acme --system-name "Page Turner" --repo page-turner \
      --arch monolith --monolith-lang java

Multitier:
  gh optivem init --owner acme --system-name "Page Turner" --repo page-turner \
      --arch multitier --backend-lang java --frontend-lang typescript

output_commands.go wires the `gh optivem output <verb>` subtree. The output noun is the structured-output channel between an ATDD agent (running under `claude` in a dispatched subprocess) and the gh-optivem dispatcher. The agent calls `gh optivem output write KEY=VALUE` from its `Bash` tool to emit a value the dispatcher then reads back from a per-invocation JSONL file. Replaces the older prose-YAML channel that could not cross the interactive-mode TTY boundary.

Two env vars drive the channel; both are exported by the dispatcher before launching `claude`:

  • GH_OPTIVEM_OUTPUT_FILE — absolute path to the JSONL file. Each `write` invocation appends one JSON object as a single line.
  • GH_OPTIVEM_OUTPUT_KEYS — comma-separated allow-list with types, shape `key1:type1,key2:type2,...`. Derived from the call-activity's BPMN `outputs:` list. Any unknown key or coercion failure exits non-zero so the agent sees the error mid-run.

Types: `string`, `bool`, `string-list` (comma-split). Coercion is self-contained in this file — there is no shared Go table; the BPMN declaration is the single source of truth, and the dispatcher hands the per-invocation slice in via the env var.

pr_commands.go wires the `gh optivem pr <verb>` subtree. The pr noun wraps `gh pr` with TBD-discipline defaults: squash- or rebase-merges only, never a merge commit on main. See plans/20260514-2043-tbd-discipline-in- workspace-tool.md (Layer 3, item 10) and docs/tbd.md for the linear-trunk invariant this enforces.

preflight_helpers.go builds the wired-up preflight.Options the cobra layer passes to preflight.Run. Both `gh optivem implement` and `gh optivem config preflight` go through this helper so the two surfaces share one definition of "what real remote checks does preflight run" — adding or removing a remote check class touches one place, not two.

Token requirements:

  • GitHub: relies on whatever auth `gh` CLI is already configured with (`gh auth login` or $GH_TOKEN / $GITHUB_TOKEN). No extra plumbing.
  • SonarCloud: the live org/project checks need $SONAR_TOKEN; they are wired only when it (and cfg.Sonar.Organization) is present.
  • The full required credential set is presence-checked via opts.MissingEnvVars, so every missing var (SONAR_TOKEN included) surfaces together in preflight.Run's aggregated failure block rather than one-at-a-time.

process_commands.go wires the `gh optivem process` parent and its children. The intent is the "view, don't generate" principle: consumers and CI alike can read the same artifact gh-optivem produces, with no per-repo tooling.

gh optivem process show           # render the Mermaid process-flow diagram
gh optivem process show > docs/process-diagram.md
gh optivem process scope          # list every phase's allowed-paths layers
gh optivem process scope AT_RED_TEST   # one phase, resolved against gh-optivem.yaml

`process` is a noun group, not a methodology namespace. The artifact described (the configured process flow) belongs to *the process*, not to *the methodology* — keeping it grouped under `process` ages better when TDD/DDD or compositions land, and matches the existing noun-first surface (`system`, `test`, `config`, `environment`).

run_commands.go wires the `gh optivem run` parent and its children. `run` is the noun group for per-pipeline-run artefacts produced under .gh-optivem/runs/<ts>/ — a dispatcher per-prompt log, the streamed claude events JSONL, the agent's declared-outputs JSONL, and the per-dispatch agent-summary sidecar. The first child, `summary`, replays any run's agent-summary table from its sidecar.

gh optivem run summary           # most recent run
gh optivem run summary 20260528-150000   # a specific run

`run` is grouped under "Other" — a diagnostic-noun verb, not a project op (no gh-optivem.yaml is touched) and not a cross-repo op (it reads only the local cwd's .gh-optivem/runs/ tree).

runner_helpers.go holds the cross-cutting helpers used by the runner-tier commands. The command wiring itself lives in `system_commands.go` and `test_commands.go` — split per the noun-first surface (`gh optivem system <verb>` / `gh optivem system-test <verb>`). The runner package is fully agnostic — these helpers translate Cobra flags into runner.* calls and resolve config paths against gh-optivem.yaml.

Working-dir contract: each command operates against the user's current working directory. A gh-optivem.yaml is required; its system.config: / system-test.config: fields drive path resolution. An alternate gh-optivem.yaml can be selected via --config / -c.

system_commands.go wires the `gh optivem system <verb>` subtree. The system noun spans the lifecycle verbs that operate on the scaffolded project's running containers (build, start, stop, clean) plus the source-level system tier compile.

Working-dir contract: every command runs against the user's cwd and reads the systems config path from gh-optivem.yaml's system.config: field (legacy `.json` files still resolve via the loader's extension dispatch). An alternate gh-optivem.yaml can be selected via --config / -c. Missing gh-optivem.yaml or empty system.config: are hard errors. Helpers live in runner_helpers.go.

test_commands.go wires the `gh optivem system-test <verb>` subtree — the system-test pyramid level. The system-test noun owns the level's lifecycle verbs: `run` against an already-running system, `setup` for harness preparation, and `compile` for the system-test source build. It is the flat sibling of `component-test` (component_commands.go); the two parallel `*-test` level nouns share the same `run | setup | compile` verb set.

NOTE: the bare top-level `test` is no longer this tier — it is the for-all aggregate verb (aggregate_commands.go) that runs every test level in pyramid order. The system-test level is addressed only as `gh optivem system-test`.

Working-dir contract: every command runs against the user's cwd and reads the tests config path from gh-optivem.yaml's system-test.config: field (legacy `.json` files still resolve via the loader's extension dispatch). An alternate gh-optivem.yaml can be selected via --config / -c. Missing gh-optivem.yaml or empty system-test.config: are hard errors. Helpers live in runner_helpers.go.

Directories

Path Synopsis
internal
atdd
Package atdd hosts ATDD doctrinal allowlists that sit outside the runtime subtree.
Package atdd hosts ATDD doctrinal allowlists that sit outside the runtime subtree.
atdd/assets
Package assets exposes the embedded asset tree for the ATDD process.
Package assets exposes the embedded asset tree for the ATDD process.
atdd/process
Package process holds the concrete ATDD/BPMN process definition that the generic engine loads via its LoadBytes contract.
Package process holds the concrete ATDD/BPMN process definition that the generic engine loads via its LoadBytes contract.
atdd/process/actions
fix_progress.go — no-progress guard for the verify-tests-pass fix loop.
fix_progress.go — no-progress guard for the verify-tests-pass fix loop.
atdd/process/clauderun
Package clauderun shells out to the `claude` CLI to dispatch a named ATDD agent for the current phase, replacing v1's "pause and let the operator launch the agent in a second window" workflow.
Package clauderun shells out to the `claude` CLI to dispatch a named ATDD agent for the current phase, replacing v1's "pause and let the operator launch the agent in a second window" workflow.
atdd/process/configcheck
Package configcheck holds the one project-config validation rule that needs engine knowledge: the `task-prompts:` keys must name MID tasks the embedded process-flow actually declares.
Package configcheck holds the one project-config validation rule that needs engine knowledge: the `task-prompts:` keys must name MID tasks the embedded process-flow actually declares.
atdd/process/gates
Bindings — Go implementations of every gateway `binding:` referenced in internal/atdd/process/process-flow.yaml.
Bindings — Go implementations of every gateway `binding:` referenced in internal/atdd/process/process-flow.yaml.
atdd/process/verify
Bindings — per-node pre/post-condition checks.
Bindings — per-node pre/post-condition checks.
atdd/runtime/agents
Package agents resolves the agent layer of a process: the per-role prompt bodies a user-task dispatches, their model/effort tuning, plus the registry that maps YAML `agent:` names to NodeFn dispatchers.
Package agents resolves the agent layer of a process: the per-role prompt bodies a user-task dispatches, their model/effort tuning, plus the registry that maps YAML `agent:` names to NodeFn dispatchers.
atdd/runtime/driver
Package driver wires together the ATDD pipeline runtime: it loads the process-flow YAML, registers gates / actions / agents, applies override and verify decorators, and walks the named process end to end.
Package driver wires together the ATDD pipeline runtime: it loads the process-flow YAML, registers gates / actions / agents, applies override and verify decorators, and walks the named process end to end.
atdd/runtime/intake
Package intake holds the deterministic markdown parser that replaces the three LLM-driven intake agents (atdd-story / atdd-bug / task).
Package intake holds the deterministic markdown parser that replaces the three LLM-driven intake agents (atdd-story / atdd-bug / task).
atdd/runtime/outlog
Package outlog provides level-tagged byte-stream multiplexing for the ATDD runtime.
Package outlog provides level-tagged byte-stream multiplexing for the ATDD runtime.
atdd/runtime/override
Package override implements the per-step override-hook decorator.
Package override implements the per-step override-hook decorator.
atdd/runtime/preflight
Package preflight validates that the consumer's gh-optivem.yaml maps onto a real on-disk layout and a real remote setup before any ATDD agent or board work runs.
Package preflight validates that the consumer's gh-optivem.yaml maps onto a real on-disk layout and a real remote setup before any ATDD agent or board work runs.
atdd/runtime/release
Package release owns the end-of-cycle release mechanics for the ATDD pipeline driver: commit and close the GitHub issue.
Package release owns the end-of-cycle release mechanics for the ATDD pipeline driver: commit and close the GitHub issue.
atdd/runtime/repolocator
Package repolocator turns a parsed projectconfig.Config into a map from repo slug → absolute local clone path.
Package repolocator turns a parsed projectconfig.Config into a map from repo slug → absolute local clone path.
atdd/runtime/trace
Package trace adds a per-node logging decorator to the engine, producing a chronological audit trail of every step the ATDD pipeline takes:
Package trace adds a per-node logging decorator to the engine, producing a chronological audit trail of every step the ATDD pipeline takes:
atdd/runtime/tracker
Package tracker is the seam between the ATDD pipeline driver and the concrete issue-tracker backend (GitHub Projects today, markdown files for the local/offline path, Jira tomorrow).
Package tracker is the seam between the ATDD pipeline driver and the concrete issue-tracker backend (GitHub Projects today, markdown files for the local/offline path, Jira tomorrow).
atdd/runtime/tracker/factory
Package factory wires projectconfig.Project values to concrete tracker.Tracker adapters.
Package factory wires projectconfig.Project values to concrete tracker.Tracker adapters.
atdd/runtime/tracker/github
Package github implements tracker.Tracker against GitHub Projects v2.
Package github implements tracker.Tracker against GitHub Projects v2.
atdd/runtime/tracker/internal/parse
Package parse holds the shared markdown helpers the github and markdown tracker adapters use to source an Issue.Title from a body — currently just FirstH1.
Package parse holds the shared markdown helpers the github and markdown tracker adapters use to source an Issue.Title from a body — currently just FirstH1.
atdd/runtime/tracker/markdown
Package markdown implements tracker.Tracker against a local board laid out as a tree of `<board>/<status>/<id>.md` files.
Package markdown implements tracker.Tracker against a local board laid out as a tree of `<board>/<status>/<id>.md` files.
build
Package build is the documentation marker for the shared build module: the home of the project's compile and system-test execution machinery.
Package build is the documentation marker for the shared build module: the home of the project's compile and system-test execution machinery.
build/compiler
Package compiler runs source-level compile sequences for one tier of a scaffolded project, dispatching by language.
Package compiler runs source-level compile sequences for one tier of a scaffolded project, dispatching by language.
build/componenttest
Package componenttest loads and runs component-level test suites declared in a per-component component-tests.yaml.
Package componenttest loads and runs component-level test suites declared in a per-component component-tests.yaml.
build/runner
Package runner orchestrates docker-compose-backed system tests using two YAML config files (with legacy JSON fallback): a systems.yaml (compose + health probes) and a tests.yaml (setup commands + suites).
Package runner orchestrates docker-compose-backed system tests using two YAML config files (with legacy JSON fallback): a systems.yaml (compose + health probes) and a tests.yaml (setup commands + suites).
claude/assets
Package assets exposes the embedded asset tree for Claude Code setup.
Package assets exposes the embedded asset tree for Claude Code setup.
config
Package config provides CLI parsing, validation, and the Config struct.
Package config provides CLI parsing, validation, and the Config struct.
config/configinit
Package configinit owns the shared "produce a gh-optivem.yaml" code path.
Package configinit owns the shared "produce a gh-optivem.yaml" code path.
config/optivemyaml
Package optivemyaml builds a projectconfig.Config (the gh-optivem.yaml schema) from an init config.Config, and writes it to disk.
Package optivemyaml builds a projectconfig.Config (the gh-optivem.yaml schema) from an init config.Config, and writes it to disk.
devworkflow/ghbulk
Package ghbulk ports the paginated bulk-delete helpers from github-utils/scripts/{delete-releases,delete-packages,delete-repos}.sh.
Package ghbulk ports the paginated bulk-delete helpers from github-utils/scripts/{delete-releases,delete-packages,delete-repos}.sh.
devworkflow/sonar
Package sonar wraps the SonarCloud REST endpoints the cleanup command uses (api/projects/search, api/projects/delete).
Package sonar wraps the SonarCloud REST endpoints the cleanup command uses (api/projects/search, api/projects/delete).
devworkflow/workspace
Package workspace resolves the cross-repo scope for a command invocation.
Package workspace resolves the cross-repo scope for a command invocation.
diagrams/architecture
Package architecture renders the canonical Mermaid markdown for the ATDD layered-architecture diagram.
Package architecture renders the canonical Mermaid markdown for the ATDD layered-architecture diagram.
diagrams/diagram
Package diagram renders the canonical Mermaid markdown for the ATDD process flow.
Package diagram renders the canonical Mermaid markdown for the ATDD process flow.
engine/statemachine
Package statemachine is a generic, BPMN-shaped process engine: a hand-coded graph traversal that walks a process definition node-by-node, dispatching service tasks, user-task agents, and gateways through pluggable registries.
Package statemachine is a generic, BPMN-shaped process engine: a hand-coded graph traversal that walks a process definition node-by-node, dispatching service tasks, user-task agents, and gateways through pluggable registries.
expand
Package expand provides the shared ${name} placeholder substitution primitive used by ATDD agent-prompt rendering (clauderun): a flat name→value map is substituted into the prompt body, with a guardrail that catches missing keys.
Package expand provides the shared ${name} placeholder substitution primitive used by ATDD agent-prompt rendering (clauderun): a flat name→value map is substituted into the prompt body, with a guardrail that catches missing keys.
kernel/approval
Package approval resolves the operator's global auto-approve policy (--auto + --confirm=<tier>) and gates every y/n confirmation against it.
Package approval resolves the operator's global auto-approve policy (--auto + --confirm=<tier>) and gates every y/n confirmation against it.
kernel/cmdctx
Package cmdctx threads the resolved auto-approve policy from the root command's PersistentPreRunE down to every Cobra subcommand's Run via a typed context key.
Package cmdctx threads the resolved auto-approve policy from the root command's PersistentPreRunE down to every Cobra subcommand's Run via a typed context key.
kernel/gitignore
Package gitignore provides a helper to idempotently ensure a line is present in a repo's .gitignore.
Package gitignore provides a helper to idempotently ensure a line is present in a repo's .gitignore.
kernel/log
Package log provides colored logging helpers.
Package log provides colored logging helpers.
kernel/pathx
Package pathx contains small cross-platform path helpers shared across packages that exec subprocesses.
Package pathx contains small cross-platform path helpers shared across packages that exec subprocesses.
kernel/projectconfig
Package projectconfig loads the consumer repo's per-project configuration file at gh-optivem.yaml (project root).
Package projectconfig loads the consumer repo's per-project configuration file at gh-optivem.yaml (project root).
kernel/promptio
Package promptio centralises every human y/n decision the CLI surfaces.
Package promptio centralises every human y/n decision the CLI surfaces.
kernel/shell
Package shell provides GitHub CLI wrapper and subprocess helpers.
Package shell provides GitHub CLI wrapper and subprocess helpers.
kernel/spinner
Package spinner shows an animated liveness indicator for long-running waits where the duration is unknown.
Package spinner shows an animated liveness indicator for long-running waits where the duration is unknown.
kernel/version
Package version provides build-time version information.
Package version provides build-time version information.
scaffolding
Package scaffolding is the documentation marker for the scaffolding module: the machinery that materializes a new project from templates.
Package scaffolding is the documentation marker for the scaffolding module: the machinery that materializes a new project from templates.
scaffolding/files
Package files provides file manipulation helpers: replace, rename, walk.
Package files provides file manipulation helpers: replace, rename, walk.
scaffolding/steps
Package steps implements the scaffold pipeline steps.
Package steps implements the scaffold pipeline steps.
scaffolding/templates
Package templates provides template helpers: copy workflows, fixups.
Package templates provides template helpers: copy workflows, fixups.
userstate
Package userstate owns the user-level gh-optivem state directory and the schemas of the small files written there.
Package userstate owns the user-level gh-optivem state directory and the schemas of the small files written there.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL