Labinetix workflow CLI for humans and AI agents
Project description
lx-tooling
Tag: Org and orchestration · CLI: lx · PyPI: lx-tooling
lx-tooling is the Labinetix engineering workflow CLI for humans and AI agents. It orchestrates the GitHub issue → branch → pull request → release loop and checks repository policy, without owning domain logic or company strategy.
What this repository is
Labinetix's company strategy, durable architecture, and cross-repo design decisions live in ../.VAULT/. This repository implements the engineering workflow toolstack that consumes those rules. The operating model 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).
Strategy boundary:
.VAULTowns company strategy and generalized architecture.lx-toolingowns scoped, tested engineering workflow commands. Seedocs/design/adr-0001-lx-tooling-policy-boundary.md.
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.8.0 · 🔜 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 [--json] [--yes] |
gh api graphql + optional gh issue comment |
✅ |
| 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) |
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):
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:
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.
Set relationships natively (these are 🟦 gh, not lx):
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 § Avoid duplicate issue creation.
The fix is a recurring reconciliation pass. Start with the dry-run audit:
uv run lx issue audit
uv run lx issue audit --json
lx issue audit loads the graph, fetches issue bodies by default, and flags deterministic
hygiene findings: closed blockers, ready-labeled blocked issues, contradictory workflow
labels, duplicate titles, and raw/thin bodies. It never closes issues and does not edit
labels or native edges. With --yes, it posts the generated Reconciliation comments only:
uv run lx issue audit --yes
For deeper curation, give Cursor an instruction such as:
Load
issue-graph.json. For every open issue, judge it against the current repository state, the shippedlxsurface (lx --help), latestdocs/release-notes/v*.md, and the manifests in../.VAULT/manifests/. Flag issues that are (a) already implemented, (b) superseded by a nativeghfeature 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, usedocs/prompts/backlog-familiarization.mdand commit the session report underdocs/reports/.
For each stale issue, the agent (or you) leaves a comment and relabels — never a silent close:
# 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>."
lx issue audit automates the load + heuristic flagging (contradictory labels, duplicate titles, raw/thin bodies, stale blockers) and can emit suggested Reconciliation comments with --yes — but closing issues stays a human decision.
Quickstart
Prerequisites:
- Python 3.11+
uvghv2.94.0+ (native issue types/sub-issues/dependencies), authenticated withgh auth login
Local development:
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):
just check
Or explicitly:
uv sync --all-groups
uv run ruff check .
uv run ruff format --check .
uv run pytest
Install
uv tool install lx-tooling
lx --version
Upgrade:
uv tool upgrade lx-tooling
Command reference (shipped in 0.8.0)
# 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 audit
lx issue audit --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.8.0
lx release create 0.8.0 --yes
lx release notes draft 0.8.0
lx release notes draft 0.8.0 --yes
Examples:
docs/examples/repo-inspect.mddocs/examples/issue-context.mddocs/examples/issue-start.mddocs/examples/pr-prepare.mddocs/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.
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
-
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; humangh issue view --commentsmay truncate. Prompts:backlog-familiarization.md(autonomous issue curation — output indocs/reports/),release-planning.md(define next release horizon +kind:release-planningissue),release-implementation.md(implement next in-scope issue from a planning issue),feature-implementation.md(unbiased pick + implement),feature-implementation-followup.md(after a merge — use closure-comment follow-ups). -
Confirm scope.
lx issue context 123 --json(orlx issue context 123). Set/verify native type, parent, and dependencies withgh issue edit; explain the rationale in a Plan comment. -
Start the branch. From an up-to-date
main:git checkout main && git pull lx issue start 123 --yes --comment
-
Implement one coherent slice — code, tests, docs, examples together; reference the issue (
feat(cli): ... (#123)). -
Verify.
just checkthenlx workflow check. -
Open the PR.
git push -u origin HEAD lx pr prepare # preview body lx pr prepare --yes # gh pr create with Closes #123
-
Review and merge through GitHub. The issue closes on merge via the closing keyword.
-
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.
| 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
- Artifacts: wheel + sdist built by CI on protected SemVer tags (
v*), published to PyPI via trusted publishing (pypi.yml, environmentpypi).
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. Release planning (what should ship): docs/prompts/release-planning.md. Release preparation (tag after merge): docs/prompts/release-preparation.md. Maintainer flow:
-
Merge feature/fix PRs to
main; keep CI green. -
Bump
versioninpyproject.tomlandsrc/lx_tooling/__init__.py; adddocs/release-notes/vX.Y.Z.md. -
Merge to
main, then tag and push:git tag -a v0.8.0 -m "Release v0.8.0" git push origin v0.8.0
-
Confirm the PyPI workflow succeeded; verify
uv tool install lx-toolingpicks up the new version.
Design and agent rules
- Workflow manifests:
../.VAULT/MANIFEST.mdand../.VAULT/manifests/ - Design:
docs/design/lx-tooling.md - Agent rules:
AGENTS.md
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lx_tooling-0.8.0.tar.gz.
File metadata
- Download URL: lx_tooling-0.8.0.tar.gz
- Upload date:
- Size: 133.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ddf2cf6a5d0913d170135205a008be447679c85ff2b0dd250646d810b563d893
|
|
| MD5 |
3cd91f2e0512ac45453017f3fa3b7c84
|
|
| BLAKE2b-256 |
34ba1ed970c3bb43c391910bff8c9b5da46e96f37c2bbfc07f260e8babf7de07
|
Provenance
The following attestation bundles were made for lx_tooling-0.8.0.tar.gz:
Publisher:
pypi.yml on labinetix/lx-tooling
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lx_tooling-0.8.0.tar.gz -
Subject digest:
ddf2cf6a5d0913d170135205a008be447679c85ff2b0dd250646d810b563d893 - Sigstore transparency entry: 1998931574
- Sigstore integration time:
-
Permalink:
labinetix/lx-tooling@81f79fba55f9d01f6bb2615e952f8ecf918d0cb5 -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/labinetix
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@81f79fba55f9d01f6bb2615e952f8ecf918d0cb5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file lx_tooling-0.8.0-py3-none-any.whl.
File metadata
- Download URL: lx_tooling-0.8.0-py3-none-any.whl
- Upload date:
- Size: 51.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5064b02bdaff242952245802e227a7842586eb2622a843ce27c18e51c8fefa8
|
|
| MD5 |
d5f60fb9c6a1402b8a2bc805202dce09
|
|
| BLAKE2b-256 |
a358c3febea537a7d040f13b944d3ac6cae7f0fa291d713f6b0f21378c5c331d
|
Provenance
The following attestation bundles were made for lx_tooling-0.8.0-py3-none-any.whl:
Publisher:
pypi.yml on labinetix/lx-tooling
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lx_tooling-0.8.0-py3-none-any.whl -
Subject digest:
e5064b02bdaff242952245802e227a7842586eb2622a843ce27c18e51c8fefa8 - Sigstore transparency entry: 1998931670
- Sigstore integration time:
-
Permalink:
labinetix/lx-tooling@81f79fba55f9d01f6bb2615e952f8ecf918d0cb5 -
Branch / Tag:
refs/tags/v0.8.0 - Owner: https://github.com/labinetix
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi.yml@81f79fba55f9d01f6bb2615e952f8ecf918d0cb5 -
Trigger Event:
push
-
Statement type: