From ae898a28b244223809226cb6bb17678db997513e Mon Sep 17 00:00:00 2001 From: Sreeram Date: Mon, 23 Mar 2026 21:53:02 +0530 Subject: [PATCH] fix: address PR review feedback (C1-C4, I1-I5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Critical fixes: - C1: Remove unused treeSitter.nodeTypes from configs and schema — extraction logic is TS/JS-specific, nodeTypes gave false impression of generality - C2+C3: Remove blocking temp dir prompt, default to .understand-anything/tmp/, update all 5 prompt templates to use project-local paths instead of /tmp/ - C4: Fix false-positive framework detection — use "next": (with quotes) for Next.js, remove cors/body-parser from Express keywords Important fixes: - I1: Change FrameworkConfig.language to languages[] array — React/Express/Vue now correctly listed under both typescript and javascript - I2: Fix getByExtension case sensitivity — .TS now resolves same as .ts - I3: languageKeyFromPath returns null instead of throwing for unknown extensions - I4: Duplicate framework registration is now a no-op instead of corrupting array - I5: SKILL.md now says "skip silently" when language/framework snippet not found Also: getForLanguage returns a defensive copy, 3 new tests added (157 total). --- .../src/__tests__/framework-registry.test.ts | 24 +++++++++++++ .../core/src/languages/configs/javascript.ts | 14 -------- .../core/src/languages/configs/typescript.ts | 18 ---------- .../core/src/languages/framework-registry.ts | 14 +++++--- .../core/src/languages/frameworks/django.ts | 2 +- .../core/src/languages/frameworks/express.ts | 4 +-- .../core/src/languages/frameworks/fastapi.ts | 2 +- .../core/src/languages/frameworks/flask.ts | 2 +- .../core/src/languages/frameworks/gin.ts | 2 +- .../core/src/languages/frameworks/nextjs.ts | 4 +-- .../core/src/languages/frameworks/rails.ts | 2 +- .../core/src/languages/frameworks/react.ts | 2 +- .../core/src/languages/frameworks/spring.ts | 2 +- .../core/src/languages/frameworks/vue.ts | 2 +- .../core/src/languages/language-registry.ts | 2 +- .../packages/core/src/languages/types.ts | 17 ++++----- .../core/src/plugins/tree-sitter-plugin.ts | 9 ++--- .../skills/understand/SKILL.md | 36 +++++++------------ .../architecture-analyzer-prompt.md | 6 ++-- .../skills/understand/file-analyzer-prompt.md | 8 ++--- .../understand/graph-reviewer-prompt.md | 4 +-- .../understand/project-scanner-prompt.md | 4 +-- .../skills/understand/tour-builder-prompt.md | 6 ++-- 23 files changed, 83 insertions(+), 103 deletions(-) diff --git a/understand-anything-plugin/packages/core/src/__tests__/framework-registry.test.ts b/understand-anything-plugin/packages/core/src/__tests__/framework-registry.test.ts index 3fdc588..3620eb0 100644 --- a/understand-anything-plugin/packages/core/src/__tests__/framework-registry.test.ts +++ b/understand-anything-plugin/packages/core/src/__tests__/framework-registry.test.ts @@ -81,6 +81,30 @@ describe("FrameworkRegistry", () => { }); }); + it("returns frameworks for all listed languages (cross-language)", () => { + const registry = FrameworkRegistry.createDefault(); + // React lists both typescript and javascript + const tsFrameworks = registry.getForLanguage("typescript"); + const jsFrameworks = registry.getForLanguage("javascript"); + expect(tsFrameworks.some((f) => f.id === "react")).toBe(true); + expect(jsFrameworks.some((f) => f.id === "react")).toBe(true); + }); + + it("does not duplicate on re-registration", () => { + const registry = new FrameworkRegistry(); + registry.register(djangoConfig); + registry.register(djangoConfig); + expect(registry.getForLanguage("python")).toHaveLength(1); + }); + + it("getForLanguage returns a copy, not the internal array", () => { + const registry = new FrameworkRegistry(); + registry.register(djangoConfig); + const result = registry.getForLanguage("python"); + result.push(reactConfig); + expect(registry.getForLanguage("python")).toHaveLength(1); + }); + describe("createDefault", () => { it("registers all 10 built-in framework configs", () => { const registry = FrameworkRegistry.createDefault(); diff --git a/understand-anything-plugin/packages/core/src/languages/configs/javascript.ts b/understand-anything-plugin/packages/core/src/languages/configs/javascript.ts index 9d29682..d89cf49 100644 --- a/understand-anything-plugin/packages/core/src/languages/configs/javascript.ts +++ b/understand-anything-plugin/packages/core/src/languages/configs/javascript.ts @@ -7,20 +7,6 @@ export const javascriptConfig = { treeSitter: { wasmPackage: "tree-sitter-javascript", wasmFile: "tree-sitter-javascript.wasm", - nodeTypes: { - function: [ - "function_declaration", - "arrow_function", - "function_expression", - "method_definition", - ], - class: ["class_declaration"], - import: ["import_statement"], - export: ["export_statement"], - call: ["call_expression"], - string: ["string", "string_fragment"], - parameter: ["formal_parameters"], - }, }, concepts: [ "closures", diff --git a/understand-anything-plugin/packages/core/src/languages/configs/typescript.ts b/understand-anything-plugin/packages/core/src/languages/configs/typescript.ts index ffb093d..04a884d 100644 --- a/understand-anything-plugin/packages/core/src/languages/configs/typescript.ts +++ b/understand-anything-plugin/packages/core/src/languages/configs/typescript.ts @@ -7,24 +7,6 @@ export const typescriptConfig = { treeSitter: { wasmPackage: "tree-sitter-typescript", wasmFile: "tree-sitter-typescript.wasm", - nodeTypes: { - function: [ - "function_declaration", - "arrow_function", - "function_expression", - "method_definition", - ], - class: ["class_declaration"], - import: ["import_statement"], - export: ["export_statement"], - call: ["call_expression"], - string: ["string", "string_fragment"], - parameter: [ - "formal_parameters", - "required_parameter", - "optional_parameter", - ], - }, }, concepts: [ "generics", diff --git a/understand-anything-plugin/packages/core/src/languages/framework-registry.ts b/understand-anything-plugin/packages/core/src/languages/framework-registry.ts index 5ec6d1d..671d5b5 100644 --- a/understand-anything-plugin/packages/core/src/languages/framework-registry.ts +++ b/understand-anything-plugin/packages/core/src/languages/framework-registry.ts @@ -12,11 +12,17 @@ export class FrameworkRegistry { register(config: FrameworkConfig): void { const parsed = FrameworkConfigSchema.parse(config); + + // Prevent duplicate registration + if (this.byId.has(parsed.id)) return; + this.byId.set(parsed.id, parsed); - const existing = this.byLanguage.get(parsed.language) ?? []; - existing.push(parsed); - this.byLanguage.set(parsed.language, existing); + for (const lang of parsed.languages) { + const existing = this.byLanguage.get(lang) ?? []; + existing.push(parsed); + this.byLanguage.set(lang, existing); + } } getById(id: string): FrameworkConfig | null { @@ -24,7 +30,7 @@ export class FrameworkRegistry { } getForLanguage(langId: string): FrameworkConfig[] { - return this.byLanguage.get(langId) ?? []; + return [...(this.byLanguage.get(langId) ?? [])]; } getAllFrameworks(): FrameworkConfig[] { diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/django.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/django.ts index 824b02c..aef5775 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/django.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/django.ts @@ -3,7 +3,7 @@ import type { FrameworkConfig } from "../types.js"; export const djangoConfig = { id: "django", displayName: "Django", - language: "python", + languages: ["python"], detectionKeywords: [ "django", "djangorestframework", diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/express.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/express.ts index af82dca..dd5e26c 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/express.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/express.ts @@ -3,8 +3,8 @@ import type { FrameworkConfig } from "../types.js"; export const expressConfig = { id: "express", displayName: "Express", - language: "javascript", - detectionKeywords: ["express", "express-validator", "cors", "body-parser"], + languages: ["javascript", "typescript"], + detectionKeywords: ["\"express\":", "express-validator", "express-session"], manifestFiles: ["package.json"], promptSnippetPath: "./frameworks/express.md", entryPoints: [ diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/fastapi.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/fastapi.ts index b62c871..a8043d0 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/fastapi.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/fastapi.ts @@ -3,7 +3,7 @@ import type { FrameworkConfig } from "../types.js"; export const fastapiConfig = { id: "fastapi", displayName: "FastAPI", - language: "python", + languages: ["python"], detectionKeywords: ["fastapi", "uvicorn", "starlette"], manifestFiles: [ "requirements.txt", diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/flask.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/flask.ts index e68fcc6..0792893 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/flask.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/flask.ts @@ -3,7 +3,7 @@ import type { FrameworkConfig } from "../types.js"; export const flaskConfig = { id: "flask", displayName: "Flask", - language: "python", + languages: ["python"], detectionKeywords: [ "flask", "flask-restful", diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/gin.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/gin.ts index eae684a..2944113 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/gin.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/gin.ts @@ -3,7 +3,7 @@ import type { FrameworkConfig } from "../types.js"; export const ginConfig = { id: "gin", displayName: "Gin", - language: "go", + languages: ["go"], detectionKeywords: ["github.com/gin-gonic/gin"], manifestFiles: ["go.mod"], promptSnippetPath: "./frameworks/gin.md", diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/nextjs.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/nextjs.ts index 97fefad..6a94bfb 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/nextjs.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/nextjs.ts @@ -3,8 +3,8 @@ import type { FrameworkConfig } from "../types.js"; export const nextjsConfig = { id: "nextjs", displayName: "Next.js", - language: "typescript", - detectionKeywords: ["next", "@next/font", "@next/image"], + languages: ["typescript", "javascript"], + detectionKeywords: ["\"next\":", "@next/font", "@next/image"], manifestFiles: ["package.json"], promptSnippetPath: "./frameworks/nextjs.md", entryPoints: [ diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/rails.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/rails.ts index 6ba47ab..7a5e82f 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/rails.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/rails.ts @@ -3,7 +3,7 @@ import type { FrameworkConfig } from "../types.js"; export const railsConfig = { id: "rails", displayName: "Ruby on Rails", - language: "ruby", + languages: ["ruby"], detectionKeywords: [ "rails", "railties", diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/react.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/react.ts index 7429fd3..c5830ad 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/react.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/react.ts @@ -3,7 +3,7 @@ import type { FrameworkConfig } from "../types.js"; export const reactConfig = { id: "react", displayName: "React", - language: "typescript", + languages: ["typescript", "javascript"], detectionKeywords: ["react", "react-dom", "@types/react"], manifestFiles: ["package.json"], promptSnippetPath: "./frameworks/react.md", diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/spring.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/spring.ts index 7b7b56d..557353d 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/spring.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/spring.ts @@ -3,7 +3,7 @@ import type { FrameworkConfig } from "../types.js"; export const springConfig = { id: "spring", displayName: "Spring Boot", - language: "java", + languages: ["java", "kotlin"], detectionKeywords: [ "spring-boot", "spring-boot-starter", diff --git a/understand-anything-plugin/packages/core/src/languages/frameworks/vue.ts b/understand-anything-plugin/packages/core/src/languages/frameworks/vue.ts index 94a8f01..78ead2f 100644 --- a/understand-anything-plugin/packages/core/src/languages/frameworks/vue.ts +++ b/understand-anything-plugin/packages/core/src/languages/frameworks/vue.ts @@ -3,7 +3,7 @@ import type { FrameworkConfig } from "../types.js"; export const vueConfig = { id: "vue", displayName: "Vue", - language: "typescript", + languages: ["typescript", "javascript"], detectionKeywords: ["vue", "@vue/cli-service", "nuxt", "vite-plugin-vue"], manifestFiles: ["package.json"], promptSnippetPath: "./frameworks/vue.md", diff --git a/understand-anything-plugin/packages/core/src/languages/language-registry.ts b/understand-anything-plugin/packages/core/src/languages/language-registry.ts index 0afef19..542cd1d 100644 --- a/understand-anything-plugin/packages/core/src/languages/language-registry.ts +++ b/understand-anything-plugin/packages/core/src/languages/language-registry.ts @@ -25,7 +25,7 @@ export class LanguageRegistry { } getByExtension(ext: string): LanguageConfig | null { - const key = ext.startsWith(".") ? ext : `.${ext}`; + const key = (ext.startsWith(".") ? ext : `.${ext}`).toLowerCase(); return this.byExtension.get(key) ?? null; } diff --git a/understand-anything-plugin/packages/core/src/languages/types.ts b/understand-anything-plugin/packages/core/src/languages/types.ts index 03953a2..7d06c3a 100644 --- a/understand-anything-plugin/packages/core/src/languages/types.ts +++ b/understand-anything-plugin/packages/core/src/languages/types.ts @@ -1,18 +1,13 @@ import { z } from "zod"; -// Tree-sitter node type mappings for a language +// Tree-sitter grammar configuration for a language. +// Only wasmPackage and wasmFile are needed for grammar loading. +// The extraction logic in tree-sitter-plugin.ts is currently TS/JS-specific; +// when grammars for other languages are added, language-specific extractors +// should be registered via the customAnalyzer escape hatch. export const TreeSitterConfigSchema = z.object({ wasmPackage: z.string(), wasmFile: z.string(), - nodeTypes: z.object({ - function: z.array(z.string()), - class: z.array(z.string()), - import: z.array(z.string()), - export: z.array(z.string()), - call: z.array(z.string()), - string: z.array(z.string()), - parameter: z.array(z.string()), - }), }); export type TreeSitterConfig = z.infer; @@ -43,7 +38,7 @@ export type LanguageConfig = z.infer; export const FrameworkConfigSchema = z.object({ id: z.string().min(1), displayName: z.string().min(1), - language: z.string().min(1), + languages: z.array(z.string().min(1)).min(1), detectionKeywords: z.array(z.string()).min(1), manifestFiles: z.array(z.string()).min(1), promptSnippetPath: z.string().min(1), diff --git a/understand-anything-plugin/packages/core/src/plugins/tree-sitter-plugin.ts b/understand-anything-plugin/packages/core/src/plugins/tree-sitter-plugin.ts index cf774f9..ff0dbda 100644 --- a/understand-anything-plugin/packages/core/src/plugins/tree-sitter-plugin.ts +++ b/understand-anything-plugin/packages/core/src/plugins/tree-sitter-plugin.ts @@ -201,17 +201,13 @@ export class TreeSitterPlugin implements AnalyzerPlugin { this.languages = langs; } - private languageKeyFromPath(filePath: string): string { + private languageKeyFromPath(filePath: string): string | null { const ext = extname(filePath).toLowerCase(); // Special case: .tsx needs its own grammar if (ext === ".tsx") return "tsx"; - const lang = this._extensionToLang.get(ext); - if (!lang) { - throw new Error(`Unsupported file extension: ${ext}`); - } - return lang; + return this._extensionToLang.get(ext) ?? null; } /** @@ -304,6 +300,7 @@ export class TreeSitterPlugin implements AnalyzerPlugin { ); } const langKey = this.languageKeyFromPath(filePath); + if (!langKey) return null; const lang = this._languages.get(langKey); if (!lang) { // Language grammar not loaded — graceful degradation diff --git a/understand-anything-plugin/skills/understand/SKILL.md b/understand-anything-plugin/skills/understand/SKILL.md index 3954054..e0f23ca 100644 --- a/understand-anything-plugin/skills/understand/SKILL.md +++ b/understand-anything-plugin/skills/understand/SKILL.md @@ -20,29 +20,19 @@ Analyze the current codebase and produce a `knowledge-graph.json` file in `.unde Determine whether to run a full analysis or incremental update. -1. **STOP and ask the user where temporary scripts and intermediate files should be written.** You MUST wait for the user's response before proceeding to step 2 or any other step. Do NOT read prompt templates, launch subagents, or begin any analysis until this question is answered. - - Ask the user: - > Where should I write temporary scripts and intermediate files during analysis? - > 1. **Project directory** (recommended): `.understand-anything/tmp/` — stays within the project - > 2. **System temp**: `/tmp/` — may require permissions outside the project - - After the user responds, store the chosen path as `$TMP_DIR`. Create it: `mkdir -p $TMP_DIR`. - - All subagent prompts reference `$TMP_DIR` for script files and intermediate JSON. When dispatching subagents, replace any `/tmp/ua-` paths in the prompt templates with `$TMP_DIR/ua-` so scripts and results are written to the user's chosen location. - -2. Set `PROJECT_ROOT` to the current working directory. -3. Get the current git commit hash: +1. Set `PROJECT_ROOT` to the current working directory. +2. Get the current git commit hash: ```bash git rev-parse HEAD ``` -4. Create the intermediate output directory: +3. Create the intermediate and temp output directories: ```bash mkdir -p $PROJECT_ROOT/.understand-anything/intermediate + mkdir -p $PROJECT_ROOT/.understand-anything/tmp ``` -5. Check if `$PROJECT_ROOT/.understand-anything/knowledge-graph.json` exists. If it does, read it. -6. Check if `$PROJECT_ROOT/.understand-anything/meta.json` exists. If it does, read it to get `gitCommitHash`. -7. **Decision logic:** +4. Check if `$PROJECT_ROOT/.understand-anything/knowledge-graph.json` exists. If it does, read it. +5. Check if `$PROJECT_ROOT/.understand-anything/meta.json` exists. If it does, read it to get `gitCommitHash`. +6. **Decision logic:** | Condition | Action | |---|---| @@ -57,7 +47,7 @@ Determine whether to run a full analysis or incremental update. ``` If this returns no files, report "Graph is up to date" and STOP. -8. **Collect project context for subagent injection:** +7. **Collect project context for subagent injection:** - Read `README.md` (or `README.rst`, `readme.md`) from `$PROJECT_ROOT` if it exists. Store as `$README_CONTENT` (first 3000 characters). - Read the primary package manifest (`package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `pom.xml`) if it exists. Store as `$MANIFEST_CONTENT`. - Capture the top-level directory tree: @@ -113,8 +103,8 @@ For each batch, dispatch a subagent using the prompt template at `./file-analyze **Build the combined prompt template:** 1. Read the base template at `./file-analyzer-prompt.md`. -2. **Language context injection:** For each language detected in Phase 1 (e.g., `python`), read the file at `./languages/.md` (e.g., `./languages/python.md`) and append its content after the base template under a `## Language Context` header. These files are in the `languages/` subdirectory next to this SKILL.md file. Use `ls ./languages/` to discover available language files if needed. -3. **Framework addendum injection:** For each framework detected in Phase 1 (e.g., `Django`), read the file at `./frameworks/.md` (e.g., `./frameworks/django.md`) and append its full content after the language context. These files are in the `frameworks/` subdirectory next to this SKILL.md file. Use `ls ./frameworks/` to discover available framework files if needed. +2. **Language context injection:** For each language detected in Phase 1 (e.g., `python`), read the file at `./languages/.md` (e.g., `./languages/python.md`) and append its content after the base template under a `## Language Context` header. If the file does not exist for a detected language, skip it silently and continue. These files are in the `languages/` subdirectory next to this SKILL.md file. Use `ls ./languages/` to discover available language files if needed. +3. **Framework addendum injection:** For each framework detected in Phase 1 (e.g., `Django`), read the file at `./frameworks/.md` (e.g., `./frameworks/django.md`) and append its full content after the language context. If the file does not exist for a detected framework, skip it silently and continue. These files are in the `frameworks/` subdirectory next to this SKILL.md file. Use `ls ./frameworks/` to discover available framework files if needed. Then for each batch pass the combined template content as the subagent's prompt, appending the following additional context: @@ -172,8 +162,8 @@ Merge all file-analyzer results into a single set of nodes and edges. Then perfo **Build the combined prompt template:** 1. Read the base template at `./architecture-analyzer-prompt.md`. -2. **Language context injection:** For each language detected in Phase 1 (e.g., `python`), read the file at `./languages/.md` (e.g., `./languages/python.md`) and append its content after the base template under a `## Language Context` header. These files are in the `languages/` subdirectory next to this SKILL.md file. -3. **Framework addendum injection:** For each framework detected in Phase 1 (e.g., `Django`), read the file at `./frameworks/.md` (e.g., `./frameworks/django.md`) and append its full content after the language context. These files are in the `frameworks/` subdirectory next to this SKILL.md file. +2. **Language context injection:** For each language detected in Phase 1 (e.g., `python`), read the file at `./languages/.md` (e.g., `./languages/python.md`) and append its content after the base template under a `## Language Context` header. If the file does not exist for a detected language, skip it silently and continue. These files are in the `languages/` subdirectory next to this SKILL.md file. +3. **Framework addendum injection:** For each framework detected in Phase 1 (e.g., `Django`), read the file at `./frameworks/.md` (e.g., `./frameworks/django.md`) and append its full content after the language context. If the file does not exist for a detected framework, skip it silently and continue. These files are in the `frameworks/` subdirectory next to this SKILL.md file. Pass the combined content as the subagent's prompt, appending the following additional context: @@ -416,7 +406,7 @@ Pass these parameters in the dispatch prompt: 3. Clean up intermediate files: ```bash rm -rf $PROJECT_ROOT/.understand-anything/intermediate - rm -rf $TMP_DIR + rm -rf $PROJECT_ROOT/.understand-anything/tmp ``` 4. Report a summary to the user containing: diff --git a/understand-anything-plugin/skills/understand/architecture-analyzer-prompt.md b/understand-anything-plugin/skills/understand/architecture-analyzer-prompt.md index e7b1158..fb4dca4 100644 --- a/understand-anything-plugin/skills/understand/architecture-analyzer-prompt.md +++ b/understand-anything-plugin/skills/understand/architecture-analyzer-prompt.md @@ -164,7 +164,7 @@ For each pair of groups with imports between them, determine the dominant direct Before writing the script, create its input JSON file: ```bash -cat > /tmp/ua-arch-input.json << 'ENDJSON' +cat > $PROJECT_ROOT/.understand-anything/tmp/ua-arch-input.json << 'ENDJSON' { "fileNodes": [], "importEdges": [] @@ -177,7 +177,7 @@ ENDJSON After writing the script, execute it: ```bash -node /tmp/ua-arch-analyze.js /tmp/ua-arch-input.json /tmp/ua-arch-results.json +node $PROJECT_ROOT/.understand-anything/tmp/ua-arch-analyze.js $PROJECT_ROOT/.understand-anything/tmp/ua-arch-input.json $PROJECT_ROOT/.understand-anything/tmp/ua-arch-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. @@ -186,7 +186,7 @@ If the script exits with a non-zero code, read stderr, diagnose the issue, fix t ## Phase 2 -- Semantic Layer Assignment -After the script completes, read `/tmp/ua-arch-results.json`. Use the structural analysis as the primary input for your layer decisions. Do NOT re-read source files or re-analyze imports -- trust the script's results entirely. +After the script completes, read `$PROJECT_ROOT/.understand-anything/tmp/ua-arch-results.json`. Use the structural analysis as the primary input for your layer decisions. Do NOT re-read source files or re-analyze imports -- trust the script's results entirely. ### Step 1 -- Evaluate Directory Groups as Layer Candidates diff --git a/understand-anything-plugin/skills/understand/file-analyzer-prompt.md b/understand-anything-plugin/skills/understand/file-analyzer-prompt.md index c948b1f..15f90be 100644 --- a/understand-anything-plugin/skills/understand/file-analyzer-prompt.md +++ b/understand-anything-plugin/skills/understand/file-analyzer-prompt.md @@ -111,7 +111,7 @@ The script must write this exact JSON structure to the output file: Before writing the script, create its input JSON file. **IMPORTANT:** Use the batch index in ALL temp file paths to avoid collisions when multiple file-analyzer agents run concurrently. ```bash -cat > /tmp/ua-file-analyzer-input-.json << 'ENDJSON' +cat > $PROJECT_ROOT/.understand-anything/tmp/ua-file-analyzer-input-.json << 'ENDJSON' { "projectRoot": "", "allProjectFiles": [], @@ -126,9 +126,9 @@ After writing the script, execute it. **Use the batch index in every temp file p ```bash # For Node.js scripts: -node /tmp/ua-file-extract-.js /tmp/ua-file-analyzer-input-.json /tmp/ua-file-extract-results-.json +node $PROJECT_ROOT/.understand-anything/tmp/ua-file-extract-.js $PROJECT_ROOT/.understand-anything/tmp/ua-file-analyzer-input-.json $PROJECT_ROOT/.understand-anything/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 +python3 $PROJECT_ROOT/.understand-anything/tmp/ua-file-extract-.py $PROJECT_ROOT/.understand-anything/tmp/ua-file-analyzer-input-.json $PROJECT_ROOT/.understand-anything/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. @@ -137,7 +137,7 @@ If the script exits with a non-zero code, read stderr, diagnose the issue, fix t ## Phase 2 -- Semantic Analysis -After the script completes, read `/tmp/ua-file-extract-results-.json`. Use these structured results as the foundation for your analysis. Do NOT re-read the source files unless the script skipped a file or you need to understand a specific code pattern that the script could not capture. +After the script completes, read `$PROJECT_ROOT/.understand-anything/tmp/ua-file-extract-results-.json`. Use these structured results as the foundation for your analysis. Do NOT re-read the source files unless the script skipped a file or you need to understand a specific code pattern that the script could not capture. For each file in the script's `results` array, produce `GraphNode` and `GraphEdge` objects by combining the script's structural data with your expert judgment. diff --git a/understand-anything-plugin/skills/understand/graph-reviewer-prompt.md b/understand-anything-plugin/skills/understand/graph-reviewer-prompt.md index f141521..ed6d3f6 100644 --- a/understand-anything-plugin/skills/understand/graph-reviewer-prompt.md +++ b/understand-anything-plugin/skills/understand/graph-reviewer-prompt.md @@ -134,7 +134,7 @@ The script must write this exact JSON structure to the output file: After writing the script, execute it: ```bash -node /tmp/ua-graph-validate.js "" "/tmp/ua-review-results.json" +node $PROJECT_ROOT/.understand-anything/tmp/ua-graph-validate.js "" "$PROJECT_ROOT/.understand-anything/tmp/ua-review-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. @@ -143,7 +143,7 @@ If the script exits with a non-zero code, read stderr, diagnose the issue, fix t ## Phase 2 -- Review and Decision -After the script completes, read `/tmp/ua-review-results.json`. Do NOT re-read the original graph file -- trust the script's results entirely. +After the script completes, read `$PROJECT_ROOT/.understand-anything/tmp/ua-review-results.json`. Do NOT re-read the original graph file -- trust the script's results entirely. Review the `issues` and `warnings` arrays and render your decision: diff --git a/understand-anything-plugin/skills/understand/project-scanner-prompt.md b/understand-anything-plugin/skills/understand/project-scanner-prompt.md index 25ae5c9..b80de31 100644 --- a/understand-anything-plugin/skills/understand/project-scanner-prompt.md +++ b/understand-anything-plugin/skills/understand/project-scanner-prompt.md @@ -141,7 +141,7 @@ The script must write this exact JSON structure to the output file: After writing the script, execute it: ```bash -node /tmp/ua-project-scan.js "" "/tmp/ua-scan-results.json" +node $PROJECT_ROOT/.understand-anything/tmp/ua-project-scan.js "" "$PROJECT_ROOT/.understand-anything/tmp/ua-scan-results.json" ``` (Or the equivalent for bash/Python, depending on which language you chose.) @@ -152,7 +152,7 @@ If the script exits with a non-zero code, read stderr, diagnose the issue, fix t ## Phase 2 -- Description and Final Assembly -After the script completes, read `/tmp/ua-scan-results.json`. Do NOT re-run file discovery commands or re-count lines -- trust the script's results entirely. +After the script completes, read `$PROJECT_ROOT/.understand-anything/tmp/ua-scan-results.json`. Do NOT re-run file discovery commands or re-count lines -- trust the script's results entirely. **IMPORTANT:** The final output must NOT contain the `scriptCompleted`, `rawDescription`, or `readmeHead` fields. These are intermediate script fields only. Strip them when assembling the final JSON. diff --git a/understand-anything-plugin/skills/understand/tour-builder-prompt.md b/understand-anything-plugin/skills/understand/tour-builder-prompt.md index 5840928..8b1d318 100644 --- a/understand-anything-plugin/skills/understand/tour-builder-prompt.md +++ b/understand-anything-plugin/skills/understand/tour-builder-prompt.md @@ -132,7 +132,7 @@ Create a lookup of each node ID to its `summary`, `type`, `tags` (default to emp Before writing the script, create its input JSON file: ```bash -cat > /tmp/ua-tour-input.json << 'ENDJSON' +cat > $PROJECT_ROOT/.understand-anything/tmp/ua-tour-input.json << 'ENDJSON' { "nodes": [], "edges": [], @@ -146,7 +146,7 @@ ENDJSON After writing the script, execute it: ```bash -node /tmp/ua-tour-analyze.js /tmp/ua-tour-input.json /tmp/ua-tour-results.json +node $PROJECT_ROOT/.understand-anything/tmp/ua-tour-analyze.js $PROJECT_ROOT/.understand-anything/tmp/ua-tour-input.json $PROJECT_ROOT/.understand-anything/tmp/ua-tour-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. @@ -155,7 +155,7 @@ If the script exits with a non-zero code, read stderr, diagnose the issue, fix t ## Phase 2 -- Pedagogical Tour Design -After the script completes, read `/tmp/ua-tour-results.json`. Use the structural analysis as your primary guide for designing the tour. Do NOT re-read source files or re-analyze the graph -- trust the script's results entirely. +After the script completes, read `$PROJECT_ROOT/.understand-anything/tmp/ua-tour-results.json`. Use the structural analysis as your primary guide for designing the tour. Do NOT re-read source files or re-analyze the graph -- trust the script's results entirely. ### Step 1 -- Choose the Starting Point