Metadata-Version: 2.4
Name: lx-tooling
Version: 0.7.1
Summary: Labinetix workflow CLI for humans and AI agents
Project-URL: Homepage, https://github.com/labinetix/lx-tooling
Project-URL: Repository, https://github.com/labinetix/lx-tooling
Project-URL: Documentation, https://github.com/labinetix/lx-tooling/blob/main/docs/design/lx-tooling.md
Author-email: Fabian Müller <fabianmueller100295@gmail.com>
License: MIT
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: typer>=0.26.8
Description-Content-Type: text/markdown

# lx-tooling

**Tag:** Org and orchestration · **CLI:** `lx` · **PyPI:** `lx-tooling`

`lx-tooling` is the **Labinetix workflow CLI** for humans and AI agents. It orchestrates the GitHub issue → branch → pull request → release loop and checks repository policy, without owning any domain logic.

## What this repository is

Labinetix builds the bioreactor control cabinet internals and software stack across many cooperating repositories (contracts, deterministic runtime, GUIs, build/deploy/test). The company operating model — see [`../.VAULT/MANIFEST.md`](../.VAULT/MANIFEST.md) and the [`manifests/`](../.VAULT/manifests/index.md) — rests on a few ideas:

- **GitHub is the durable coordination layer.** Issues are the backlog and the development memory; PRs are the review record; releases are the shipped product.
- **Issues are strictly typed and related natively.** Work is classified with GitHub **issue types** and connected with **sub-issues** and **blocked-by/blocking dependencies** (GitHub Issues 2.0), not ad-hoc labels or free text.
- **Local Cursor agents do the implementation**, driving `git`/`gh`; a cloud coding agent is an optional secondary lane for small chores.
- **Humans own product judgment**, review, merge, release, and deployment.

`lx-tooling` is the **front-end that makes the correct path the easy path**. It wraps `git`, `gh`, repository metadata, and Labinetix policy so that humans and agents run one consistent, dry-run-first, JSON-emitting command instead of remembering every rule. It does **not** replace `git`, `gh`, CI, GitHub review, or branch protection — those stay authoritative.

> **Non-goals:** model semantics, ABI/schema ownership, runtime algorithms, protocol implementations, build logic (`lx-toolchains`), deployment (`lx-deploy`), or hardware validation (`lx-testbench`).

## How `lx` relates to `gh` and `git`

Think of three layers:

| Layer | Owns | Examples |
|-------|------|----------|
| `git` | Local source history | branches, commits, diffs |
| `gh` / GitHub API | GitHub **transport** and platform primitives | issues, issue types, sub-issues, dependencies, PRs, CI, releases, GraphQL |
| `lx` | Labinetix **policy + orchestration** on top | readiness checks, branch-prefix-from-type, PR body generation, release preflight, the derived issue graph |

**Guiding rule:** `lx` *consumes* native `gh` primitives and adds Labinetix interpretation. It does **not** re-implement anything `gh` already does well. Before a feature is added to `lx`, we check whether `gh ... --json` already covers it.

### Workflow ↔ command map

Legend: ✅ shipped in `lx 0.7.0+` (CLI unchanged in 0.7.1 — docs/prompts only) · 🔜 planned in `lx` · 🟦 use `gh`/`git` directly (native command already covers it precisely; `lx` will not wrap it)

