diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 119e4efa1..1305efdf9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -91,6 +91,7 @@ repos: hooks: - id: mdformat language: python + exclude: ^skills/[^/]+/SKILL\.md$ # Optionally add plugins additional_dependencies: - mdformat-gfm diff --git a/skills.sh.json b/skills.sh.json new file mode 100644 index 000000000..932f19021 --- /dev/null +++ b/skills.sh.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://skills.sh/schemas/skills.sh.schema.json", + "notGrouped": "bottom", + "groupings": [ + { + "title": "Code Graphs", + "description": "Skills for codebase graph inspection and safe codemods.", + "skills": ["graph-sitter"] + } + ] +} diff --git a/skills/graph-sitter/SKILL.md b/skills/graph-sitter/SKILL.md new file mode 100644 index 000000000..f1d626f70 --- /dev/null +++ b/skills/graph-sitter/SKILL.md @@ -0,0 +1,109 @@ +--- +name: graph-sitter +description: Use Graph-sitter to inspect, query, and transform Python, TypeScript, JavaScript, and React repositories through `uvx graph-sitter` or the local Python API. Trigger when Codex needs semantic codebase graphs, symbol discovery, call graph or usage tracing, import/dependency analysis, graph-aware renames, codemod execution, large-repo parse diagnostics, or safe structural edits. +--- + +# Graph-sitter + +Graph-sitter is the codebase graph and codemod layer. Use it when ordinary text search is too weak: find exact symbols first, inspect file structure, trace inbound or outbound calls, then perform graph-aware transformations only after check-mode validation. + +## Load References + +- Read `references/cli.md` when using `graph-sitter`, `uvx graph-sitter`, `parse`, `diagnose`, `inspect`, `symbols`, `callgraph`, `using`, `usages`, or `rename`. +- Read `references/codemods.md` before writing or running a codemod, `transform`, `run`, or any command that may change files. +- Read `references/rust-backend.md` before making Rust backend, fallback, TypeScript large-repo, performance, memory, parity, wheel, or release claims. + +## Choose The Interface + +1. Use `uvx graph-sitter ...` for released package workflows and one-shot use outside the Graph-sitter checkout. +1. Use `uv run graph-sitter ...` when working inside a local Graph-sitter source checkout. +1. Use the Python API when the task needs custom traversal, filtering, or codemod logic beyond a built-in CLI command. +1. Use ordinary `rg`, editor inspection, and project tests alongside Graph-sitter; do not replace cheap local evidence with a graph query when text search is enough. + +There is no `uvx` equivalent for installing skills from `skills.sh`; use `npx skills add ...` for skill installation and `uvx graph-sitter ...` for running the Python package. + +## Core Workflow + +1. Start with repository state: + + ```bash + git status --short + uvx graph-sitter doctor --json + ``` + +1. Parse or diagnose before deeper graph queries: + + ```bash + uvx graph-sitter parse /path/to/repo --language auto --backend python --format json + uvx graph-sitter diagnose /path/to/repo --language auto --backend auto --fallback python --json + ``` + +1. Find exact targets before tracing or renaming: + + ```bash + uvx graph-sitter symbols runInference /path/to/repo --kind function + ``` + +1. Use copyable target strings from `symbols`. Targets may be globally unique names, `path/to/file.py:handler`, `path/to/file.py::handler`, or dotted file targets such as `src/app.py.handler`. + +1. Prefer scoped parsing on large monorepos: + + ```bash + uvx graph-sitter inspect packages/app/src/index.ts /repo --subdir packages/app --level calls + uvx graph-sitter usages packages/app/src/index.ts.main /repo --subdir packages/app --depth 2 --resolved-only --local-only --dedupe + ``` + +## Common Tasks + +Use `inspect` for a file summary: + +```bash +uvx graph-sitter inspect src/app.py /repo --level functions +uvx graph-sitter inspect packages/app/src/index.ts /repo --level full --format json +``` + +Use `using`, `usages`, or `callgraph` for structure: + +```bash +uvx graph-sitter using src/app.py.handler /repo --depth 2 --resolved-only --local-only --dedupe +uvx graph-sitter usages src/app.py.helper /repo --depth 2 --resolved-only --local-only --dedupe +uvx graph-sitter callgraph src/app.py.handler /repo --direction outbound --depth 3 +uvx graph-sitter callgraph src/app.py.handler /repo --direction inbound --depth 2 +``` + +Use `rename` only after check mode: + +```bash +uvx graph-sitter rename src/app.py.helper /repo --to execute_helper --check +uvx graph-sitter rename src/app.py.helper /repo --to execute_helper --write +``` + +Use `transform` for ad hoc codemods and `run` for registered workspace codemods. Always run `--check` before `--write`. + +```bash +uvx graph-sitter transform ./codemod.py:run /repo --check +uvx graph-sitter run rename-symbol /repo --check +``` + +## Python API + +Use the Python API for custom analysis: + +```python +from graph_sitter import Codebase + +codebase = Codebase("/path/to/repo") +source_file = codebase.get_file("src/app.py") +handler = source_file.get_function("handler") +print([dependency.name for dependency in handler.dependencies]) +``` + +Prefer targeted file and symbol lookups over broad graph materialization in large repos. + +## Safety Rules + +- Run `git status --short` before any mutation. +- Use `--format json` when downstream parsing matters. +- Use `--check` before `--write` for `rename`, `transform`, and `run`. +- Inspect `git diff` after a write, then run focused tests or type checks for touched code. +- Keep Rust-backend claims scoped to the supported subset and validated package/platform. diff --git a/skills/graph-sitter/agents/openai.yaml b/skills/graph-sitter/agents/openai.yaml new file mode 100644 index 000000000..d4f95e8cf --- /dev/null +++ b/skills/graph-sitter/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Graph-sitter" + short_description: "Map and codemod codebase graphs" + default_prompt: "Use $graph-sitter to inspect this repository's call graph and plan the safest change." diff --git a/skills/graph-sitter/references/cli.md b/skills/graph-sitter/references/cli.md new file mode 100644 index 000000000..1c9117232 --- /dev/null +++ b/skills/graph-sitter/references/cli.md @@ -0,0 +1,151 @@ +# CLI Reference + +Use this reference when the task can be handled through `graph-sitter` commands rather than custom Python. + +## Invocation + +Use the released package with `uvx`: + +```bash +uvx graph-sitter --help +uvx graph-sitter COMMAND --help +``` + +Use the local source checkout with `uv run`: + +```bash +uv run graph-sitter --help +uv run graph-sitter COMMAND --help +``` + +`graph-sitter` is the canonical command. `gs` is a compatibility alias. + +## Install And Skill Distribution + +Install this skill through the skills CLI, not `uvx`: + +```bash +npx skills add codegen-sh/graph-sitter +``` + +Use `uvx` to run the Graph-sitter Python package: + +```bash +uvx graph-sitter parse /path/to/repo --format json +``` + +## Shared Parse Options + +Most graph commands accept: + +- `--backend python|rust|auto`: choose the graph backend. +- `--fallback python|error`: control behavior when Rust is unavailable or unsupported. +- `--language auto|python|typescript`: choose language detection explicitly. +- `--subdir PATH`: limit parsing to a repo-relative file or directory; repeat it for multiple scopes. +- `--format summary|json`: choose human-readable or machine-readable output. + +Prefer `--subdir` for monorepos when the user asks about a package, service, or file cluster. + +## Parse And Diagnose + +Use `parse` for count summaries and machine-readable graph size signals: + +```bash +uvx graph-sitter parse /repo --language auto --backend python --format json +uvx graph-sitter parse /repo --language typescript --backend rust --fallback error --format json +uvx graph-sitter parse /repo --subdir packages/app --format json +``` + +Use `diagnose` when wall time, memory, parse errors, or backend behavior matters: + +```bash +uvx graph-sitter diagnose /repo --language auto --backend auto --fallback python --json +uvx graph-sitter diagnose /repo --language typescript --backend rust --fallback error --json +``` + +Use `doctor` for installation readiness: + +```bash +uvx graph-sitter doctor --json +uvx graph-sitter doctor --backend rust --language python --json +uvx graph-sitter doctor --backend rust --language typescript --json +``` + +## Inspect Files + +Use `inspect` for source-file structure, line numbers, and per-function call summaries: + +```bash +uvx graph-sitter inspect src/app.py /repo --level summary +uvx graph-sitter inspect src/app.py /repo --level functions +uvx graph-sitter inspect src/app.py /repo --level calls +uvx graph-sitter inspect src/app.py /repo --level full --format json +``` + +Useful limits: + +- `--max-functions N`: cap function records. +- `--max-calls N`: cap per-function call names. + +## Resolve Targets + +Start with `symbols` when a target is not exact: + +```bash +uvx graph-sitter symbols runInference /repo --kind function +uvx graph-sitter symbols AuthService /repo --kind class --format json +``` + +Use target strings printed by `symbols`. Supported forms include: + +- `qualifiedName` when globally unique. +- `path/to/file.py:function_name`. +- `path/to/file.py::function_name`. +- `path/to/file.py.function_name`. +- `path/to/file.py.ClassName.method_name`. + +If Graph-sitter reports ambiguity, rerun `symbols` with a narrower query or add the file path. + +## Trace Calls + +Use `using` for outbound callees: + +```bash +uvx graph-sitter using src/app.py.handler /repo --depth 2 --resolved-only --local-only --dedupe +``` + +Use `usages` for inbound callers and usage sites: + +```bash +uvx graph-sitter usages src/app.py.helper /repo --depth 2 --resolved-only --local-only --dedupe +``` + +Use `callgraph` for a clean first-party trace; it defaults to resolved, local, deduped edges unless `--raw` is passed: + +```bash +uvx graph-sitter callgraph src/app.py.handler /repo --direction outbound --depth 3 +uvx graph-sitter callgraph src/app.py.helper /repo --direction inbound --depth 2 +``` + +Filtering options for `using` and `usages`: + +- `--resolved-only`: drop unresolved calls. +- `--local-only`: keep only parsed local files on both sides. +- `--hide-runtime`: suppress common runtime/library helpers. +- `--dedupe`: collapse repeated source/target/call triples. + +## Rename + +Run check mode first: + +```bash +uvx graph-sitter rename src/app.py.helper /repo --to execute_helper --check --format json +``` + +Apply only after reviewing the target, counts, and affected files: + +```bash +uvx graph-sitter rename src/app.py.helper /repo --to execute_helper --write +``` + +Follow with `git diff` and focused tests. diff --git a/skills/graph-sitter/references/codemods.md b/skills/graph-sitter/references/codemods.md new file mode 100644 index 000000000..d224e9b35 --- /dev/null +++ b/skills/graph-sitter/references/codemods.md @@ -0,0 +1,60 @@ +# Codemod Reference + +Use this before writing or running Graph-sitter transformations. + +## Import-Path Transform + +Create a Python module with a function that accepts `codebase`: + +```python +def run(codebase): + source_file = codebase.get_file("src/app.py") + target = source_file.get_function("old_name") + target.rename("new_name") + codebase.commit() +``` + +Preview first: + +```bash +uvx graph-sitter transform ./codemod.py:run /repo --check --diff-preview 200 +``` + +Apply only after reviewing the diff: + +```bash +uvx graph-sitter transform ./codemod.py:run /repo --write +``` + +The transform loader also accepts `Codemod` subclasses or instances with `execute(codebase)`. + +## Arguments + +Pass JSON to transforms that accept an `arguments` parameter: + +```bash +uvx graph-sitter transform ./codemod.py:run /repo --arguments '{"old":"foo","new":"bar"}' --check +``` + +Prefer explicit Pydantic argument models in reusable codemods so invalid inputs fail early. + +## Registered Workspace Codemods + +Use `run` when the repository already has registered `.codegen/codemods` functions: + +```bash +uvx graph-sitter run rename-symbol /repo --check --arguments '{"name":"new_name"}' +uvx graph-sitter run rename-symbol /repo --write --arguments '{"name":"new_name"}' +``` + +`run` still writes by default for compatibility. Always pass `--check` or `--write` explicitly in agent workflows. + +## Safety Workflow + +1. Inspect `git status --short` before running the codemod. +1. Run with `--check` and review the diff. +1. Use `--write` only when the diff matches the requested change. +1. Inspect `git diff` after writing. +1. Run focused tests, type checks, or linters for touched files. + +For ordinary user codemods, call `codebase.commit()` after edits. Use stricter commit options only when the repository already documents that pattern or the task explicitly needs compact Rust-backend mutation proof. diff --git a/skills/graph-sitter/references/rust-backend.md b/skills/graph-sitter/references/rust-backend.md new file mode 100644 index 000000000..9d42aac0c --- /dev/null +++ b/skills/graph-sitter/references/rust-backend.md @@ -0,0 +1,81 @@ +# Rust Backend Reference + +Use this before making Rust backend, TypeScript large-repo, fallback, performance, memory, parity, wheel, or release claims. + +## Backend Modes + +Configure the Python API through `CodebaseConfig`: + +```python +from graph_sitter.configs.models.codebase import CodebaseConfig, GraphBackend, RustFallbackMode + +CodebaseConfig(graph_backend=GraphBackend.PYTHON) +CodebaseConfig(graph_backend=GraphBackend.RUST, rust_fallback=RustFallbackMode.ERROR) +CodebaseConfig(graph_backend=GraphBackend.RUST, rust_fallback=RustFallbackMode.PYTHON) +CodebaseConfig(graph_backend=GraphBackend.AUTO) +``` + +CLI equivalents: + +```bash +uvx graph-sitter parse /repo --backend python +uvx graph-sitter parse /repo --backend rust --fallback error +uvx graph-sitter diagnose /repo --backend auto --fallback python --json +``` + +## Claims To Make + +Use precise language: + +- "supported Rust-backend subset" +- "selected pinned large-repo parity" +- "Rust-backed parse/diagnose on this package/platform" +- "Python backend remains the compatibility backend" + +Avoid overclaims: + +- complete graph-wide parity +- absolute semantic correctness +- Rust backend is always the default +- Rust-backed `uvx` works from PyPI before release validation proves it + +## Validation + +Check installation and strict Rust readiness: + +```bash +uvx graph-sitter doctor --backend rust --language python --json +uvx graph-sitter doctor --backend rust --language typescript --json +``` + +Measure parse time and memory: + +```bash +uvx graph-sitter diagnose /repo --language typescript --backend rust --fallback error --json +``` + +For local Graph-sitter source work, use repository gates when Rust backend behavior changes: + +```bash +rust-rewrite/tools/check_fast.sh +rust-rewrite/tools/check_pinned_large_repos.sh +``` + +Run large pinned checks only when the change touches Rust backend behavior, performance claims, packaging, or large-repo parsing. + +## Large Repos + +Prefer Rust for broad TypeScript and monorepo discovery when strict support is available: + +```bash +uvx graph-sitter parse /repo --language typescript --backend rust --fallback error --format json +uvx graph-sitter callgraph packages/app/src/index.ts.main /repo --language typescript --backend rust --depth 2 +``` + +Prefer scoped Python queries when inbound call-site detail or unsupported semantic surfaces are required: + +```bash +uvx graph-sitter usages packages/app/src/index.ts.main /repo --language typescript --backend python --subdir packages/app --depth 2 +``` + +When reporting performance, include repo path or commit, platform, Python version, package source, backend, fallback mode, wall time, peak RSS, and whether broad JSON output or Python graph materialization was requested.