From 46fb114b14cfc05702e1f87e12b77ce2f3470f90 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 21 Mar 2026 16:00:03 +0000 Subject: [PATCH] feat: extend analysis pipeline for Python codebases and frameworks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - project-scanner: detect Python frameworks from requirements.txt, pyproject.toml, setup.py, Pipfile (django, fastapi, flask, sqlalchemy, celery, pydantic, etc.); add pyproject.toml to project name extraction - SKILL.md: expand Python entry points (manage.py, app.py, wsgi.py, asgi.py, run.py, __main__.py); add FastAPI and Flask framework guidance to Phase 2 and Phase 4 inline hints; wire addendum file injection for Django, FastAPI, and Flask when detected - architecture-analyzer: add __init__.py and manage.py as entry-point file-level patterns; add Python directory patterns (migrations, signals, serializers, management, templatetags); clarify *.d.ts is TS-only - tour-builder: add Python entry point filename patterns to +3 scoring (manage.py, app.py, wsgi.py, asgi.py, run.py, __main__.py) - file-analyzer: add __init__.py barrel/entry-point detection alongside index.ts; show Python script execution alternative in example - new: django-analyzer-addendum.md — canonical file roles, edge patterns (URL routing graph, signal wiring, ORM relationships), layer guide, and language lesson patterns for Django projects - new: fastapi-analyzer-addendum.md — canonical file roles, DI tree edge patterns, layer guide, and language lesson patterns for FastAPI and Flask - new: PYTHON-SUPPORT-CHANGES.md — reviewer doc covering every change, rationale, regression risk, and a testing checklist https://claude.ai/code/session_015ihoTRnr7yYx3TkcadKYbn --- .../understand/PYTHON-SUPPORT-CHANGES.md | 208 ++++++++++++++++++ .../skills/understand/SKILL.md | 14 +- .../architecture-analyzer-prompt.md | 13 +- .../understand/django-analyzer-addendum.md | 67 ++++++ .../understand/fastapi-analyzer-addendum.md | 109 +++++++++ .../skills/understand/file-analyzer-prompt.md | 7 +- .../understand/project-scanner-prompt.md | 7 +- .../skills/understand/tour-builder-prompt.md | 2 +- 8 files changed, 415 insertions(+), 12 deletions(-) create mode 100644 understand-anything-plugin/skills/understand/PYTHON-SUPPORT-CHANGES.md create mode 100644 understand-anything-plugin/skills/understand/django-analyzer-addendum.md create mode 100644 understand-anything-plugin/skills/understand/fastapi-analyzer-addendum.md diff --git a/understand-anything-plugin/skills/understand/PYTHON-SUPPORT-CHANGES.md b/understand-anything-plugin/skills/understand/PYTHON-SUPPORT-CHANGES.md new file mode 100644 index 0000000..39939a1 --- /dev/null +++ b/understand-anything-plugin/skills/understand/PYTHON-SUPPORT-CHANGES.md @@ -0,0 +1,208 @@ +# Python Codebase Support — Change Review Guide + +This document explains every change made to add Python and Python framework support. It is written for a reviewer who wants to verify correctness, spot regressions, and understand the rationale for each decision. + +--- + +## Background: What Was Wrong + +The tool worked well for TypeScript/JavaScript codebases. For Python codebases it would: +- Fail to detect frameworks (Django, FastAPI, Flask) — `frameworks: []` always +- Miss common Python entry points (`manage.py`, `app.py`, `wsgi.py`) — defaulting to no entry point +- Score Python entry points much lower than TS equivalents in the tour builder (4 Python patterns vs 8 JS/TS patterns) +- Miss Python's `__init__.py` as a barrel/entry-point equivalent (only `index.ts`/`index.js` were recognized) +- Have no layer guidance for FastAPI or Flask (only Django had a brief mention) +- Ignore `pyproject.toml` for project name extraction + +The bias was **only in agent prompts** (markdown files). The graph schema, dashboard, search engine, and core plugin architecture are language-agnostic and required no changes. + +--- + +## Files Changed + +### 1. `project-scanner-prompt.md` + +**What changed:** + +**Step 5 (Framework Detection)** — Extended the Python manifest reading from "confirms Python project" to actually detecting frameworks: +- `requirements.txt`: now reads line-by-line, strips version specifiers, and matches against a Python framework keyword list: `django`, `djangorestframework`, `fastapi`, `flask`, `sqlalchemy`, `alembic`, `celery`, `pydantic`, `uvicorn`, `gunicorn`, `aiohttp`, `tornado`, `starlette`, `pytest`, `hypothesis`, `channels` +- `pyproject.toml`: now parses `[project].dependencies` and `[tool.poetry.dependencies]`, applies the same keyword matching, and also checks for `[tool.pytest.ini_options]` (pytest) and `[tool.django]` (Django) +- `setup.py`, `setup.cfg`, `Pipfile`: now apply the same Python framework keyword matching + +**Step 7 (Project Name)** — Added `pyproject.toml` to the priority order between `go.mod` and directory name. Checks `[project].name` first, then `[tool.poetry].name`. + +**Why:** Without framework detection, `frameworks: []` is passed to every downstream agent. The framework-specific guidance injected in Phase 2 and Phase 4 of SKILL.md is only useful when `frameworks` is non-empty. + +**Regression risk:** None. The JS framework detection in `package.json` is unchanged. The Python additions are additive. + +**How to verify:** Run `/understand` on a Django project with `requirements.txt` containing `django`. Check that `scan-result.json` has `frameworks: ["Django"]`. + +--- + +### 2. `SKILL.md` + +**What changed:** + +**Phase 0 (entry point detection, line 57)** — Added Python entry points to the pattern list: +- Before: `src/index.ts`, `src/main.ts`, `src/App.tsx`, `main.py`, `main.go`, `src/main.rs`, `index.js` +- After: added `manage.py`, `app.py`, `wsgi.py`, `asgi.py`, `run.py`, `__main__.py` + +**Why:** A Django project's real entry point is `manage.py`. A FastAPI/Flask project uses `app.py` or `run.py`. Without these, `$ENTRY_POINT` is empty for most Python projects, and the tour builder gets no starting hint. + +**Phase 2 (file-analyzer framework guidance)** — Extended the inline framework hints: +- Django: added `serializers.py`, `signals.py`, `admin.py`, `migrations/` descriptions +- Added FastAPI: describes `@router` decorator files, Pydantic schemas, `Depends()` providers +- Added Flask: describes `@blueprint.route`, `blueprints/`, SQLAlchemy `models.py` +- Added addendum injection: if `Django` detected, reads `./django-analyzer-addendum.md` and appends to the file-analyzer prompt. If `FastAPI` or `Flask` detected, reads `./fastapi-analyzer-addendum.md` and appends. + +**Phase 4 (architecture-analyzer framework hints)** — Extended the inline layer hints: +- Django: added `serializers.py`, `signals.py`, `migrations/` → specific layers +- Added FastAPI: router files → API, Pydantic schemas → Types, `dependencies.py` → Service, DB files → Data +- Added Flask: blueprint route files → API, `models.py` → Data, `forms.py` → UI, `extensions.py` → Config +- Added addendum injection: same logic as Phase 2 + +**Regression risk:** Low. The addendum injection only triggers when those frameworks are in the detected list. The inline guidance additions are additive strings — they don't change the structure of the injected context. + +**How to verify:** +- Run on a FastAPI project: check `layers.json` has a `layer:types` or `layer:api` with Pydantic schema files assigned correctly +- Run on a TS project: check that no Django/FastAPI addendum content appears in the analysis (it shouldn't, since `frameworks` won't contain those values) + +--- + +### 3. `architecture-analyzer-prompt.md` + +**What changed:** + +**Directory pattern table** — Added Python-specific directory names: + +| Added | Pattern Label | Why | +|-------|---------------|-----| +| `migrations` | `data` | Django/Alembic migration directories hold schema history — Data Layer | +| `management`, `commands` | `config` | Django management command directories | +| `templatetags` | `utility` | Django custom template tag directories | +| `signals` | `service` | Signal handler modules — cross-cutting service logic | +| `serializers` | `api` | DRF serializer directories | + +**File-level pattern matching** — Three changes: +1. Added `test_*.py` to the test pattern (Python's `pytest` naming convention) +2. Added `__init__.py` at a directory root → `entry` pattern (Python package barrel equivalent of `index.ts`) +3. Added `manage.py` → `entry` and `wsgi.py`/`asgi.py` → `config` +4. Clarified `*.d.ts → types` with "(TypeScript declaration files only)" — making it explicit this is TS-specific so an LLM doesn't misapply it to Python + +**Why:** Without `__init__.py → entry`, the architecture analyzer would never recognize any Python file as an entry point via file-level patterns. The `hooks` pattern label was left as-is (it won't trigger on Python projects since they don't conventionally have a `hooks/` directory). + +**Note on Node.js script:** The architecture analyzer's structural analysis script is hardcoded to `node`. This is correct to leave as-is — the script processes the JSON graph structure (file nodes, import edges), not the source language of the codebase being analyzed. The script's input/output is always JSON regardless of whether the project is Python or TypeScript. + +**Regression risk:** Very low. Added rows to the directory pattern table and clarified file-level pattern descriptions. No existing patterns were removed or modified. + +**How to verify:** Run on a Django project. Check that `migrations/` directory files land in `layer:data` and that `manage.py` gets tagged `entry`. + +--- + +### 4. `tour-builder-prompt.md` + +**What changed:** + +**Entry point candidate scoring (Section C)** — Added Python entry points to the +3 filename list: +- Added: `manage.py`, `app.py`, `wsgi.py`, `asgi.py`, `run.py`, `__main__.py` + +Before this change, the entry point scoring had 8 TS/JS patterns vs 4 for all other languages. After: 8 TS/JS + 6 Python + 4 others. + +**Why:** The tour builder uses entry point scores to decide Step 1 of the tour. For a Django project where `manage.py` exists, it should score highly. Without this, the tour might start from a random high-fan-in utility file instead of the actual entry point. + +**The `languageLesson` example** was left as-is (TypeScript barrel files). This is just an illustrative example in the output format section — it does not affect how Python tours are generated. The language lessons section already lists Python-specific patterns (decorators, generators, context managers, metaclasses, protocols). + +**Regression risk:** None. The scoring list is additive. TS/JS entry points retain their +3 scores. + +**How to verify:** Run on a Django project. Check that `tour.json` starts from `manage.py` or `apps.py`/`wsgi.py` rather than a utility file. + +--- + +### 5. `file-analyzer-prompt.md` + +**What changed:** + +**Tags indicators — barrel/entry-point detection** — Extended the `index.ts` rule: +- Before: `Named index.ts at a directory root with re-exports = entry-point` +- After: Added `__init__.py` at a package root with imports or re-exports = `entry-point`, and `manage.py` = `entry-point` + +**Script execution example** — Added the Python equivalent command alongside the Node.js example. The base prompt already says "Choose the best language for this task — Node.js is recommended for TypeScript/JavaScript projects, Python for Python projects" (line 15), but the execution example only showed `node`. This created a contradiction. Now both are shown. + +**Regression risk:** None. Additive changes only. + +**How to verify:** Run on a Python project with a package structure. Check that `__init__.py` files at package roots get the `entry-point` or `barrel` tag rather than being treated as empty boilerplate files. + +--- + +## New Files Created + +### `django-analyzer-addendum.md` + +A detailed reference injected into the file-analyzer and architecture-analyzer when Django is detected. Contains: +- Canonical file roles table (15+ Django file types with appropriate tags) +- Edge patterns to look for (URL routing graph, signal wiring, ORM relationships, serializer→model binding) +- Layer assignment guide (7 layers: api, data, service, ui, middleware, config, test) +- Notable `languageLesson` patterns (fat models, ORM lazy evaluation, CBV mixins, signal anti-patterns, app isolation) + +**How it's injected:** SKILL.md reads this file and appends it to the base `file-analyzer-prompt.md` and `architecture-analyzer-prompt.md` content when `Django` appears in the detected frameworks list. + +### `fastapi-analyzer-addendum.md` + +A detailed reference for FastAPI and Flask projects, injected when either framework is detected. Contains two sections: + +**FastAPI section:** +- Canonical file roles (router files, Pydantic schemas, CRUD, dependencies, database session) +- Edge patterns (router inclusion chain, DI tree, Pydantic inheritance, CRUD→model binding) +- Layer assignment guide (7 layers) +- Notable `languageLesson` patterns (DI as composition, Pydantic validation, async vs sync, route order) + +**Flask section:** +- Canonical file roles (blueprints, application factory, WTForms, Marshmallow) +- Edge patterns (blueprint registration, extension coupling, before/after request hooks) +- Layer assignment guide +- Notable `languageLesson` patterns (factory pattern, blueprint modularity, extension `init_app` protocol) + +**How it's injected:** Same mechanism as the Django addendum — SKILL.md appends it when `FastAPI` or `Flask` is in the detected frameworks list. + +--- + +## What Was NOT Changed (And Why) + +| Component | Rationale | +|-----------|-----------| +| Graph schema (`types.ts`, `schema.ts`) | Already language-agnostic. All 18 edge types work for Python patterns. | +| `packages/core/src/plugins/tree-sitter-plugin.ts` | Still TS/JS only. Adding Python tree-sitter support is Phase 3 (separate PR). | +| `packages/core/src/plugins/registry.ts` | Extension map already has `.py → python`. A Python plugin will register here in Phase 3. | +| `packages/core/src/analyzer/language-lesson.ts` | Concept detection patterns. Phase 3 work. | +| Dashboard, search engine, skills | Already language-agnostic. | +| `tour-builder-prompt.md` language lessons example | The TypeScript barrel file example is illustrative only. Python tours will produce Python-specific `languageLesson` strings based on the language-lessons list (which already includes Python patterns). | +| Architecture analyzer `node` script execution | The script analyzes the graph JSON, not the source language. `node` is always correct here. | +| `hooks` directory pattern label | React-specific but harmless — Python projects don't conventionally have `hooks/` directories, so this label will never trigger on Python codebases. | + +--- + +## Testing Checklist for Reviewer + +For a Django project (e.g., a real Django app with `requirements.txt`): +- [ ] `scan-result.json` has `frameworks: ["Django"]` (or similar) +- [ ] `manage.py` is detected as `$ENTRY_POINT` in SKILL.md Phase 0 +- [ ] `manage.py` node gets tags including `entry-point` +- [ ] `urls.py` files get `api-handler`, `routing` tags +- [ ] `models.py` files get `data-model` tag +- [ ] `migrations/` directory files land in `layer:data` +- [ ] Tour Step 1 starts from `manage.py` or `wsgi.py` +- [ ] No TypeScript-specific guidance appears in the analysis output + +For a FastAPI project: +- [ ] `scan-result.json` has `frameworks: ["FastAPI"]` +- [ ] Router files get `api-handler`, `routing` tags +- [ ] Pydantic schema files get `type-definition`, `serialization` tags +- [ ] `dependencies.py` or `deps.py` gets `service` tag +- [ ] `depends_on` edges appear between router files and their dependencies +- [ ] `layer:types` exists with schema files + +For an existing TypeScript project (regression check): +- [ ] No Django/FastAPI addendum content appears in analysis +- [ ] `frameworks: ["React"]` (or whatever was there before) unchanged +- [ ] `src/index.ts` still detected as entry point +- [ ] All existing layer assignments and tour steps unchanged diff --git a/understand-anything-plugin/skills/understand/SKILL.md b/understand-anything-plugin/skills/understand/SKILL.md index 1327551..fd89b92 100644 --- a/understand-anything-plugin/skills/understand/SKILL.md +++ b/understand-anything-plugin/skills/understand/SKILL.md @@ -54,7 +54,7 @@ Determine whether to run a full analysis or incremental update. find $PROJECT_ROOT -maxdepth 2 -type f -not -path '*/node_modules/*' -not -path '*/.git/*' -not -path '*/dist/*' | head -100 ``` Store as `$DIR_TREE`. - - Detect the project entry point by checking for common patterns: `src/index.ts`, `src/main.ts`, `src/App.tsx`, `main.py`, `main.go`, `src/main.rs`, `index.js`. Store first match as `$ENTRY_POINT`. + - Detect the project entry point by checking for common patterns (in order): `src/index.ts`, `src/main.ts`, `src/App.tsx`, `index.js`, `main.py`, `manage.py`, `app.py`, `wsgi.py`, `asgi.py`, `run.py`, `__main__.py`, `main.go`, `src/main.rs`. Store first match as `$ENTRY_POINT`. --- @@ -98,7 +98,7 @@ After the subagent completes, read `$PROJECT_ROOT/.understand-anything/intermedi Batch the file list from Phase 1 into groups of **5-10 files each** (aim for balanced batch sizes). -For each batch, dispatch a subagent using the prompt template at `./file-analyzer-prompt.md`. Run up to **3 subagents concurrently** using parallel dispatch. Read the template once, then for each batch pass the full template content as the subagent's prompt, appending the following additional context: +For each batch, dispatch a subagent using the prompt template at `./file-analyzer-prompt.md`. Run up to **3 subagents concurrently** using parallel dispatch. Read the template once. If any detected framework is `Django`, also read `./django-analyzer-addendum.md` and append its full content after the base template. If any detected framework is `FastAPI` or `Flask`, also read `./fastapi-analyzer-addendum.md` and append its full content after the base template. Then for each batch pass the combined template content as the subagent's prompt, appending the following additional context: > **Additional context from main session:** > @@ -109,7 +109,9 @@ For each batch, dispatch a subagent using the prompt template at `./file-analyze > Framework-specific guidance: > - If React/Next.js: files in `app/` or `pages/` are routes, `components/` are UI, `lib/` or `utils/` are utilities > - If Express/Fastify: files in `routes/` are API endpoints, `middleware/` is middleware, `models/` or `db/` is data -> - If Python Django: `views.py` are controllers, `models.py` is data, `urls.py` is routing, `templates/` is UI +> - If Python Django: `views.py` are controllers, `models.py` is data, `urls.py` is routing, `templates/` is UI, `serializers.py` is API serialization, `signals.py` is event wiring, `admin.py` is admin registration, `migrations/` is schema history +> - If Python FastAPI: files with `@router.get/post/...` decorators are endpoints, `schemas.py` or `models.py` with Pydantic classes are request/response types, `dependencies.py` or `deps.py` holds `Depends()` providers, `routers/` or `api/` groups route modules +> - If Python Flask: files with `@app.route` or `@blueprint.route` are endpoints, `blueprints/` or `views/` groups route modules, `models.py` with SQLAlchemy classes is data > - If Go: `cmd/` is entry points, `internal/` is private packages, `pkg/` is public packages > > Use this context to produce more accurate summaries and better classify file roles. @@ -158,7 +160,7 @@ Merge all file-analyzer results into a single set of nodes and edges. Then perfo ## Phase 4 — ARCHITECTURE -Dispatch a subagent using the prompt template at `./architecture-analyzer-prompt.md`. Read the template file and pass the full content as the subagent's prompt, appending the following additional context: +Dispatch a subagent using the prompt template at `./architecture-analyzer-prompt.md`. If any detected framework is `Django`, also read `./django-analyzer-addendum.md` and append its full content after the base template. If any detected framework is `FastAPI` or `Flask`, also read `./fastapi-analyzer-addendum.md` and append its full content after the base template. Pass the combined content as the subagent's prompt, appending the following additional context: > **Additional context from main session:** > @@ -172,7 +174,9 @@ Dispatch a subagent using the prompt template at `./architecture-analyzer-prompt > Framework-specific layer hints: > - If React/Next.js: `app/` or `pages/` → UI Layer, `api/` → API Layer, `lib/` → Service Layer, `components/` → UI Layer > - If Express: `routes/` → API Layer, `controllers/` → Service Layer, `models/` → Data Layer, `middleware/` → Middleware Layer -> - If Python Django: `views/` → API Layer, `models/` → Data Layer, `templates/` → UI Layer, `management/` → CLI Layer +> - If Python Django: `views/` or `views.py` → API Layer, `models/` or `models.py` → Data Layer, `templates/` → UI Layer, `management/` → CLI Layer, `serializers.py` → API Layer, `signals.py` → Event Layer, `migrations/` → Data Layer +> - If Python FastAPI: files with router decorators → API Layer, Pydantic schema files → Types Layer, `dependencies.py` or `deps.py` → Service Layer, `routers/` or `api/` → API Layer, database session/engine files → Data Layer +> - If Python Flask: files with `@blueprint.route` → API Layer, `models.py` → Data Layer, `forms.py` → UI Layer, `extensions.py` → Config Layer > - If Go: `cmd/` → Entry Points, `internal/` → Service Layer, `pkg/` → Shared Library, `api/` → API Layer > > Use the directory tree and framework hints to inform layer assignments. Directory structure is strong evidence for layer boundaries. diff --git a/understand-anything-plugin/skills/understand/architecture-analyzer-prompt.md b/understand-anything-plugin/skills/understand/architecture-analyzer-prompt.md index 2200252..9728db3 100644 --- a/understand-anything-plugin/skills/understand/architecture-analyzer-prompt.md +++ b/understand-anything-plugin/skills/understand/architecture-analyzer-prompt.md @@ -82,11 +82,18 @@ Classify each directory name against known architectural patterns: | `hooks` | `hooks` | | `store`, `state`, `reducers`, `actions`, `slices` | `state` | | `assets`, `static`, `public` | `assets` | +| `migrations` | `data` | +| `management`, `commands` | `config` | +| `templatetags` | `utility` | +| `signals` | `service` | +| `serializers` | `api` | Also check file-level patterns: -- Files matching `*.test.*` or `*.spec.*` -> `test` -- Files matching `*.d.ts` -> `types` -- Files named `index.ts`/`index.js` at a package root -> `entry` +- Files matching `*.test.*` or `*.spec.*` or `test_*.py` -> `test` +- Files matching `*.d.ts` -> `types` (TypeScript declaration files only) +- Files named `index.ts`, `index.js`, or `__init__.py` at a package/directory root -> `entry` +- Files named `manage.py` at the project root -> `entry` (Django management entry point) +- Files named `wsgi.py` or `asgi.py` -> `config` (Python WSGI/ASGI server config) **F. Dependency Direction** diff --git a/understand-anything-plugin/skills/understand/django-analyzer-addendum.md b/understand-anything-plugin/skills/understand/django-analyzer-addendum.md new file mode 100644 index 0000000..e4c0601 --- /dev/null +++ b/understand-anything-plugin/skills/understand/django-analyzer-addendum.md @@ -0,0 +1,67 @@ +# Django Framework Addendum + +> Injected into file-analyzer and architecture-analyzer prompts when Django is detected. +> Do NOT use as a standalone prompt — always appended to the base prompt template. + +## Django Project Structure + +When analyzing a Django project, apply these additional conventions on top of the base analysis rules. + +### Canonical File Roles + +| File / Pattern | Role | Tags | +|---|---|---| +| `manage.py` | CLI entry point for dev server, migrations, management commands | `entry-point`, `config` | +| `*/settings.py`, `*/settings/*.py` | Project-wide configuration (DB, installed apps, middleware) | `config` | +| `*/urls.py` | URL routing — maps URL patterns to views | `api-handler`, `routing` | +| `*/views.py`, `*/views/*.py` | Request handlers (function-based or class-based views) | `api-handler`, `controller` | +| `*/models.py`, `*/models/*.py` | ORM models — map to database tables | `data-model` | +| `*/serializers.py` | DRF serializers — convert models to/from JSON | `serialization`, `api-handler` | +| `*/forms.py` | Django forms — validation and rendering logic | `validation`, `ui` | +| `*/admin.py` | Admin site registrations — exposes models in Django admin | `config` | +| `*/signals.py` | Signal handlers — cross-cutting side effects on model events | `event-handler` | +| `*/tasks.py` | Celery async task definitions | `service`, `event-handler` | +| `*/middleware.py`, `*/middleware/*.py` | Request/response middleware classes | `middleware` | +| `*/permissions.py` | DRF permission classes | `middleware`, `validation` | +| `*/filters.py` | DRF filter backends | `utility` | +| `*/migrations/*.py` | Auto-generated schema migrations — do not summarize individually | `config` | +| `*/templates/**/*.html` | Django HTML templates | `ui` | +| `*/templatetags/*.py` | Custom template filters and tags | `utility` | +| `*/management/commands/*.py` | Custom management commands (`./manage.py mycommand`) | `config`, `entry-point` | +| `wsgi.py`, `asgi.py` | WSGI/ASGI server adapter — production entry point | `config`, `entry-point` | +| `*/apps.py` | App configuration and startup hooks (`AppConfig`) | `config` | +| `*/tests.py`, `*/tests/*.py` | Unit and integration tests | `test` | + +### Edge Patterns to Look For + +**URL routing graph** — Create `calls` edges from `urls.py` nodes to their corresponding view nodes when `path()` or `re_path()` maps a URL pattern to a view function or class. These edges represent the HTTP routing chain. + +**Signal wiring** — When `signals.py` uses `post_save.connect(handler, sender=Model)` or `@receiver(post_save, sender=Model)`, create `subscribes` edges from the signal handler function to the model class. Create `publishes` edges from the model to the signal handler to show the trigger direction. + +**ORM relationships** — When `models.py` defines `ForeignKey`, `OneToOneField`, or `ManyToManyField`, create `relates_to` edges (use `depends_on` edge type) between the model classes with a description indicating the relationship type and cardinality. + +**Serializer-to-model binding** — When a DRF serializer has `model = MyModel` in its `Meta` class, create a `depends_on` edge from the serializer to the model. + +**View-to-serializer binding** — When a DRF ViewSet or APIView references a serializer class, create a `depends_on` edge from the view to the serializer. + +### Architectural Layers for Django + +Assign nodes to these layers when detected: + +| Layer ID | Layer Name | What Goes Here | +|---|---|---| +| `layer:api` | API Layer | `views.py`, `serializers.py`, `urls.py`, DRF ViewSets and APIViews | +| `layer:data` | Data Layer | `models.py`, `migrations/`, database utility files | +| `layer:service` | Service Layer | `signals.py`, `tasks.py`, custom managers, service modules | +| `layer:ui` | UI Layer | `templates/`, `forms.py`, `templatetags/` | +| `layer:middleware` | Middleware Layer | `middleware.py`, `permissions.py`, authentication backends | +| `layer:config` | Config Layer | `settings.py`, `urls.py` (root), `wsgi.py`, `asgi.py`, `apps.py`, `manage.py` | +| `layer:test` | Test Layer | `tests.py`, `tests/` directory, `conftest.py` | + +### Notable Patterns to Capture in languageLesson + +- **Fat models vs. thin views**: Django encourages business logic in model methods, keeping views thin HTTP adapters +- **Django ORM lazy evaluation**: QuerySets are not evaluated until iterated — chain filters without DB hits +- **Class-based views (CBVs)**: Mixins like `LoginRequiredMixin`, `PermissionRequiredMixin` compose behavior through multiple inheritance +- **Signal anti-patterns**: Signals create invisible coupling; a signal in `signals.py` may be triggered by a `save()` call anywhere in the codebase +- **App isolation**: Each Django app (`INSTALLED_APPS`) should be self-contained with its own models, views, urls, and migrations diff --git a/understand-anything-plugin/skills/understand/fastapi-analyzer-addendum.md b/understand-anything-plugin/skills/understand/fastapi-analyzer-addendum.md new file mode 100644 index 0000000..d8a71c6 --- /dev/null +++ b/understand-anything-plugin/skills/understand/fastapi-analyzer-addendum.md @@ -0,0 +1,109 @@ +# FastAPI / Flask Framework Addendum + +> Injected into file-analyzer and architecture-analyzer prompts when FastAPI or Flask is detected. +> Do NOT use as a standalone prompt — always appended to the base prompt template. + +## FastAPI Project Structure + +When analyzing a FastAPI project, apply these additional conventions on top of the base analysis rules. + +### Canonical File Roles — FastAPI + +| File / Pattern | Role | Tags | +|---|---|---| +| `main.py`, `app.py` | Application factory — creates and configures the `FastAPI()` instance | `entry-point`, `config` | +| `*/routers/*.py`, `*/api/*.py` | `APIRouter` modules — group related endpoints by domain | `api-handler`, `routing` | +| `*/schemas.py`, `*/schemas/*.py` | Pydantic request/response models | `type-definition`, `serialization` | +| `*/models.py`, `*/models/*.py` | SQLAlchemy ORM models or other DB models | `data-model` | +| `*/dependencies.py`, `*/deps.py` | `Depends()` provider functions — shared logic injected into routes | `service`, `middleware` | +| `*/crud.py`, `*/repository.py` | Database access layer — CRUD operations | `data-model`, `service` | +| `*/database.py`, `*/db.py` | DB engine, session factory, connection management | `config`, `data-model` | +| `*/config.py`, `*/settings.py` | `pydantic-settings` / `BaseSettings` config classes | `config` | +| `*/middleware.py` | Starlette middleware classes | `middleware` | +| `*/exceptions.py` | Custom exception classes and exception handlers | `utility` | +| `*/security.py`, `*/auth.py` | Auth utilities — JWT decoding, password hashing, OAuth helpers | `service`, `middleware` | +| `*/tasks.py` | Background tasks or Celery task definitions | `service`, `event-handler` | +| `*/tests/*.py`, `test_*.py` | pytest test files | `test` | +| `conftest.py` | pytest fixtures and test configuration | `test`, `config` | + +### Edge Patterns to Look For — FastAPI + +**Router inclusion chain** — When `app.include_router(some_router, prefix="/api")` appears in `main.py` or a router aggregator, create `imports` + `depends_on` edges from the main app file to each router module. This builds the URL hierarchy graph. + +**Dependency injection tree** — When a route function or another `Depends()` provider imports and calls `Depends(some_function)`, create `depends_on` edges from the caller to the dependency provider. Trace these chains — they often span multiple files (e.g., route → auth dependency → DB session dependency). + +**Pydantic model inheritance** — When a schema class inherits from another (e.g., `class UserCreate(UserBase)`), create `inherits` edges between the schema class nodes. + +**ORM model relationships** — When SQLAlchemy models use `relationship()`, `ForeignKey`, create `depends_on` edges between the model classes. + +**CRUD-to-model binding** — When a `crud.py` function takes a model type as an argument or directly references a model class, create `depends_on` edges from the CRUD file to the model file. + +### Architectural Layers for FastAPI + +| Layer ID | Layer Name | What Goes Here | +|---|---|---| +| `layer:api` | API Layer | Router files, endpoint functions with `@router.get/post/...` decorators | +| `layer:types` | Types Layer | Pydantic schema files, request/response models | +| `layer:service` | Service Layer | `dependencies.py`, `crud.py`, business logic modules | +| `layer:data` | Data Layer | ORM models, `database.py`, migrations | +| `layer:config` | Config Layer | `main.py` / `app.py` factory, `settings.py`, `config.py` | +| `layer:middleware` | Middleware Layer | `middleware.py`, `security.py`, `auth.py`, exception handlers | +| `layer:test` | Test Layer | `tests/`, `conftest.py` | + +### Notable Patterns to Capture in languageLesson + +- **Dependency injection as composition**: FastAPI's `Depends()` is a first-class DI system — a route can declare any number of dependencies, each of which can have their own dependencies, forming a tree resolved at request time +- **Pydantic for validation**: Request bodies, query params, and path params are automatically validated by Pydantic — invalid input raises `422 Unprocessable Entity` before your code runs +- **Async endpoints**: `async def` routes run in the event loop; `def` routes run in a threadpool — mixing them incorrectly can cause performance issues +- **Path operation order**: FastAPI matches routes in declaration order; a catch-all route before a specific one will shadow it + +--- + +## Flask Project Structure + +When analyzing a Flask project, apply these additional conventions on top of the base analysis rules. + +### Canonical File Roles — Flask + +| File / Pattern | Role | Tags | +|---|---|---| +| `app.py`, `__init__.py` (in app package) | Application factory (`create_app()`) or direct `Flask(__name__)` instance | `entry-point`, `config` | +| `run.py`, `wsgi.py` | Production/dev server entry point | `entry-point`, `config` | +| `*/views.py`, `*/routes.py` | Route handler functions with `@app.route` or `@blueprint.route` | `api-handler`, `routing` | +| `*/blueprints/*.py`, `*/api/*.py` | Blueprint modules — group routes by feature | `api-handler`, `routing` | +| `*/models.py` | SQLAlchemy models or other ORM models | `data-model` | +| `*/forms.py` | WTForms form classes | `validation`, `ui` | +| `*/schemas.py` | Marshmallow serialization schemas | `serialization`, `type-definition` | +| `*/config.py` | Config classes (`DevelopmentConfig`, `ProductionConfig`) | `config` | +| `*/extensions.py` | Flask extension initialization (`db = SQLAlchemy()`, `login_manager = LoginManager()`) | `config`, `singleton` | +| `*/decorators.py` | Custom route decorators (auth guards, rate limiting) | `middleware`, `utility` | +| `*/utils.py`, `*/helpers.py` | Shared utility functions | `utility` | +| `*/templates/**/*.html` | Jinja2 templates | `ui` | +| `*/static/` | CSS, JS, and asset files | `assets` | +| `*/tests/*.py`, `test_*.py` | pytest or unittest test files | `test` | + +### Edge Patterns to Look For — Flask + +**Blueprint registration** — When `app.register_blueprint(bp, url_prefix='/api')` appears in the application factory, create `depends_on` edges from the app factory to each blueprint module. + +**Extension coupling** — When a view imports from `extensions.py` (e.g., `from .extensions import db, login_manager`), create `imports` edges to show which views depend on which extensions. + +**Before/after request hooks** — When `@app.before_request` or `@blueprint.before_request` decorates a function, create `middleware` edges from those functions to the app/blueprint they attach to. + +### Architectural Layers for Flask + +| Layer ID | Layer Name | What Goes Here | +|---|---|---| +| `layer:api` | API Layer | Blueprint route files, view functions | +| `layer:data` | Data Layer | `models.py`, database migration files | +| `layer:service` | Service Layer | Business logic modules, `schemas.py`, service classes | +| `layer:ui` | UI Layer | `templates/`, `forms.py`, `static/` | +| `layer:config` | Config Layer | `app.py` factory, `config.py`, `extensions.py` | +| `layer:middleware` | Middleware Layer | `decorators.py`, before/after request hooks | +| `layer:test` | Test Layer | Test files, `conftest.py` | + +### Notable Patterns to Capture in languageLesson + +- **Application factory pattern**: `create_app()` functions allow multiple app instances (e.g., for testing) and delay extension initialization — avoids circular imports +- **Blueprint modularity**: Blueprints group related routes, templates, and static files; they are registered on the app with a URL prefix, making them independently testable +- **Flask extension protocol**: Extensions follow `init_app(app)` for lazy initialization — the extension object is created globally but bound to an app instance later diff --git a/understand-anything-plugin/skills/understand/file-analyzer-prompt.md b/understand-anything-plugin/skills/understand/file-analyzer-prompt.md index 4f28e77..0ab0cf1 100644 --- a/understand-anything-plugin/skills/understand/file-analyzer-prompt.md +++ b/understand-anything-plugin/skills/understand/file-analyzer-prompt.md @@ -125,7 +125,10 @@ ENDJSON After writing the script, execute it. **Use the batch index in every temp file path** — multiple file-analyzer agents run in parallel and must not overwrite each other's files: ```bash +# For Node.js scripts: node /tmp/ua-file-extract-.js /tmp/ua-file-analyzer-input-.json /tmp/ua-file-extract-results-.json +# For Python scripts: +python3 /tmp/ua-file-extract-.py /tmp/ua-file-analyzer-input-.json /tmp/ua-file-extract-results-.json ``` If the script exits with a non-zero code, read stderr, diagnose the issue, fix the script, and re-run. You have up to 2 retry attempts. @@ -166,7 +169,9 @@ Indicators from script data: - Filename contains `.test.` or `.spec.` = `test` - Exports a class with `Handler` or `Controller` in the name = `api-handler` - Only type/interface exports = `type-definition` -- Named `index.ts` at a directory root with re-exports = `entry-point` +- Named `index.ts` or `index.js` at a directory root with re-exports = `entry-point` (JavaScript/TypeScript barrel) +- Named `__init__.py` at a package root with imports or re-exports = `entry-point` (Python package barrel) +- Named `manage.py` = `entry-point` (Django management script) **Language Notes** (optional, your expert judgment): If the structural data reveals notable language-specific patterns (e.g., many generic type parameters, decorator usage, complex trait bounds), add a brief `languageNotes` string. Only add this when genuinely educational. diff --git a/understand-anything-plugin/skills/understand/project-scanner-prompt.md b/understand-anything-plugin/skills/understand/project-scanner-prompt.md index 30112ab..2b88af1 100644 --- a/understand-anything-plugin/skills/understand/project-scanner-prompt.md +++ b/understand-anything-plugin/skills/understand/project-scanner-prompt.md @@ -81,7 +81,9 @@ Read config files (if they exist) and extract framework information: - `tsconfig.json` -- if present, confirms TypeScript usage - `Cargo.toml` -- if present, confirms Rust project; extract `[package].name` - `go.mod` -- if present, confirms Go project; extract module name -- `requirements.txt` / `pyproject.toml` / `setup.py` / `Pipfile` -- if present, confirms Python project +- `requirements.txt` -- if present, confirms Python project; read line by line and match package names (strip version specifiers) against known Python frameworks: `django`, `djangorestframework`, `fastapi`, `flask`, `sqlalchemy`, `alembic`, `celery`, `pydantic`, `uvicorn`, `gunicorn`, `aiohttp`, `tornado`, `starlette`, `pytest`, `hypothesis`, `channels` +- `pyproject.toml` -- if present, confirms Python project; parse the `[project].dependencies` or `[tool.poetry.dependencies]` section and apply the same Python framework keyword matching as above. Also check for `[tool.pytest.ini_options]` (confirms pytest) and `[tool.django]` (confirms Django). +- `setup.py` / `setup.cfg` / `Pipfile` -- if present, confirms Python project; read and apply Python framework keyword matching - `Gemfile` -- if present, confirms Ruby project - `pom.xml` / `build.gradle` -- if present, confirms Java project @@ -99,7 +101,8 @@ Extract from (in priority order): 1. `package.json` `name` field 2. `Cargo.toml` `[package].name` 3. `go.mod` module path (last segment) -4. Directory name of project root +4. `pyproject.toml` -- check `[project].name` first, then `[tool.poetry].name` +5. Directory name of project root ### Script Output Format diff --git a/understand-anything-plugin/skills/understand/tour-builder-prompt.md b/understand-anything-plugin/skills/understand/tour-builder-prompt.md index fbfb8c6..dca4353 100644 --- a/understand-anything-plugin/skills/understand/tour-builder-prompt.md +++ b/understand-anything-plugin/skills/understand/tour-builder-prompt.md @@ -46,7 +46,7 @@ For every node, count how many other nodes it has edges pointing TO (fan-out). H **C. Entry Point Candidates** Identify likely entry points using these signals (score each file node, sum the scores): -- Filename matches `index.ts`, `index.js`, `main.ts`, `main.js`, `app.ts`, `app.js`, `server.ts`, `server.js`, `mod.rs`, `main.go`, `main.py`, `main.rs` -> +3 points +- Filename matches `index.ts`, `index.js`, `main.ts`, `main.js`, `app.ts`, `app.js`, `server.ts`, `server.js`, `mod.rs`, `main.go`, `main.py`, `main.rs`, `manage.py`, `app.py`, `wsgi.py`, `asgi.py`, `run.py`, `__main__.py` -> +3 points - Node tags contain `entry-point` or `barrel` -> +2 points - File is at the project root or one level deep (e.g., `src/index.ts`) -> +1 point - High fan-out (top 10%) -> +1 point