homelab: v0.1 docs, distribution wiring, and version
Completes v0.1: documentation, build/install path, and version stamping.
- cli/VERSION (v0.1.0) stamped into the binary via ldflags.
- cli/README.md rewritten as the homelab overview (verbs + tiers, manifest,
build, the preserved legacy webhook use-cases).
- docs/adr/0004-0006: why homelab exists (grown in place from infra/cli, not a
separate repo), v0.1 scope + everything-allowed/tiers-recorded, and the
work/tf behaviour (native worktree entry, verification-gated auto-land,
presence-coupled apply).
- setup-devvm.sh builds cli/ -> /usr/local/bin/homelab each provisioning run
(t3-dispatch pattern), so every devvm user gets the current binary.
- AGENTS.md: discovery pointer under Common Operations.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 19:25:51 +00:00
|
|
|
|
# homelab
|
|
|
|
|
|
|
|
|
|
|
|
`homelab` is the unified, agent-facing CLI for operating this homelab — one
|
|
|
|
|
|
composable, JSON-capable surface for the operations agents run over and over,
|
|
|
|
|
|
discovered progressively at runtime. It is grown **in place** from this
|
|
|
|
|
|
directory (the former `infra-cli`), and the legacy webhook use-cases still work
|
|
|
|
|
|
(see below).
|
|
|
|
|
|
|
|
|
|
|
|
It encodes *actions*, never *judgment*: methodology (debugging, TDD, review) and
|
|
|
|
|
|
third-party/owned MCP servers (e.g. phpIPAM) are deliberately out of scope.
|
|
|
|
|
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
homelab <command> [args]
|
|
|
|
|
|
homelab manifest [--json] # list every verb + its read/write tier (discovery entrypoint)
|
|
|
|
|
|
homelab version
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### v0.1 verbs — the infra inner-loop
|
|
|
|
|
|
|
|
|
|
|
|
| Command | Tier | What it does |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `claim <kind>:<name> --purpose "…"` | write | claim a shared resource on the presence board (wraps `scripts/presence`) |
|
|
|
|
|
|
| `release <kind>:<name>` | write | release a presence claim |
|
|
|
|
|
|
| `tf plan <stack>` | read | `scripts/tg plan` for a stack (resolved from cwd) |
|
|
|
|
|
|
| `tf validate <stack>` | read | `scripts/tg validate` |
|
|
|
|
|
|
| `tf fmt <stack>` | read | `terraform fmt -recursive` on the stack |
|
|
|
|
|
|
| `tf force-unlock <stack> <lock-id>` | write | release a stuck state lock |
|
|
|
|
|
|
| `tf apply <stack>` | write | `scripts/tg apply` — auto-claims `stack:<name>`, always releases, warns it's out-of-band |
|
|
|
|
|
|
| `work start <topic>` | write | create `.worktrees/<topic>` on `<user>/<topic>` off `<remote>/master`; enter with native `EnterWorktree` |
|
|
|
|
|
|
| `work land [--verify-cmd "…"] [--no-verify]` | write | merge master in → verify → push `HEAD:master` (non-ff retry; PR fallback) |
|
|
|
|
|
|
| `work clean <topic>` | write | remove a task's worktree + branch (run from the main checkout) |
|
|
|
|
|
|
|
2026-06-18 22:30:41 +00:00
|
|
|
|
### v0.2 verbs — Kubernetes
|
|
|
|
|
|
|
|
|
|
|
|
Built on an **app→namespace→pod resolver**: `<app>` defaults to the namespace
|
|
|
|
|
|
(most namespaces hold one app); the target defaults to `deploy/<app>` and lets
|
|
|
|
|
|
kubectl resolve the pod. Override with `-n`/`--pod`/`-c`/`-l`/`--tty`. Uses the
|
|
|
|
|
|
ambient kubeconfig.
|
|
|
|
|
|
|
|
|
|
|
|
| Command | Tier | What it does |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `k8s status [ns]` | read | pods (wide) + recent non-Normal events (`-A` if no ns) |
|
|
|
|
|
|
| `k8s get <ns> <resource> […]` | read | `kubectl -n <ns> get …` passthrough |
|
|
|
|
|
|
| `k8s logs <app>` | read | logs for `deploy/<app>` (`--tail` default 200; `-c`/`--previous`/`--since`/`-l`) |
|
|
|
|
|
|
| `k8s describe <app> [resource]` | read | describe the deployment (or an explicit resource) |
|
|
|
|
|
|
| `k8s debug <app>` | read | one-shot triage: pods + workloads + describe + recent logs + events |
|
|
|
|
|
|
| `k8s pf <app> <local:remote> [target]` | read | port-forward to `svc/<app>` (or an explicit target) |
|
|
|
|
|
|
| `k8s rollout-status <app>` | read | `rollout status deploy/<app>` |
|
|
|
|
|
|
| `k8s db <app> [--mysql] [--db N] -- "<SQL>"` | write | exec into the dbaas DB (PG `pg-cluster-rw`, or MySQL with env-password wrapper) |
|
|
|
|
|
|
| `k8s exec <app> [--tty] -- <cmd>` | write | exec in the app's pod |
|
|
|
|
|
|
| `k8s restart <app>` | write | `rollout restart deploy/<app>` then wait for status |
|
|
|
|
|
|
| `k8s rm-pod <name> -n <ns> [--job] [--force]` | write | delete a stuck **pod/job only** |
|
|
|
|
|
|
|
|
|
|
|
|
Config-mutation verbs (`apply`/`edit`/`patch`/`scale`/`create`) are intentionally
|
|
|
|
|
|
**not** exposed — they stay raw `kubectl`, per the Terraform-only policy.
|
|
|
|
|
|
|
homelab: v0.1 docs, distribution wiring, and version
Completes v0.1: documentation, build/install path, and version stamping.
- cli/VERSION (v0.1.0) stamped into the binary via ldflags.
- cli/README.md rewritten as the homelab overview (verbs + tiers, manifest,
build, the preserved legacy webhook use-cases).
- docs/adr/0004-0006: why homelab exists (grown in place from infra/cli, not a
separate repo), v0.1 scope + everything-allowed/tiers-recorded, and the
work/tf behaviour (native worktree entry, verification-gated auto-land,
presence-coupled apply).
- setup-devvm.sh builds cli/ -> /usr/local/bin/homelab each provisioning run
(t3-dispatch pattern), so every devvm user gets the current binary.
- AGENTS.md: discovery pointer under Common Operations.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 19:25:51 +00:00
|
|
|
|
`tf` resolves the stack dir by walking up from cwd to the infra root and
|
|
|
|
|
|
delegates to `scripts/tg` (which owns state decrypt/encrypt, the Vault lock, and
|
|
|
|
|
|
the ingress auth-comment check). git-crypt filter flags are auto-injected on git
|
|
|
|
|
|
operations in the encrypted infra repo.
|
|
|
|
|
|
|
|
|
|
|
|
**`work land` refuses to push when it cannot verify** (no `--verify-cmd` and no
|
|
|
|
|
|
auto-detected suite) unless you pass `--no-verify` — landing to master unverified
|
|
|
|
|
|
must be deliberate. It does not yet block on CI to green (that arrives with the
|
|
|
|
|
|
ci/deploy watch verbs); it reminds you to follow the pipeline.
|
|
|
|
|
|
|
|
|
|
|
|
Tiers are recorded per verb so a future PreToolUse classifier can auto-allow
|
|
|
|
|
|
reads / prompt writes; v0.1 allows everything and relies on existing gates
|
|
|
|
|
|
(permission mode, presence claims, plan approval).
|
|
|
|
|
|
|
homelab: add memory verb-group (v0.3.0) — direct claude-memory HTTP client
Lets agents search/navigate memory via the CLI, as the first step toward
deprecating the memory MCP. claude-memory is a FastAPI service (the MCP is just
one frontend); homelab memory is a thin Bearer-auth HTTP client over the same
API, using the env the hooks already set (CLAUDE_MEMORY_API_URL/KEY). It works
even when the MCP frontend is down — the recurring disconnect that took the MCP
offline for this whole session.
Verbs: recall (server-side semantic search), list, categories, tags, stats,
secret (read); store, update, delete (write). Validated against the live API
including a store→recall→delete round-trip — full data-plane parity with the MCP.
The deprecation itself (rewiring the per-prompt auto-recall + auto-learn hooks to
the CLI, then uninstalling the MCP) is a deliberate follow-up, sequenced after
the CLI is proven in the hooks — see docs/adr/0008.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 05:56:25 +00:00
|
|
|
|
### v0.3 verbs — memory
|
|
|
|
|
|
|
|
|
|
|
|
A thin HTTP client over the **claude-memory** service (the same backend the
|
|
|
|
|
|
memory MCP wraps), authed with `CLAUDE_MEMORY_API_KEY` against
|
|
|
|
|
|
`CLAUDE_MEMORY_API_URL` (the env the hooks already set; defaults to the
|
|
|
|
|
|
ingress). Because it hits the HTTP API directly, it **works even when the MCP
|
|
|
|
|
|
frontend is down**.
|
|
|
|
|
|
|
|
|
|
|
|
| Command | Tier | What it does |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `memory recall "<context>" [--query --category --sort --limit]` | read | semantic search (server-side ranking) — the navigate workhorse |
|
|
|
|
|
|
| `memory list [--category --tag --limit]` | read | recent memories |
|
|
|
|
|
|
| `memory categories` / `memory tags` / `memory stats` | read | enumerate the store |
|
|
|
|
|
|
| `memory secret <id>` | read | reveal a sensitive memory's content |
|
|
|
|
|
|
| `memory store "<content>" [--category --tags --keywords --importance --sensitive]` | write | store a memory |
|
|
|
|
|
|
| `memory update <id> [--content --tags --importance]` | write | edit a memory |
|
|
|
|
|
|
| `memory delete <id>` | write | delete a memory |
|
|
|
|
|
|
|
|
|
|
|
|
All read/write paths are validated against the live API (incl. a
|
|
|
|
|
|
store→recall→delete round-trip). This gives full data-plane parity with the MCP;
|
|
|
|
|
|
the eventual deprecation (rewiring the per-prompt auto-recall + auto-learn hooks
|
|
|
|
|
|
to the CLI, then uninstalling the MCP) is a **separate, deliberate follow-up** —
|
|
|
|
|
|
see `docs/adr/0008`.
|
|
|
|
|
|
|
homelab: v0.1 docs, distribution wiring, and version
Completes v0.1: documentation, build/install path, and version stamping.
- cli/VERSION (v0.1.0) stamped into the binary via ldflags.
- cli/README.md rewritten as the homelab overview (verbs + tiers, manifest,
build, the preserved legacy webhook use-cases).
- docs/adr/0004-0006: why homelab exists (grown in place from infra/cli, not a
separate repo), v0.1 scope + everything-allowed/tiers-recorded, and the
work/tf behaviour (native worktree entry, verification-gated auto-land,
presence-coupled apply).
- setup-devvm.sh builds cli/ -> /usr/local/bin/homelab each provisioning run
(t3-dispatch pattern), so every devvm user gets the current binary.
- AGENTS.md: discovery pointer under Common Operations.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 19:25:51 +00:00
|
|
|
|
## Build / install
|
|
|
|
|
|
|
|
|
|
|
|
Built from source to `/usr/local/bin/homelab` during devvm provisioning
|
|
|
|
|
|
(`scripts/workstation/setup-devvm.sh`, the `t3-dispatch` pattern); version is
|
|
|
|
|
|
stamped from `cli/VERSION` via ldflags. Manual build:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
cd cli && go build -ldflags "-X main.version=$(cat VERSION)" -o /usr/local/bin/homelab .
|
|
|
|
|
|
go test ./...
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Legacy webhook use-cases (preserved)
|
|
|
|
|
|
|
|
|
|
|
|
This binary is also the in-cluster `infra-cli` image. Invocations starting with
|
|
|
|
|
|
`-use-case=<vpn|setup-openwrt-dns|add-email-alias|...>` fall through to the
|
|
|
|
|
|
original flag-based path unchanged, so the webhook handler is unaffected.
|
|
|
|
|
|
|
|
|
|
|
|
## Design
|
|
|
|
|
|
|
homelab: add memory verb-group (v0.3.0) — direct claude-memory HTTP client
Lets agents search/navigate memory via the CLI, as the first step toward
deprecating the memory MCP. claude-memory is a FastAPI service (the MCP is just
one frontend); homelab memory is a thin Bearer-auth HTTP client over the same
API, using the env the hooks already set (CLAUDE_MEMORY_API_URL/KEY). It works
even when the MCP frontend is down — the recurring disconnect that took the MCP
offline for this whole session.
Verbs: recall (server-side semantic search), list, categories, tags, stats,
secret (read); store, update, delete (write). Validated against the live API
including a store→recall→delete round-trip — full data-plane parity with the MCP.
The deprecation itself (rewiring the per-prompt auto-recall + auto-learn hooks to
the CLI, then uninstalling the MCP) is a deliberate follow-up, sequenced after
the CLI is proven in the hooks — see docs/adr/0008.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 05:56:25 +00:00
|
|
|
|
See `infra/docs/adr/0004`–`0008` for the architecture decisions.
|