Add openarmature CLI and patterns API (agent-docs A3+A4)#73
Merged
Conversation
Two new agent-discovery surfaces that complement the bundled AGENTS.md from the previous release cycle: - openarmature.patterns exposes list() and get(name) reading the same patterns content as the bundled file via importlib.resources. Useful in sandboxed environments that can import openarmature but can't freely read arbitrary package paths. - openarmature CLI registers init (writes a discovery pointer block into the host project's AGENTS.md / CLAUDE.md) and docs (prints the bundled AGENTS.md path). The same surface is reachable as python -m openarmature via __main__.py for environments where the [project.scripts] entry point doesn't land cleanly. The CLI's pointer block is sourced from a canonical src/openarmature/_pointer_block.md so editing what init writes doesn't require touching Python code. init uses a comment marker (<!-- openarmature-init -->) for idempotency so renaming the visible heading doesn't fool the re-run detection. The generator at scripts/build_agents_md.py now emits per-pattern .md files under src/openarmature/_patterns/ with a programmatic-only transform (no heading demotion; intra-pattern links rewritten to absolute openarmature.ai URLs). The drift test extends to cover the new directory. __init__.py advertises all three discovery surfaces (bundled AGENTS.md, programmatic patterns API, CLI). README's "For AI agents" section mentions the CLI and the patterns API.
There was a problem hiding this comment.
Pull request overview
This PR adds two new discovery surfaces for OpenArmature’s agent documentation: a programmatic patterns API and an openarmature CLI, and updates the docs generator to ship per-pattern markdown files alongside the bundled AGENTS.md.
Changes:
- Add
openarmature.patternsAPI (list()/get(name)) backed by generated per-pattern resources undersrc/openarmature/_patterns/. - Add an
openarmatureCLI (init,docs) pluspython -m openarmatureentrypoint, and a canonical pointer-block template file. - Extend the drift/regeneration test and generator to cover both
AGENTS.mdand_patterns/outputs.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_patterns_api.py | Adds unit coverage for the new openarmature.patterns API behavior and contract. |
| tests/unit/test_cli.py | Adds unit coverage for CLI docs/init behavior (create/append/idempotent/force/dry-run). |
| tests/test_agents_md_drift.py | Extends drift checking to include generated _patterns/ artifacts. |
| src/openarmature/patterns.py | Implements the new programmatic patterns catalog using importlib.resources. |
| src/openarmature/cli.py | Implements the new argparse-based CLI and entrypoint function. |
| src/openarmature/_pointer_block.md | Adds canonical pointer block content used by openarmature init. |
| src/openarmature/_patterns/tool-dispatch-as-node.md | Adds generated per-pattern markdown payload file. |
| src/openarmature/_patterns/session-as-checkpoint-resume.md | Adds generated per-pattern markdown payload file. |
| src/openarmature/_patterns/parameterized-entry-point.md | Adds generated per-pattern markdown payload file. |
| src/openarmature/_patterns/bypass-if-output-exists.md | Adds generated per-pattern markdown payload file. |
| src/openarmature/_patterns/init.py | Marks _patterns as a package and documents its generated nature. |
| src/openarmature/main.py | Enables python -m openarmature to dispatch to the CLI. |
| src/openarmature/init.py | Updates top-level docs to advertise all discovery surfaces. |
| scripts/build_agents_md.py | Updates generator to emit _patterns/ files and splits transforms for bundle vs programmatic outputs. |
| README.md | Documents CLI usage and the programmatic patterns API. |
| pyproject.toml | Registers openarmature as a [project.scripts] entry point. |
| CHANGELOG.md | Adds changelog entries for the new CLI and patterns API. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Address two issues raised in PR #73 review: - _apply_init_to_file now reads and writes project AGENTS.md / CLAUDE.md with an explicit encoding="utf-8" on every read_text / write_text call. The platform default text encoding is not UTF-8 on Windows (cp1252), which would produce UnicodeDecodeError on UTF-8 content in existing files or mojibake when writing the pointer block. - _bundled_agents_md_path now uses importlib.resources.as_file to resolve the bundled AGENTS.md and raises RuntimeError with a clear message when the install isn't filesystem-backed (pure zipimport). Previously the function would print a non-existent path that the caller would then fail to open. cmd_docs handles the RuntimeError by printing the message to stderr and exiting with code 2. The docstring now claims only wheel and editable installs (the realistic shapes for this distribution) rather than implying "or zipped".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
openarmature.patternsprogrammatic API withlist()andget(name), exposing the same patterns content as the bundledAGENTS.mdviaimportlib.resources. Useful for agents in sandboxed environments that canimport openarmaturebut can't freely read arbitrary package paths.openarmatureCLI registered as a[project.scripts]entry point with two subcommands:init(writes a discovery pointer block into the project'sAGENTS.md/CLAUDE.md) anddocs(prints the bundledAGENTS.mdpath). Same surface reachable aspython -m openarmaturevia__main__.py.scripts/build_agents_md.pynow emits per-pattern.mdfiles undersrc/openarmature/_patterns/alongside the bundledAGENTS.md. Drift test extended to cover the new directory.The pointer block
initwrites is sourced from a canonicalsrc/openarmature/_pointer_block.mdso changing what it writes doesn't require touching Python code. Idempotency uses a comment marker (<!-- openarmature-init -->) so renaming the visible heading doesn't fool the re-run detection.__init__.pynow advertises all three discovery surfaces (bundledAGENTS.md, programmatic patterns API, CLI). README's "For AI agents" section mentions the CLI and the patterns API.Test plan
uv run pytest -qruns greenuv run openarmature --helpshows both subcommandsuv run openarmature docsprints the bundledAGENTS.mdpathuv run python -m openarmature docsprints the same pathuv run openarmature init --dry-run --cwd $(mktemp -d)reports two[dry-run] create:lines without writing filesuv run openarmature init --cwd <tmpdir>creates bothAGENTS.mdandCLAUDE.mdwith the## OpenArmaturesection +<!-- openarmature-init -->markeropenarmature initon the same directory reportsskip:for both filesopenarmature init --forcere-appends the block; file ends with two pointer blockspython -c "import openarmature.patterns as p; print(p.list())"returns four expected pattern slugspython -c "import openarmature.patterns as p; p.get('does-not-exist')"raisesKeyErrorwith the known names listed