Skip to content

ci: add GitHub Actions workflow - #1

Merged
ggrace519 merged 3 commits into
mainfrom
feat/ci-workflow
Aug 29, 2026
Merged

ci: add GitHub Actions workflow#1
ggrace519 merged 3 commits into
mainfrom
feat/ci-workflow

Conversation

@ggrace519

Copy link
Copy Markdown
Owner

Summary

Add CI workflow for automated testing and type checking on every push/PR to main.

What it runs

  • Test — Python 3.11, 3.12, 3.13 via uv, pytest with coverage reporting, Codecov upload
  • Typecheck — mypy on the graphlm/ package

Why uv

Faster dependency resolution, cached builds, and matches the project's own dev workflow.

- Validate project directory exists before config validation so the
  correct FileNotFoundError is raised for missing directories
- Fix loop variable name collision in render.py (edge vs flow)
- Fix llm.py last_error type annotation to Exception | None
- Fix call_llm return type to CodebaseGraph | str
- Use cast() for union return narrowing in __init__.py
- Fix ArchitectureNote dict -> model in dry-run code path
Path.walk() was added in Python 3.13. Replace with os.walk() to
maintain compatibility with the project's requires-python >=3.11.
@ggrace519
ggrace519 merged commit 9b711f8 into main Aug 29, 2026
4 checks passed
@ggrace519
ggrace519 deleted the feat/ci-workflow branch August 29, 2026 20:48
ggrace519 added a commit that referenced this pull request Sep 3, 2026
…ion #1) (#51)

* feat(query): pure query layer over a generated map (innovation #1)

The map's consumer is a coding agent, and a flat GRAPH.md makes it pay for
the whole document to answer "who imports X?". query.py answers each such
question over an already-materialized CodebaseGraph: a unified edge index
(deterministic_edges ∪ import_edges, labelled ast/llm/both), fuzzy path
resolution, overview, module_info, neighbors, dependents (BFS blast radius
with a cap), find (ranked search across the curated sections), cycles,
entry_points, staleness (stamped SHA vs HEAD), and load_map (reusing
diff.load_baseline so a corrupt map is reported, not misread).

No LLM, no network, no MCP dependency — this is the testable core the
--serve transport wraps.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XhMa9VQQPB5m1Z9tP3eP4M

* feat(cli): --serve exposes the map to agents over MCP (innovation #1)

Adds graphlm/mcp_server.py, a stdio MCP server (SDK v2) registering eight
zero-LLM tools over query.py — overview, find, module, neighbors,
dependents, cycles, entry_points, staleness. GRAPH.json is re-read when
its mtime changes so a regeneration mid-session is picked up; an
unreadable map is raised as ToolError so the agent sees the actionable
message instead of the SDK's masked "Error executing tool".

The mcp package is an optional extra (graphlm[mcp]); nothing outside
mcp_server.py imports it. The CLI flag short-circuits like --install-skill
(single-command Typer app), defaults PROJECT_DIR to '.', honours -o for
the map location, and checks the map exists BEFORE importing mcp so a
missing map reports 'run graphlm .' rather than an install hint. CI now
installs the extra so the in-memory-client server tests run; they
importorskip without it. The --install-skill guide tells the agent to
prefer the MCP tools when registered.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XhMa9VQQPB5m1Z9tP3eP4M

* docs: document graphlm --serve (MCP) and the mcp extra (innovation #1)

README section + options row + install note, CHANGELOG [Unreleased] entry,
CLAUDE.md architecture paragraph (query.py/mcp_server.py split, SDK v2
ToolError rule, extra + CI), and the branch DEMO.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XhMa9VQQPB5m1Z9tP3eP4M

* fix(query): drop question filler and match inflections in find

Verified on a real map: "where is the secret redaction" ranked every
quick-reference entry first because they all begin "Where is…" and the
scorer counted "where"/"is" as exact-token hits. Stopwords are now
stripped before scoring, and a >=4-char token matches a word it prefixes
(or that prefixes it) so "redaction" reaches "_redact_secrets".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XhMa9VQQPB5m1Z9tP3eP4M

* fix(query): review fixes — absolute paths, distinct-file degrees, anchored refs, find shape, clamps

Fresh-context review of --serve surfaced five query-layer bugs, each now
with a regression test:
- resolve_path could not match an absolute or repo-prefixed path (an
  agent's natural input) and answered "no such path" — now the longest
  known path that the query ends with wins; suffix candidates are capped.
- in/out degree in overview and module counted edge rows, so a file that
  both `import x` and `from x import y` counted twice — now distinct files.
- module's quick-reference lookup was an unanchored substring test
  (`a.py` claimed `data.py`) — now exact-file.
- find returned a shape without `total` for an all-stopword query (the
  test had locked the bug in); stopword-only queries now search the raw
  tokens instead of answering nothing.
- neighbors' direction is a Literal in the tool schema and ValueErrors are
  raised as ToolError, so the reason reaches the model instead of the
  SDK's masked "Error executing tool".
Also: model-supplied limits clamped to MAX_LIMIT, deterministic cycle
ordering on ties, and MapCache defers to load_map's classification so a
broken symlink reads as unreadable rather than "run graphlm .".

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XhMa9VQQPB5m1Z9tP3eP4M

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
ggrace519 added a commit that referenced this pull request Sep 3, 2026
Neither the test nor typecheck job writes anything (no releases, no PR
comments, no checks API calls), so scope the default GITHUB_TOKEN down
to contents: read. Least-privilege, no behavior change.

Fixes CodeQL actions/missing-workflow-permissions alerts #1 and #2.


Claude-Session: https://claude.ai/code/session_01XhMa9VQQPB5m1Z9tP3eP4M

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant