Skip to content

v0.6.0 — Catalog selection filters + grouped --help

Choose a tag to compare

@yottayoshida yottayoshida released this 09 Aug 11:50
· 25 commits to main since this release
532e882

Summary: The catalog can now be sliced the way its metadata always allowed: --layer and --frequency filter search and list on both the CLI and MCP surfaces, and mpg list --with-content emits the selected guides in full — the shape to pipe into a generated system prompt. mpg --help groups the nine commands by purpose and shows runnable examples. A contributor's first commands now work as documented: ruff check . passes from the repository root, and an ordinary session no longer leaves the working tree dirty. One behavioural cost is recorded under Changed: the new option names make the --f and --l abbreviations ambiguous.

Added

  • search and list accept --layer and --frequency, and the search_guides / list_guides MCP tools accept the same two arguments. Filters are conjunctive, so --layer 1 --frequency high returns the intersection. retrieve is unchanged on both surfaces: it selects by explicit ID, and docs/design.md says so in two places. (closes #30, #31)
  • mpg list --with-content emits each selected guide's full body alongside its metadata, which is the shape to pipe into a generated system prompt or rules file. This is where bulk retrieval belongs — the requested retrieve --all would have made retrieve a selection command and contradicted the documented guarantee that it preserves explicitly requested IDs. The body is the same one retrieve serves, and the field is absent unless the flag is passed, so the default list schema is unchanged. (closes #29)
  • mpg --help groups the commands by what they are for and shows four runnable examples, instead of listing nine flat with no indication of how to invoke them. The grouping is composed by hand because argparse has no notion of it; the same table registers the subparsers, so a command cannot appear in the listing without existing, and adding one to the listing without wiring it up is now rejected rather than silently exiting 0. Tests compare the rendered help against the parser's own commands and parse every example shown, so a listing that drifts from the CLI fails rather than misleading. (closes #36)

Changed

  • Adding --layer and --frequency made two option abbreviations ambiguous that previously resolved: --f no longer selects --format, and --l no longer selects --limit, on both search and list. argparse accepts unambiguous prefixes by default, and the new options collide with the old ones; both now exit 2 with ambiguous option. Nothing inside this repository used the short forms, but a script that did will need them spelled out. Turning prefix matching off entirely would break every other abbreviation, so the behaviour stands and is documented instead.

Fixed

  • ruff check . from the repository root passes. It reported 34 violations, all of them in bench/fixtures, where outdated patterns are the point — so a contributor following the obvious command met a wall of failures that were never theirs to fix. Those fixtures are now excluded, and only those: the runner and scorers elsewhere under bench/ are still linted, which a test verifies by reading back the file list ruff says it will check. Excluding bench/ wholesale would have been shorter and would have quietly dropped the tooling too. CONTRIBUTING states the scope CI uses rather than leaving the two commands to disagree. (closes #123)

  • .coverage, uv.lock, and the paths mpg setup writes under .claude/ are now ignored, so an ordinary development session no longer leaves a dirty working tree. uv.lock is ignored rather than tracked because CI installs with uv pip install --system -e and never reads a lock file, so committing one would pin nothing; the choice is recorded next to the rule rather than left implicit. The .claude/ entries name individual paths instead of the directory: a directory-wide rule would silently swallow anything the project later decides to track there, whereas an unlisted path shows up in git status and gets a line added deliberately. A test asks git check-ignore for each path rather than grepping .gitignore, since a pattern being present and a path being ignored are different claims, and it pins in both directions — the generated paths stay hidden and project content stays visible. (closes #125)

  • Catalog selection by category now runs through a single predicate rather than four independent implementations of the same comparison — the scored search, the fuzzy fallback, mpg list, and the list_guides MCP tool each had their own. Nothing was broken beforehand; the point is that adding two filters to four separate sites is how a filter comes to be applied on three paths and quietly ignored on the fourth, and the MCP tool was the copy easiest to overlook because its sibling search_guides already delegates to the shared search. The accepted values for both new filters come from the frontmatter vocabulary the parser validates against, so the CLI choices, the MCP schema, and the parser cannot drift apart. The MCP server checks them in code as well: an enum in inputSchema is advertised to the client, not enforced by the server, and without the check layer: 99 would return an empty array — which reads as "no such guides" when it means "no such layer".