mirror of
https://github.com/Egonex-AI/Understand-Anything.git
synced 2026-06-22 10:58:03 +08:00
feat(agents): extend tour builder for non-code file stops
Allow non-code files as tour stops: README.md as step 1, Dockerfile, SQL migrations, CI configs, and other infrastructure files. Add non-code file inventory computation to the topology script. Add languageLesson concepts for Dockerfile (multi-stage builds), SQL (normalization), YAML (CI/CD triggers), Terraform (state management), GraphQL (type system), Protobuf (backward compatibility), and Kubernetes (deployments). Update pedagogical flow to weave non-code stops into the narrative naturally. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
7c8f056447
commit
83040be895
@@ -6,7 +6,7 @@ You are an expert technical educator who designs learning paths through codebase
|
||||
|
||||
## Task
|
||||
|
||||
Given a codebase's nodes, edges, and layers, design a guided tour that teaches the project's architecture and key concepts. The tour must reference only real node IDs from the provided graph data. You will accomplish this in two phases: first, write and execute a script that computes structural properties of the graph to identify key files and dependency paths; second, use those insights to design the pedagogical flow.
|
||||
Given a codebase's nodes, edges, and layers, design a guided tour that teaches the project's architecture and key concepts. The tour must reference only real node IDs from the provided graph data. The tour should include both code and non-code files (documentation, infrastructure, data schemas) to give a complete picture of the project. You will accomplish this in two phases: first, write and execute a script that computes structural properties of the graph to identify key files and dependency paths; second, use those insights to design the pedagogical flow.
|
||||
|
||||
---
|
||||
|
||||
@@ -20,13 +20,19 @@ Write a Node.js script that analyzes the graph's topology to surface structural
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{"id": "file:src/index.ts", "type": "file", "name": "index.ts", "filePath": "src/index.ts", "summary": "..."}
|
||||
{"id": "file:src/index.ts", "type": "file", "name": "index.ts", "filePath": "src/index.ts", "summary": "..."},
|
||||
{"id": "document:README.md", "type": "document", "name": "README.md", "filePath": "README.md", "summary": "..."},
|
||||
{"id": "service:Dockerfile", "type": "service", "name": "Dockerfile", "filePath": "Dockerfile", "summary": "..."},
|
||||
{"id": "config:package.json", "type": "config", "name": "package.json", "filePath": "package.json", "summary": "..."}
|
||||
],
|
||||
"edges": [
|
||||
{"source": "file:src/index.ts", "target": "file:src/utils.ts", "type": "imports"}
|
||||
{"source": "file:src/index.ts", "target": "file:src/utils.ts", "type": "imports"},
|
||||
{"source": "service:Dockerfile", "target": "file:src/index.ts", "type": "deploys"},
|
||||
{"source": "document:README.md", "target": "file:src/index.ts", "type": "documents"}
|
||||
],
|
||||
"layers": [
|
||||
{"id": "layer:core", "name": "Core", "description": "Core application logic"}
|
||||
{"id": "layer:core", "name": "Core", "description": "Core application logic"},
|
||||
{"id": "layer:infrastructure", "name": "Infrastructure", "description": "Deployment and CI/CD"}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -45,12 +51,18 @@ 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):
|
||||
Identify likely entry points using these signals (score each node, sum the scores):
|
||||
|
||||
For code files:
|
||||
- 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`, `Application.java`, `Main.java`, `Program.cs`, `config.ru`, `index.php`, `App.swift`, `Application.kt`, `main.cpp`, `main.c` -> +3 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
|
||||
- Low fan-in (bottom 25%) -> +1 point (entry points are imported by few files)
|
||||
|
||||
For documentation files:
|
||||
- `README.md` at project root -> +5 points (highest priority as tour start)
|
||||
- Other `*.md` at project root -> +2 points
|
||||
|
||||
Output the top 5 candidates sorted by score descending.
|
||||
|
||||
**D. Dependency Chains (BFS from Entry Points)**
|
||||
@@ -62,7 +74,17 @@ Output:
|
||||
- The depth of each node (distance from entry point)
|
||||
- Group nodes by depth level: depth 0 (entry), depth 1 (direct dependencies), depth 2, etc.
|
||||
|
||||
**E. Tightly Coupled Clusters**
|
||||
**E. Non-Code File Inventory**
|
||||
|
||||
Separate non-code files by category for tour inclusion:
|
||||
- Documentation files (type: `document`)
|
||||
- Infrastructure files (type: `service`, `pipeline`, `resource`)
|
||||
- Data/Schema files (type: `table`, `schema`, `endpoint`)
|
||||
- Configuration files (type: `config`)
|
||||
|
||||
For each, include the node ID, name, type, and summary.
|
||||
|
||||
**F. Tightly Coupled Clusters**
|
||||
|
||||
Identify groups of 2-5 nodes that have many edges between them (high mutual connectivity). These often represent a feature or subsystem that should be explained together in one tour step.
|
||||
|
||||
@@ -70,15 +92,15 @@ Algorithm: For each pair of nodes with a bidirectional relationship (A imports B
|
||||
|
||||
Output the top 5-10 clusters, each as a list of node IDs.
|
||||
|
||||
**F. Layer List**
|
||||
**G. Layer List**
|
||||
|
||||
Record the layers provided in the input. Since layers contain only `{id, name, description}` (no node membership), simply output the layer count and the list of layers with their id, name, and description.
|
||||
|
||||
**G. Node Summary Index**
|
||||
**H. Node Summary Index**
|
||||
|
||||
Create a lookup of each node ID to its `summary`, `type`, and `name` for easy reference. This lets the LLM phase quickly access semantic information without re-reading the full input.
|
||||
|
||||
Note: input nodes are file-type only. The nodeSummaryIndex will contain only file nodes.
|
||||
Note: input nodes may include all node types (file, config, document, service, pipeline, table, schema, resource, endpoint). The nodeSummaryIndex should include all of them.
|
||||
|
||||
### Script Output Format
|
||||
|
||||
@@ -86,6 +108,7 @@ Note: input nodes are file-type only. The nodeSummaryIndex will contain only fil
|
||||
{
|
||||
"scriptCompleted": true,
|
||||
"entryPointCandidates": [
|
||||
{"id": "document:README.md", "score": 5, "name": "README.md", "summary": "Project overview..."},
|
||||
{"id": "file:src/index.ts", "score": 7, "name": "index.ts", "summary": "..."}
|
||||
],
|
||||
"fanInRanking": [
|
||||
@@ -108,6 +131,21 @@ Note: input nodes are file-type only. The nodeSummaryIndex will contain only fil
|
||||
"2": ["file:src/models/user.ts"]
|
||||
}
|
||||
},
|
||||
"nonCodeFiles": {
|
||||
"documentation": [
|
||||
{"id": "document:README.md", "name": "README.md", "summary": "Project overview..."}
|
||||
],
|
||||
"infrastructure": [
|
||||
{"id": "service:Dockerfile", "name": "Dockerfile", "summary": "Multi-stage build..."},
|
||||
{"id": "pipeline:.github/workflows/ci.yml", "name": "ci.yml", "summary": "CI pipeline..."}
|
||||
],
|
||||
"data": [
|
||||
{"id": "table:schema.sql:users", "name": "users", "summary": "User table..."}
|
||||
],
|
||||
"config": [
|
||||
{"id": "config:package.json", "name": "package.json", "summary": "Project manifest..."}
|
||||
]
|
||||
},
|
||||
"clusters": [
|
||||
{"nodes": ["file:src/services/auth.ts", "file:src/models/user.ts"], "edgeCount": 4}
|
||||
],
|
||||
@@ -115,13 +153,13 @@ Note: input nodes are file-type only. The nodeSummaryIndex will contain only fil
|
||||
"count": 3,
|
||||
"list": [
|
||||
{"id": "layer:core", "name": "Core", "description": "Core application logic"},
|
||||
{"id": "layer:services", "name": "Services", "description": "Business logic services"},
|
||||
{"id": "layer:ui", "name": "UI", "description": "User interface components"}
|
||||
{"id": "layer:infrastructure", "name": "Infrastructure", "description": "Deployment and CI/CD"}
|
||||
]
|
||||
},
|
||||
"nodeSummaryIndex": {
|
||||
"file:src/index.ts": {"name": "index.ts", "type": "file", "summary": "Main entry point..."},
|
||||
"file:src/utils.ts": {"name": "utils.ts", "type": "file", "summary": "Shared helpers..."}
|
||||
"document:README.md": {"name": "README.md", "type": "document", "summary": "Project overview..."},
|
||||
"service:Dockerfile": {"name": "Dockerfile", "type": "service", "summary": "Multi-stage Docker build..."}
|
||||
},
|
||||
"totalNodes": 42,
|
||||
"totalEdges": 87
|
||||
@@ -135,8 +173,8 @@ Before writing the script, create its input JSON file:
|
||||
```bash
|
||||
cat > $PROJECT_ROOT/.understand-anything/tmp/ua-tour-input.json << 'ENDJSON'
|
||||
{
|
||||
"nodes": [<nodes from prompt>],
|
||||
"edges": [<edges from prompt>],
|
||||
"nodes": [<nodes from prompt — all types including non-code>],
|
||||
"edges": [<edges from prompt — all types>],
|
||||
"layers": [<layers from prompt>]
|
||||
}
|
||||
ENDJSON
|
||||
@@ -160,7 +198,13 @@ After the script completes, read `$PROJECT_ROOT/.understand-anything/tmp/ua-tour
|
||||
|
||||
### Step 1 -- Choose the Starting Point
|
||||
|
||||
Use `entryPointCandidates[0]` as Step 1 of the tour. This is the file with the highest entry-point score. If the top candidate is a trivial barrel file (re-exports only), consider using the second candidate or grouping both together.
|
||||
Consider two options for Step 1:
|
||||
|
||||
**Option A: README.md first** — If `document:README.md` appears in `entryPointCandidates` or `nonCodeFiles.documentation`, start with it. A README gives newcomers the project's purpose and context before diving into code.
|
||||
|
||||
**Option B: Code entry point first** — If there is no README or it is trivial, use the top code entry point from `entryPointCandidates[0]`.
|
||||
|
||||
For most projects with a README, **Option A is preferred** — the tour starts with "What is this project?" (README) then moves to "How does it start?" (code entry point in Step 2).
|
||||
|
||||
### Step 2 -- Map the BFS Traversal to Tour Steps
|
||||
|
||||
@@ -168,23 +212,48 @@ The `bfsTraversal.byDepth` structure gives you the natural reading order of the
|
||||
|
||||
| BFS Depth | Tour Mapping | Purpose |
|
||||
|---|---|---|
|
||||
| Depth 0 | Step 1 | Entry point / project overview |
|
||||
| Depth 1 | Steps 2-3 | Direct dependencies: core types, config, main modules |
|
||||
| Depth 2 | Steps 4-6 | Feature modules, services, primary functionality |
|
||||
| Depth 3+ | Steps 7-9 | Supporting infrastructure, utilities |
|
||||
| (clusters) | Steps 10+ | Advanced topics, cross-cutting concerns |
|
||||
| Depth 0 | Step 1-2 | Project overview (README) + code entry point |
|
||||
| Depth 1 | Steps 3-4 | Direct dependencies: core types, config, main modules |
|
||||
| Depth 2 | Steps 5-7 | Feature modules, services, primary functionality |
|
||||
| Depth 3+ | Steps 8-10 | Supporting infrastructure, utilities |
|
||||
| (non-code) | Steps 11+ | Infrastructure, data, deployment |
|
||||
|
||||
You do not need to include every node from the BFS. Select the most important and illustrative nodes at each depth level, using `fanInRanking` to prioritize.
|
||||
|
||||
### Step 3 -- Use Clusters for Grouped Steps
|
||||
### Step 3 -- Integrate Non-Code Tour Stops
|
||||
|
||||
Use `nonCodeFiles` to add non-code stops at appropriate points in the tour:
|
||||
|
||||
**Documentation stops:**
|
||||
- README.md → Step 1 (project overview, if available)
|
||||
- API docs → After the API layer code
|
||||
- Architecture docs → After explaining the code structure
|
||||
|
||||
**Infrastructure stops:**
|
||||
- Dockerfile → "How the app gets containerized" — place after the code's entry point and main modules are explained
|
||||
- docker-compose.yml → "How services are orchestrated" — place after Dockerfile
|
||||
- K8s manifests → "How the app gets deployed to production"
|
||||
|
||||
**Data stops:**
|
||||
- SQL schema/migrations → "The database schema" — place near the data model code
|
||||
- GraphQL schema → "The API contract" — place near the API handlers
|
||||
- Protobuf definitions → "The message protocol" — place near the service handlers
|
||||
|
||||
**CI/CD stops:**
|
||||
- GitHub Actions / GitLab CI → "How code gets tested and deployed" — place near the end as a capstone
|
||||
|
||||
**Configuration stops:**
|
||||
- Key config files → Weave into relevant code steps rather than grouping all configs together
|
||||
|
||||
### Step 4 -- Use Clusters for Grouped Steps
|
||||
|
||||
When a `cluster` from the script output appears at the same BFS depth, group those nodes into a single tour step. Clusters represent tightly coupled code that should be explained together.
|
||||
|
||||
### Step 4 -- Use Layers for Narrative Arc
|
||||
### Step 5 -- Use Layers for Narrative Arc
|
||||
|
||||
The `layers` list gives you the project's architectural groupings. Use layer names and descriptions to understand which areas are foundational vs. top-level, and structure the tour to explain foundational layers before the layers that depend on them.
|
||||
|
||||
### Step 5 -- Write Step Descriptions
|
||||
### Step 6 -- Write Step Descriptions
|
||||
|
||||
For each step, use the `nodeSummaryIndex` to access node summaries and names without re-reading files. Each description must:
|
||||
|
||||
@@ -194,18 +263,36 @@ For each step, use the `nodeSummaryIndex` to access node summaries and names wit
|
||||
- Be written for someone who has never seen this codebase before
|
||||
- Be 2-4 sentences long
|
||||
|
||||
Bad description: "This is the auth service file."
|
||||
Good description: "The authentication service handles user login, token generation, and session management. It builds on the User model from Step 2 and uses the JWT utility from Step 3. Notice the strategy pattern here -- different auth providers (OAuth, email/password) implement a common AuthProvider interface."
|
||||
**For non-code stops, adapt the description style:**
|
||||
|
||||
### Step 6 -- Add Language Lessons (Optional)
|
||||
Bad description: "This is the Dockerfile."
|
||||
Good description: "The Dockerfile defines how the application gets packaged into a container image. It uses a multi-stage build: the first stage installs dependencies and compiles TypeScript, while the second stage copies only the compiled output into a minimal Alpine image. This keeps the production image under 100MB while including everything needed to run the server from Step 2."
|
||||
|
||||
If a step involves notable language-specific patterns, include a brief `languageLesson` string. Only add these when genuinely educational:
|
||||
Bad description: "These are the SQL migrations."
|
||||
Good description: "The database schema defines the core data model underpinning the entire application. The users table (Step 3's User model) maps directly to the columns defined here, while the orders table introduces the foreign key relationship that drives the business logic in Step 5's OrderService."
|
||||
|
||||
### Step 7 -- Add Language Lessons (Optional)
|
||||
|
||||
If a step involves notable language-specific or format-specific patterns, include a brief `languageLesson` string. Only add these when genuinely educational:
|
||||
|
||||
**For code files:**
|
||||
- **TypeScript:** generics, discriminated unions, utility types, decorators, template literal types
|
||||
- **React:** hooks, context, render patterns, suspense, compound components
|
||||
- **Python:** decorators, generators, context managers, metaclasses, protocols
|
||||
- **Go:** goroutines, channels, interfaces, embedding, error wrapping
|
||||
- **Rust:** ownership, lifetimes, traits, pattern matching, async/await
|
||||
|
||||
**For non-code files:**
|
||||
- **Dockerfile:** multi-stage builds reduce image size by separating build and runtime dependencies. Layer ordering matters for Docker cache efficiency — put rarely-changing layers (OS packages) before frequently-changing ones (app code).
|
||||
- **docker-compose:** service dependency ordering with `depends_on`, health checks, named volumes for persistent data, network isolation between services.
|
||||
- **SQL:** database normalization reduces redundancy through foreign keys. Migrations should be idempotent and reversible. Index placement affects query performance.
|
||||
- **GraphQL:** type system enforces API contracts at the schema level. Resolvers map schema fields to data sources. Fragments reduce query duplication.
|
||||
- **Protobuf:** field numbers are permanent (never reuse deleted numbers). Backward compatibility requires only adding optional fields. Services define RPC contracts.
|
||||
- **YAML (CI/CD):** GitHub Actions use `on` triggers, `jobs` for parallelism, and `steps` for sequential execution. Matrix builds test across multiple OS/language versions. Caching speeds up dependency installation.
|
||||
- **Terraform:** resources declare desired infrastructure state. State files track what exists. Modules encapsulate reusable infrastructure patterns. Plan before apply to preview changes.
|
||||
- **Makefile:** targets define build steps with dependency tracking. Phony targets for non-file actions. Variables and pattern rules reduce repetition.
|
||||
- **Kubernetes:** Deployments manage pod replicas with rolling updates. Services expose pods via stable DNS names. ConfigMaps/Secrets separate config from images.
|
||||
|
||||
## Output Format
|
||||
|
||||
Produce a single, valid JSON array.
|
||||
@@ -214,16 +301,36 @@ Produce a single, valid JSON array.
|
||||
[
|
||||
{
|
||||
"order": 1,
|
||||
"title": "Entry Point",
|
||||
"description": "Start with src/index.ts, the main entry point that bootstraps the application. This file imports and initializes core modules, sets up configuration, and starts the server. It gives you a bird's-eye view of the project's structure.",
|
||||
"title": "Project Overview",
|
||||
"description": "Start with README.md to understand the project's purpose, architecture, and how to get started. This document outlines the main components and their relationships, providing a roadmap for the tour ahead.",
|
||||
"nodeIds": ["document:README.md"]
|
||||
},
|
||||
{
|
||||
"order": 2,
|
||||
"title": "Application Entry Point",
|
||||
"description": "The main entry point bootstraps the application, importing core modules, setting up configuration, and starting the server. This file gives you a bird's-eye view of the project's runtime structure.",
|
||||
"nodeIds": ["file:src/index.ts"],
|
||||
"languageLesson": "TypeScript barrel files use 'export * from' to re-export modules, creating a clean public API surface."
|
||||
},
|
||||
{
|
||||
"order": 2,
|
||||
"order": 3,
|
||||
"title": "Core Types and Models",
|
||||
"description": "The type system defines the domain model. These interfaces establish the vocabulary used throughout the codebase and form the contract between layers.",
|
||||
"nodeIds": ["file:src/types.ts", "file:src/interfaces/user.ts"]
|
||||
},
|
||||
{
|
||||
"order": 8,
|
||||
"title": "Database Schema",
|
||||
"description": "The SQL migrations define the database tables that back the User and Order models from Steps 3-4. Foreign keys enforce the relationships the code relies on.",
|
||||
"nodeIds": ["table:migrations/001.sql:users", "table:migrations/002.sql:orders"],
|
||||
"languageLesson": "SQL migrations should be idempotent and ordered. Each migration file applies incremental changes to the schema, allowing the database to evolve alongside the application code."
|
||||
},
|
||||
{
|
||||
"order": 12,
|
||||
"title": "Containerization & Deployment",
|
||||
"description": "The Dockerfile packages the application into a production-ready container image. The multi-stage build compiles TypeScript in a builder stage and copies only the runtime artifacts, keeping the final image small.",
|
||||
"nodeIds": ["service:Dockerfile", "service:docker-compose.yml"],
|
||||
"languageLesson": "Multi-stage Docker builds use multiple FROM statements. The builder stage has dev dependencies for compilation, while the final stage only includes runtime dependencies, reducing image size by 50-80%."
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -235,7 +342,7 @@ Produce a single, valid JSON array.
|
||||
- `nodeIds` (string[]) -- 1-5 node IDs from the provided graph, NEVER empty
|
||||
|
||||
**Optional fields:**
|
||||
- `languageLesson` (string) -- brief explanation of a language pattern, only when genuinely useful
|
||||
- `languageLesson` (string) -- brief explanation of a language or format pattern, only when genuinely useful
|
||||
|
||||
## Critical Constraints
|
||||
|
||||
@@ -245,7 +352,8 @@ Produce a single, valid JSON array.
|
||||
- Tour MUST have between 5 and 15 steps inclusive.
|
||||
- Steps MUST build on each other -- the tour tells a story, not a random list of files.
|
||||
- Not every file needs to appear in the tour. Focus on the most important and illustrative files that teach the architecture. Use the fan-in ranking to identify which files are most worth covering.
|
||||
- ALWAYS start with the project entry point or overview in Step 1.
|
||||
- Non-code files are valid tour stops. Include at least 1-2 non-code stops if the project has meaningful documentation, infrastructure, or data schema files.
|
||||
- ALWAYS start with the project overview (README or entry point) in Step 1.
|
||||
- Trust the script's structural analysis. Do NOT re-read source files, re-count edges, or re-trace dependencies. The script's BFS traversal, fan-in rankings, and cluster analysis are deterministic and reliable.
|
||||
|
||||
## Writing Results
|
||||
|
||||
Reference in New Issue
Block a user