| Workflow step (from the manifests) | `lx` command | Wraps / consumes | Status |
|---|---|---|---|
| Orient in a repository | `lx repo inspect [--json]` | filesystem + `gh repo view` | ✅ |
| List ready (unblocked) issues | `lx issue list --ready` | `gh issue list` | ✅ |
| Filter backlog by label | `lx issue list --label group:<area>` | `gh issue list --label` | ✅ |
| Read one issue + readiness hints (label-state + body-section) | `lx issue view <n>` | `gh issue view` | ✅ |
| **Bundle issue metadata + comments** | `lx issue context <n> [--json]` | `gh issue view` + relationships + comments | ✅ |
| **Read whole backlog as a graph** | `lx issue graph [--include-recent-closed] [--json]` | `gh api graphql` (types, sub-issues, deps) + optional closed slice | ✅ |
| Create a typed issue from a template | `lx issue create <type>` | `gh issue create --type ...` | 🔜 |
| **Reconcile stale issues (knowledge-base hygiene)** | `lx issue audit` | `gh api graphql` + `gh issue comment/edit` | 🔜 (do it manually, see below) |
| Set issue **type / parent / dependency** | — | `gh issue edit --type / --add-sub-issue / --add-blocked-by` | 🟦 native, precise |
| Comment lifecycle notes on an issue | — | `gh issue comment` | 🟦 |
| Start a branch from an issue (type-aware prefix + git preflight) | `lx issue start <n> --yes --comment` | `git checkout -b` + `gh issue comment` | ✅ |
| Pre-PR policy check | `lx workflow check` | reads `git`/files | ✅ |
| Run local checks matching CI | `lx workflow run-checks` | configured cmd (`just check`) | 🔜 (run `just check` now) |
| Generate a PR body | `lx pr prepare` | builds body, infers `Closes #n` | ✅ |
| Create the PR | `lx pr prepare --yes` | `gh pr create` | ✅ |
| Edit PR body before creating | `lx pr prepare --body-file` | `gh pr create --body-file` | 🔜 |
| Inspect PR CI checks | `lx pr checks` | `gh pr checks` | 🟦 `gh pr checks` is excellent |
| Read PR review comments / CI logs | `lx pr feedback` | `gh pr view --comments`, `gh run view` | 🟦 use `gh` directly |
| Plan a release | `lx release plan` | `gh` tags + CI status + `git` | ✅ |
| Validate release readiness | `lx release create <v>` | validation only | ✅ |
| Draft release notes from merged PRs | `lx release notes draft <v>` | `gh pr list --search` | ✅ |
| Create tag / GitHub Release / publish | — | `git tag`, `gh release create` | 🟦 intentionally manual + human approval |
| Delegate a small issue to a cloud agent | `lx issue delegate <n>` | assign issue to agent (API) | 🔜 (see [#83](https://github.com/labinetix/lx-tooling/issues/83)) |

In short: `lx` ships the **policy-heavy orchestration** (readiness, branch start, PR body, release preflight); `gh` keeps the **precise platform operations** (relationship edits, CI inspection, releases); and the 🔜 rows are where `lx` still adds value on top of `gh`.

## Reading the whole backlog: the issue graph

Both you and an agent need to see the entire issue knowledge base at any moment. GitHub Issues 2.0 stores issue **types**, **sub-issues**, and **blocked-by/blocking dependencies** natively, and a **single GraphQL query** returns the whole open backlog with those relationships in one round-trip (measured: 63 issues in ~1.5s, no pagination under 100). No background-synced database is needed.

Load the derived graph (recommended — from a clone use `uv run lx` until `lx-tooling` is installed globally):

```bash
uv run lx issue graph
uv run lx issue graph --json > issue-graph.json
uv run lx issue graph --include-recent-closed --since 90d --json
```

`lx issue graph` runs the live GraphQL query and adds the **derived view** GitHub does not give for free: ready-vs-blocked ordering, dependency-cycle detection, roots/leaves, per-issue `created_at`/`updated_at` timestamps, and an agent-friendly denormalized shape. With `--include-recent-closed`, it also merges a **recent closed slice** (PR-seeded closures plus a time window) for familiarization — use `lx issue context <n>` for full comment bodies on specific closed threads.

Inspect native relationship coverage:

```bash
jq '.summary | {open: .open_count, typed: .typed_count, parented: .parented_count, deps: .with_dependencies_count, blocked: (.blocked | length), policy_ready: (.policy_ready | length)}' issue-graph.json
```

The graph is structure only — fetch **full** comment bodies on candidate issues with `lx issue context <n> --json` (preferred) or `gh issue view <n> --json …,comments`. Human `gh issue view <n> --comments` is a quick preview only; the terminal renderer may truncate long closure comments. See [`docs/prompts/backlog-familiarization.md`](docs/prompts/backlog-familiarization.md).

Set relationships natively (these are 🟦 `gh`, not `lx`):

```bash
gh issue edit <n> --type "Feature"
gh issue edit <epic> --add-sub-issue <child1>,<child2>
gh issue edit <n> --add-blocked-by <blocker>
```

## Keeping the issue knowledge base current

Because issues **are** the durable memory, they must stay honest. When the workflow or manifests change, some open issues go stale: already shipped, **superseded by a native `gh` feature**, duplicate titles for the same scope, or no longer matching the workflow. Stale issues mislead both humans and agents and make the graph meaningless.

**Before creating issues:** search open titles first (`gh issue list --search "in:title …"`) so maintainer and agent do not open the same scope twice in one session. See [`AGENTS.md`](AGENTS.md) § Avoid duplicate issue creation.

The fix is a recurring **reconciliation pass**. Until `lx issue audit` ships, run it manually:

```bash
# 1. Load the full backlog graph
uv run lx issue graph --json > issue-graph.json
```

Then, in Cursor, give the agent an instruction such as:

> Load `issue-graph.json`. For every open issue, judge it against the current repository state, the shipped `lx` surface (`lx --help`), latest `docs/release-notes/v*.md`, and the manifests in `../.VAULT/manifests/`. Flag issues that are (a) already implemented, (b) superseded by a native `gh` feature such as issue types / sub-issues / dependencies, or (c) inconsistent with the updated workflow. For each, propose: comment, relabel, set a dependency, or close as superseded. **Do not close anything silently** — leave a Reconciliation comment first. For a full autonomous pass, use [`docs/prompts/backlog-familiarization.md`](docs/prompts/backlog-familiarization.md) and commit the session report under `docs/reports/`.

For each stale issue, the agent (or you) leaves a comment and relabels — never a silent close:

```bash
# Mark an issue as superseded by a native GitHub feature, with rationale
gh issue comment <n> --body "Re-triage: the relationship modelling planned here is now native (GitHub Issues 2.0 dependencies/sub-issues, exposed via gh + GraphQL). See ../.VAULT/manifests/agentic-workflow.md §3. Recommend closing as superseded; remaining policy value tracked in #<m>."

# Move it out of "ready" until a human confirms
gh issue edit <n> --add-label "status:needs-design"

# Only after human confirmation:
gh issue close <n> --reason "not planned" --comment "Superseded by native GitHub issue dependencies. Tracked in #<m>."
```

The planned `lx issue audit` will automate the load + heuristic flagging (shipped vs native-covered vs inconsistent) and emit the suggested comments for review — but closing stays a human decision.

## Quickstart

Prerequisites:

- Python 3.11+
- [`uv`](https://docs.astral.sh/uv/)
- [`gh`](https://cli.github.com/) **v2.94.0+** (native issue types/sub-issues/dependencies), authenticated with `gh auth login`

Local development:

```bash
git clone git@github.com:labinetix/lx-tooling.git
cd lx-tooling
uv sync --all-groups
uv run lx --version
```

Local checks (same as CI):

```bash
just check
```

Or explicitly:

```bash
uv sync --all-groups
uv run ruff check .
uv run ruff format --check .
uv run pytest
```

## Install

```bash
uv tool install lx-tooling
lx --version
```

Upgrade:

```bash
uv tool upgrade lx-tooling
```

## Command reference (shipped in 0.7.0)

```bash
# Orient
lx repo inspect
lx repo inspect --json

# Discover work
lx issue graph
lx issue graph --json
lx issue graph --include-recent-closed --since 90d --json
lx issue list --ready
lx issue list --label group:issue-workflow
lx issue view 123
lx issue context 123
lx issue context 123 --json

# Start work (dry-run unless --yes; branch prefix inferred from issue type + git preflight)
lx issue start 123
lx issue start 123 --yes --comment

# Verify before a PR
just check
lx workflow check

# Open a PR (dry-run unless --yes)
lx pr prepare
lx pr prepare --yes

# Plan / validate a release (never tags or publishes)
lx release plan
lx release create 0.7.0
lx release create 0.7.0 --yes
lx release notes draft 0.7.1
lx release notes draft 0.7.1 --yes
```

Examples:

- [`docs/examples/repo-inspect.md`](docs/examples/repo-inspect.md)
- [`docs/examples/issue-context.md`](docs/examples/issue-context.md)
- [`docs/examples/issue-start.md`](docs/examples/issue-start.md)
- [`docs/examples/pr-prepare.md`](docs/examples/pr-prepare.md)
- [`docs/examples/release-plan.md`](docs/examples/release-plan.md)

## Development loop with `lx`

The intended day-to-day loop in any Labinetix repository. `lx` wraps `git`/`gh`; risky steps stay behind `--yes`.

```mermaid
flowchart LR
  graph["lx issue graph"]
  view["lx issue view"]
  start["lx issue start --yes"]
  work["code + tests + docs"]
  check["just check + lx workflow check"]
  pr["lx pr prepare --yes"]
  merge["review + merge main"]
  release["release plan + tag"]
  graph --> view --> start --> work --> check --> pr --> merge --> release
```

1. **See the backlog.** Load the issue graph and pick a ready, scoped issue. Fetch **full** comment bodies on candidates with `lx issue context <n> --json` — the graph is structure only; human `gh issue view --comments` may truncate. Prompts: [`backlog-familiarization.md`](docs/prompts/backlog-familiarization.md) (autonomous issue curation — output in `docs/reports/`), [`release-planning.md`](docs/prompts/release-planning.md) (define next release horizon + `kind:release-planning` issue), [`release-implementation.md`](docs/prompts/release-implementation.md) (implement next in-scope issue from a planning issue), [`feature-implementation.md`](docs/prompts/feature-implementation.md) (unbiased pick + implement), [`feature-implementation-followup.md`](docs/prompts/feature-implementation-followup.md) (after a merge — use closure-comment follow-ups).
2. **Confirm scope.** `lx issue context 123 --json` (or `lx issue context 123`). Set/verify native type, parent, and dependencies with `gh issue edit`; explain the rationale in a Plan comment.
3. **Start the branch.** From an up-to-date `main`:

   ```bash
   git checkout main && git pull
   lx issue start 123 --yes --comment
   ```

4. **Implement one coherent slice** — code, tests, docs, examples together; reference the issue (`feat(cli): ... (#123)`).
5. **Verify.** `just check` then `lx workflow check`.
6. **Open the PR.**

   ```bash
   git push -u origin HEAD
   lx pr prepare          # preview body
   lx pr prepare --yes    # gh pr create with Closes #123
   ```

7. **Review and merge through GitHub.** The issue closes on merge via the closing keyword.

8. **Close the loop on the issue.** Post an after-merge comment with what users can do now, verification, release impact, suggested next issues, and any workflow observations. See [`docs/examples/issue-closure-comment.md`](docs/examples/issue-closure-comment.md).

| Kind | Issue type | Branch prefix | Typical release |
|------|-----------|---------------|-----------------|
| Feature | Feature | `feat/` | minor `0.y.0` |
| Bugfix | Bug | `fix/` | patch `0.y.z` |
| Docs only | Docs/Task | `docs/` | patch or none |
| CI/tooling | Task | `ci/` | patch |

## Releases and release notes

- Latest release: [GitHub Releases](https://github.com/labinetix/lx-tooling/releases)
- Artifacts: wheel + sdist built by CI on protected SemVer tags (`v*`), published to PyPI via trusted publishing (`pypi.yml`, environment `pypi`).

Store release notes in the repository (`docs/release-notes/vX.Y.Z.md`) drafted from merged PRs and the issues they closed. See [`docs/release-notes/README.md`](docs/release-notes/README.md). **Release planning** (what should ship): [`docs/prompts/release-planning.md`](docs/prompts/release-planning.md). **Release preparation** (tag after merge): [`docs/prompts/release-preparation.md`](docs/prompts/release-preparation.md). Maintainer flow:

1. Merge feature/fix PRs to `main`; keep CI green.
2. Bump `version` in `pyproject.toml` and `src/lx_tooling/__init__.py`; add `docs/release-notes/vX.Y.Z.md`.
3. Merge to `main`, then tag and push:

   ```bash
   git tag -a v0.7.1 -m "Release v0.7.1"
   git push origin v0.7.1
   ```

4. Confirm the PyPI workflow succeeded; verify `uv tool install lx-tooling` picks up the new version.

## Design and agent rules

- Workflow manifests: [`../.VAULT/MANIFEST.md`](../.VAULT/MANIFEST.md) and [`../.VAULT/manifests/`](../.VAULT/manifests/index.md)
- Design: [`docs/design/lx-tooling.md`](docs/design/lx-tooling.md)
- Agent rules: [`AGENTS.md`](AGENTS.md)
