mirror of
https://github.com/Egonex-AI/Understand-Anything.git
synced 2026-06-22 10:58:03 +08:00
Merge branch 'feat/keyboard-shortcuts-and-contributing' of https://github.com/berkcangumusisik/Understand-Anything into feat/keyboard-shortcuts-and-contributing
This commit is contained in:
@@ -11,16 +11,20 @@
|
||||
git clone https://github.com/Lum1104/Understand-Anything.git ~/.antigravity/understand-anything
|
||||
```
|
||||
|
||||
2. **Create the skills symlink:**
|
||||
2. **Create the skills symlinks:**
|
||||
```bash
|
||||
mkdir -p ~/.gemini/antigravity/skills
|
||||
ln -s ~/.antigravity/understand-anything/understand-anything-plugin/skills ~/.gemini/antigravity/skills/understand-anything
|
||||
# Universal plugin root symlink — lets the dashboard skill find packages/dashboard/
|
||||
# Skip if already exists (e.g. another platform was installed first)
|
||||
[ -e ~/.understand-anything-plugin ] || [ -L ~/.understand-anything-plugin ] || ln -s ~/.antigravity/understand-anything/understand-anything-plugin ~/.understand-anything-plugin
|
||||
```
|
||||
|
||||
**Windows (PowerShell):**
|
||||
```powershell
|
||||
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.gemini\antigravity\skills"
|
||||
cmd /c mklink /J "$env:USERPROFILE\.gemini\antigravity\skills\understand-anything" "$env:USERPROFILE\.antigravity\understand-anything\understand-anything-plugin\skills"
|
||||
cmd /c mklink /J "$env:USERPROFILE\.understand-anything-plugin" "$env:USERPROFILE\.antigravity\understand-anything\understand-anything-plugin"
|
||||
```
|
||||
|
||||
3. **Restart the chat or IDE** so Antigravity can discover the skills.
|
||||
@@ -52,5 +56,6 @@ Skills update instantly through the symlink.
|
||||
|
||||
```bash
|
||||
rm ~/.gemini/antigravity/skills/understand-anything
|
||||
rm ~/.understand-anything-plugin
|
||||
rm -rf ~/.antigravity/understand-anything
|
||||
```
|
||||
|
||||
+23
-7
@@ -11,16 +11,29 @@
|
||||
git clone https://github.com/Lum1104/Understand-Anything.git ~/.codex/understand-anything
|
||||
```
|
||||
|
||||
2. **Create the skills symlink:**
|
||||
2. **Create the skills symlinks:**
|
||||
```bash
|
||||
mkdir -p ~/.agents/skills
|
||||
ln -s ~/.codex/understand-anything/understand-anything-plugin/skills ~/.agents/skills/understand-anything
|
||||
# Note: if OpenCode's Understand-Anything is already installed, these symlinks
|
||||
# already exist and the ln commands will safely fail — that is fine, the
|
||||
# existing symlinks work for Codex too.
|
||||
for skill in understand understand-chat understand-dashboard understand-diff understand-explain understand-onboard; do
|
||||
ln -sf ~/.codex/understand-anything/understand-anything-plugin/skills/$skill ~/.agents/skills/$skill
|
||||
done
|
||||
# Universal plugin root symlink — lets the dashboard skill find packages/dashboard/
|
||||
# Skip if already exists (e.g. another platform was installed first)
|
||||
[ -e ~/.understand-anything-plugin ] || [ -L ~/.understand-anything-plugin ] || ln -s ~/.codex/understand-anything/understand-anything-plugin ~/.understand-anything-plugin
|
||||
```
|
||||
|
||||
**Windows (PowerShell):**
|
||||
```powershell
|
||||
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.agents\skills"
|
||||
cmd /c mklink /J "$env:USERPROFILE\.agents\skills\understand-anything" "$env:USERPROFILE\.codex\understand-anything\understand-anything-plugin\skills"
|
||||
$skills = @("understand","understand-chat","understand-dashboard","understand-diff","understand-explain","understand-onboard")
|
||||
foreach ($skill in $skills) {
|
||||
cmd /c mklink /J "$env:USERPROFILE\.agents\skills\$skill" "$env:USERPROFILE\.codex\understand-anything\understand-anything-plugin\skills\$skill"
|
||||
}
|
||||
# Universal plugin root symlink
|
||||
cmd /c mklink /J "$env:USERPROFILE\.understand-anything-plugin" "$env:USERPROFILE\.codex\understand-anything\understand-anything-plugin"
|
||||
```
|
||||
|
||||
3. **Restart Codex** to discover the skills.
|
||||
@@ -28,10 +41,10 @@
|
||||
## Verify
|
||||
|
||||
```bash
|
||||
ls -la ~/.agents/skills/understand-anything
|
||||
ls -la ~/.agents/skills/ | grep understand
|
||||
```
|
||||
|
||||
You should see a symlink pointing to the skills directory.
|
||||
You should see symlinks for each skill pointing into the cloned repository.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -45,11 +58,14 @@ Skills activate automatically when relevant. You can also invoke directly:
|
||||
cd ~/.codex/understand-anything && git pull
|
||||
```
|
||||
|
||||
Skills update instantly through the symlink.
|
||||
Skills update instantly through the symlinks.
|
||||
|
||||
## Uninstalling
|
||||
|
||||
```bash
|
||||
rm ~/.agents/skills/understand-anything
|
||||
for skill in understand understand-chat understand-dashboard understand-diff understand-explain understand-onboard; do
|
||||
rm -f ~/.agents/skills/$skill
|
||||
done
|
||||
rm ~/.understand-anything-plugin
|
||||
rm -rf ~/.codex/understand-anything
|
||||
```
|
||||
|
||||
@@ -11,16 +11,20 @@
|
||||
git clone https://github.com/Lum1104/Understand-Anything.git ~/.openclaw/understand-anything
|
||||
```
|
||||
|
||||
2. **Create the skills symlink:**
|
||||
2. **Create the skills symlinks:**
|
||||
```bash
|
||||
mkdir -p ~/.openclaw/skills
|
||||
ln -s ~/.openclaw/understand-anything/understand-anything-plugin/skills ~/.openclaw/skills/understand-anything
|
||||
# Universal plugin root symlink — lets the dashboard skill find packages/dashboard/
|
||||
# Skip if already exists (e.g. another platform was installed first)
|
||||
[ -e ~/.understand-anything-plugin ] || [ -L ~/.understand-anything-plugin ] || ln -s ~/.openclaw/understand-anything/understand-anything-plugin ~/.understand-anything-plugin
|
||||
```
|
||||
|
||||
**Windows (PowerShell):**
|
||||
```powershell
|
||||
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.openclaw\skills"
|
||||
cmd /c mklink /J "$env:USERPROFILE\.openclaw\skills\understand-anything" "$env:USERPROFILE\.openclaw\understand-anything\understand-anything-plugin\skills"
|
||||
cmd /c mklink /J "$env:USERPROFILE\.understand-anything-plugin" "$env:USERPROFILE\.openclaw\understand-anything\understand-anything-plugin"
|
||||
```
|
||||
|
||||
3. **Restart OpenClaw** to discover the skills.
|
||||
@@ -41,5 +45,6 @@ cd ~/.openclaw/understand-anything && git pull
|
||||
|
||||
```bash
|
||||
rm ~/.openclaw/skills/understand-anything
|
||||
rm ~/.understand-anything-plugin
|
||||
rm -rf ~/.openclaw/understand-anything
|
||||
```
|
||||
|
||||
+53
-22
@@ -2,55 +2,86 @@
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [OpenCode.ai](https://opencode.ai) installed
|
||||
- Git
|
||||
- [OpenCode](https://opencode.ai) installed
|
||||
|
||||
## Installation
|
||||
|
||||
Add understand-anything to the `plugin` array in your `opencode.json` (global or project-level):
|
||||
1. **Clone the repository:**
|
||||
```bash
|
||||
git clone https://github.com/Lum1104/Understand-Anything.git ~/.opencode/understand-anything
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"plugin": ["understand-anything@git+https://github.com/Lum1104/Understand-Anything.git"]
|
||||
}
|
||||
```
|
||||
2. **Create the skills symlinks:**
|
||||
```bash
|
||||
mkdir -p ~/.agents/skills
|
||||
# Note: if Codex's Understand-Anything is already installed, these symlinks
|
||||
# already exist and the ln commands will safely fail — that is fine, the
|
||||
# existing symlinks work for OpenCode too.
|
||||
for skill in understand understand-chat understand-dashboard understand-diff understand-explain understand-onboard; do
|
||||
ln -sf ~/.opencode/understand-anything/understand-anything-plugin/skills/$skill ~/.agents/skills/$skill
|
||||
done
|
||||
# Universal plugin root symlink — lets the dashboard skill find packages/dashboard/
|
||||
# Skip if already exists (e.g. another platform was installed first)
|
||||
[ -e ~/.understand-anything-plugin ] || [ -L ~/.understand-anything-plugin ] || ln -s ~/.opencode/understand-anything/understand-anything-plugin ~/.understand-anything-plugin
|
||||
```
|
||||
|
||||
Restart OpenCode. The plugin auto-installs and registers all skills.
|
||||
**Windows (PowerShell):**
|
||||
```powershell
|
||||
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.agents\skills"
|
||||
$skills = @("understand","understand-chat","understand-dashboard","understand-diff","understand-explain","understand-onboard")
|
||||
foreach ($skill in $skills) {
|
||||
cmd /c mklink /J "$env:USERPROFILE\.agents\skills\$skill" "$env:USERPROFILE\.opencode\understand-anything\understand-anything-plugin\skills\$skill"
|
||||
}
|
||||
# Universal plugin root symlink
|
||||
cmd /c mklink /J "$env:USERPROFILE\.understand-anything-plugin" "$env:USERPROFILE\.opencode\understand-anything\understand-anything-plugin"
|
||||
```
|
||||
|
||||
3. **Restart OpenCode** to discover the skills.
|
||||
|
||||
## Verify
|
||||
|
||||
Ask: "List available skills" — you should see understand, understand-chat, understand-dashboard, etc.
|
||||
```bash
|
||||
ls -la ~/.agents/skills/ | grep understand
|
||||
```
|
||||
|
||||
You should see symlinks for each skill pointing into the cloned repository.
|
||||
|
||||
## Usage
|
||||
|
||||
Skills activate automatically when relevant. You can also invoke directly:
|
||||
|
||||
```
|
||||
use skill tool to load understand-anything/understand
|
||||
use skill tool to load understand
|
||||
```
|
||||
|
||||
Or just ask: "Analyze this codebase and build a knowledge graph"
|
||||
|
||||
## Updating
|
||||
|
||||
Restart OpenCode — the plugin re-installs from git automatically.
|
||||
|
||||
To pin a specific version:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugin": ["understand-anything@git+https://github.com/Lum1104/Understand-Anything.git#v1.1.1"]
|
||||
}
|
||||
```bash
|
||||
cd ~/.opencode/understand-anything && git pull
|
||||
```
|
||||
|
||||
Skills update instantly through the symlinks.
|
||||
|
||||
## Uninstalling
|
||||
|
||||
Remove the plugin line from `opencode.json` and restart.
|
||||
```bash
|
||||
for skill in understand understand-chat understand-dashboard understand-diff understand-explain understand-onboard; do
|
||||
rm -f ~/.agents/skills/$skill
|
||||
done
|
||||
rm ~/.understand-anything-plugin
|
||||
rm -rf ~/.opencode/understand-anything
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Skills not found
|
||||
|
||||
1. Verify the plugin line in your `opencode.json`
|
||||
2. Check that `~/.cache/opencode/node_modules/understand-anything` exists after restart
|
||||
3. Use the `skill` tool to list discovered skills
|
||||
1. Check that the symlinks exist: `ls -la ~/.agents/skills/ | grep understand`
|
||||
2. Verify the clone succeeded: `ls ~/.opencode/understand-anything/understand-anything-plugin/skills/`
|
||||
3. Restart OpenCode
|
||||
|
||||
### Tool mapping
|
||||
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Understand Anything plugin for OpenCode.ai
|
||||
*
|
||||
* Auto-registers the skills directory so OpenCode discovers all
|
||||
* understand-anything skills without manual symlinks or config edits.
|
||||
*/
|
||||
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export const UnderstandAnythingPlugin = async ({ client, directory }) => {
|
||||
const skillsDir = path.resolve(__dirname, '../../understand-anything-plugin/skills');
|
||||
|
||||
return {
|
||||
config: async (config) => {
|
||||
config.skills = config.skills || {};
|
||||
config.skills.paths = config.skills.paths || [];
|
||||
if (!config.skills.paths.includes(skillsDir)) {
|
||||
config.skills.paths.push(skillsDir);
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
+4
-6
@@ -122,11 +122,9 @@ Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Und
|
||||
|
||||
### OpenCode
|
||||
|
||||
`opencode.json` に以下を追加:
|
||||
```json
|
||||
{
|
||||
"plugin": ["understand-anything@git+https://github.com/Lum1104/Understand-Anything.git"]
|
||||
}
|
||||
OpenCodeに以下を伝えてください:
|
||||
```
|
||||
Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Understand-Anything/refs/heads/main/.opencode/INSTALL.md
|
||||
```
|
||||
|
||||
### OpenClaw
|
||||
@@ -153,7 +151,7 @@ Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Und
|
||||
|----------|--------|----------------|
|
||||
| Claude Code | ✅ ネイティブ | プラグインマーケットプレイス |
|
||||
| Codex | ✅ サポート | AI駆動インストール |
|
||||
| OpenCode | ✅ サポート | プラグイン設定 |
|
||||
| OpenCode | ✅ サポート | AI駆動インストール |
|
||||
| OpenClaw | ✅ サポート | AI駆動インストール |
|
||||
| Cursor | ✅ サポート | 自動検出 |
|
||||
| Antigravity | ✅ サポート | AI駆動インストール |
|
||||
|
||||
@@ -122,11 +122,9 @@ Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Und
|
||||
|
||||
### OpenCode
|
||||
|
||||
Add to your `opencode.json`:
|
||||
```json
|
||||
{
|
||||
"plugin": ["understand-anything@git+https://github.com/Lum1104/Understand-Anything.git"]
|
||||
}
|
||||
Tell OpenCode:
|
||||
```
|
||||
Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Understand-Anything/refs/heads/main/.opencode/INSTALL.md
|
||||
```
|
||||
|
||||
### OpenClaw
|
||||
@@ -153,7 +151,7 @@ Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Und
|
||||
|----------|--------|----------------|
|
||||
| Claude Code | ✅ Native | Plugin marketplace |
|
||||
| Codex | ✅ Supported | AI-driven install |
|
||||
| OpenCode | ✅ Supported | Plugin config |
|
||||
| OpenCode | ✅ Supported | AI-driven install |
|
||||
| OpenClaw | ✅ Supported | AI-driven install |
|
||||
| Cursor | ✅ Supported | Auto-discovery |
|
||||
| Antigravity | ✅ Supported | AI-driven install |
|
||||
|
||||
+4
-6
@@ -121,11 +121,9 @@ Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Und
|
||||
|
||||
### OpenCode
|
||||
|
||||
添加到你的 `opencode.json` 文件:
|
||||
```json
|
||||
{
|
||||
"plugin": ["understand-anything@git+https://github.com/Lum1104/Understand-Anything.git"]
|
||||
}
|
||||
告诉 OpenCode:
|
||||
```
|
||||
Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Understand-Anything/refs/heads/main/.opencode/INSTALL.md
|
||||
```
|
||||
|
||||
### OpenClaw
|
||||
@@ -152,7 +150,7 @@ Fetch and follow instructions from https://raw.githubusercontent.com/Lum1104/Und
|
||||
|----------|--------|----------------|
|
||||
| Claude Code | ✅ Native | 插件市场 |
|
||||
| Codex | ✅ 支持 | AI驱动安装 |
|
||||
| OpenCode | ✅ 支持 | 插件配置 |
|
||||
| OpenCode | ✅ 支持 | AI驱动安装 |
|
||||
| OpenClaw | ✅ 支持 | AI驱动安装 |
|
||||
| Cursor | ✅ 支持 | 自动发现 |
|
||||
| Antigravity | ✅ 支持 | AI驱动安装 |
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
# Language-Agnostic Support Design
|
||||
|
||||
**Date:** 2026-03-21
|
||||
**Status:** Approved
|
||||
**Issue:** Make Understand-Anything codebase-aware and language-agnostic instead of TypeScript-heavy
|
||||
|
||||
## Problem
|
||||
|
||||
The tool's agent prompts, tree-sitter plugin, and language lesson system are heavily biased toward TypeScript/JavaScript. Non-TS codebases get degraded analysis because:
|
||||
|
||||
1. Agent prompts use TS-specific examples and concepts (e.g., "barrel files", "type guards", "generics")
|
||||
2. Tree-sitter plugin only ships TS/JS grammar support — structural analysis silently fails for other languages
|
||||
3. Language lesson detection hardcodes TS-specific concept patterns and display names
|
||||
|
||||
The architecture (PluginRegistry, GraphBuilder, dashboard, search) is already language-neutral. The bias is in shipped content, not the framework.
|
||||
|
||||
## Decisions
|
||||
|
||||
- **Scope:** All three layers — prompts, tree-sitter plugins, language framework
|
||||
- **Languages (v1):** TypeScript, JavaScript, Python, Go, Java, Rust, C/C++, C#, Ruby, PHP, Swift, Kotlin
|
||||
- **Architecture:** Config-first with code escape hatch (hybrid)
|
||||
- **Prompt strategy:** Base prompt + per-language markdown snippet files in a `languages/` folder
|
||||
- **Config location:** Prompt snippets in `skills/understand/languages/`, tree-sitter configs in `packages/core/src/languages/`
|
||||
- **Multi-language projects:** Per-file language analysis + project-level multi-language summary
|
||||
- **Language detection:** Auto-detect from file extensions only (no manual override for v1)
|
||||
|
||||
## Design
|
||||
|
||||
### 1. LanguageConfig Type & Registry
|
||||
|
||||
#### LanguageConfig Interface
|
||||
|
||||
```typescript
|
||||
// packages/core/src/languages/types.ts
|
||||
interface LanguageConfig {
|
||||
id: string; // e.g., "python"
|
||||
displayName: string; // e.g., "Python"
|
||||
extensions: string[]; // e.g., [".py", ".pyi"]
|
||||
treeSitter: {
|
||||
grammarPackage: string; // npm package name
|
||||
nodeTypes: {
|
||||
function: string[]; // e.g., ["function_definition"]
|
||||
class: string[]; // e.g., ["class_definition"]
|
||||
import: string[]; // e.g., ["import_statement", "import_from_statement"]
|
||||
export: string[]; // e.g., ["export_statement"] or [] for languages without exports
|
||||
typeAnnotation: string[]; // e.g., ["type"] for Python type hints
|
||||
};
|
||||
};
|
||||
concepts: string[]; // e.g., ["decorators", "list comprehensions", "generators"]
|
||||
filePatterns?: Record<string, string>; // special files, e.g., {"config": "pyproject.toml"}
|
||||
customAnalyzer?: (node: SyntaxNode) => AnalysisResult; // escape hatch for unusual AST shapes
|
||||
}
|
||||
```
|
||||
|
||||
#### Language Registry
|
||||
|
||||
```typescript
|
||||
// packages/core/src/languages/registry.ts
|
||||
class LanguageRegistry {
|
||||
private configs: Map<string, LanguageConfig>;
|
||||
|
||||
register(config: LanguageConfig): void;
|
||||
getByExtension(ext: string): LanguageConfig | null;
|
||||
getById(id: string): LanguageConfig;
|
||||
getAll(): LanguageConfig[];
|
||||
}
|
||||
```
|
||||
|
||||
#### File Structure
|
||||
|
||||
```
|
||||
packages/core/src/languages/
|
||||
├── types.ts
|
||||
├── registry.ts
|
||||
├── index.ts
|
||||
├── configs/
|
||||
│ ├── typescript.ts
|
||||
│ ├── javascript.ts
|
||||
│ ├── python.ts
|
||||
│ ├── go.ts
|
||||
│ ├── java.ts
|
||||
│ ├── rust.ts
|
||||
│ ├── cpp.ts
|
||||
│ ├── csharp.ts
|
||||
│ ├── ruby.ts
|
||||
│ ├── php.ts
|
||||
│ ├── swift.ts
|
||||
│ └── kotlin.ts
|
||||
```
|
||||
|
||||
All built-in configs auto-registered on import.
|
||||
|
||||
### 2. GenericTreeSitterPlugin
|
||||
|
||||
Replaces the current TS-only `TreeSitterPlugin` with a config-driven version.
|
||||
|
||||
```typescript
|
||||
// packages/core/src/plugins/generic-tree-sitter-plugin.ts
|
||||
class GenericTreeSitterPlugin implements AnalyzerPlugin {
|
||||
private registry: LanguageRegistry;
|
||||
|
||||
canAnalyze(filePath: string): boolean {
|
||||
return this.registry.getByExtension(path.extname(filePath)) !== null;
|
||||
}
|
||||
|
||||
async analyzeFile(filePath: string, content: string): Promise<FileAnalysis> {
|
||||
const config = this.registry.getByExtension(path.extname(filePath));
|
||||
|
||||
// Custom analyzer escape hatch
|
||||
if (config.customAnalyzer) {
|
||||
return config.customAnalyzer(tree.rootNode);
|
||||
}
|
||||
|
||||
// Generic extraction driven by config.treeSitter.nodeTypes
|
||||
const functions = this.extractNodes(tree, config.treeSitter.nodeTypes.function);
|
||||
const classes = this.extractNodes(tree, config.treeSitter.nodeTypes.class);
|
||||
const imports = this.extractNodes(tree, config.treeSitter.nodeTypes.import);
|
||||
const exports = this.extractNodes(tree, config.treeSitter.nodeTypes.export);
|
||||
// ...
|
||||
}
|
||||
|
||||
private extractNodes(tree: Tree, nodeTypes: string[]): NodeInfo[] {
|
||||
// Walk AST, collect all nodes matching any of the given types
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Migration
|
||||
|
||||
- Current `TreeSitterPlugin` deleted, replaced by `GenericTreeSitterPlugin` + TS/JS configs
|
||||
- `PluginRegistry` unchanged
|
||||
- Existing tests updated to use new plugin
|
||||
|
||||
#### WASM Grammar Loading
|
||||
|
||||
- Each grammar loaded lazily on first use and cached
|
||||
- WASM files bundled in `packages/core/src/languages/grammars/` or fetched from tree-sitter's official WASM builds
|
||||
|
||||
### 3. Language-Aware Prompts
|
||||
|
||||
#### File Structure
|
||||
|
||||
```
|
||||
skills/understand/
|
||||
├── file-analyzer-prompt.md # Base prompt (language-neutral)
|
||||
├── tour-builder-prompt.md
|
||||
├── project-scanner-prompt.md
|
||||
├── languages/
|
||||
│ ├── typescript.md
|
||||
│ ├── javascript.md
|
||||
│ ├── python.md
|
||||
│ ├── go.md
|
||||
│ ├── java.md
|
||||
│ ├── rust.md
|
||||
│ ├── cpp.md
|
||||
│ ├── csharp.md
|
||||
│ ├── ruby.md
|
||||
│ ├── php.md
|
||||
│ ├── swift.md
|
||||
│ └── kotlin.md
|
||||
```
|
||||
|
||||
#### Base Prompt Changes
|
||||
|
||||
All TS-specific examples removed from base prompts. Replaced with injection point:
|
||||
|
||||
```markdown
|
||||
## Language-Specific Guidance
|
||||
|
||||
{{LANGUAGE_CONTEXT}}
|
||||
```
|
||||
|
||||
#### Language Markdown Format
|
||||
|
||||
Each language file contains:
|
||||
|
||||
```markdown
|
||||
# Python
|
||||
|
||||
## Key Concepts
|
||||
- Decorators, comprehensions, generators, context managers, type hints, dunder methods
|
||||
|
||||
## Import Patterns
|
||||
- `import module`, `from module import name`, relative imports
|
||||
|
||||
## Notable File Patterns
|
||||
- `__init__.py` (package initializer), `conftest.py` (pytest), `pyproject.toml` (config)
|
||||
|
||||
## Example Summary Style
|
||||
> "FastAPI route handler that accepts a Pydantic model, validates input..."
|
||||
```
|
||||
|
||||
#### Injection Logic
|
||||
|
||||
1. Project scanner detects languages present in the codebase
|
||||
2. File-analyzer: inject matching language `.md` for that file's language
|
||||
3. Tour-builder: inject all detected languages' `.md` files
|
||||
4. Project-scanner: inject all detected languages' key concepts for project-level summary
|
||||
|
||||
#### Multi-Language Projects
|
||||
|
||||
Project-scanner prompt gets a combined section listing all detected languages with their key concepts.
|
||||
|
||||
### 4. Language Lesson Updates
|
||||
|
||||
- Delete `LANGUAGE_DISPLAY_NAMES` — use `LanguageRegistry.getById(id).displayName`
|
||||
- Delete hardcoded concept patterns — use `LanguageConfig.concepts` from registry
|
||||
- Language lesson generation becomes config-driven
|
||||
|
||||
### 5. Testing Strategy
|
||||
|
||||
#### Unit Tests
|
||||
|
||||
1. **LanguageConfig validation** — Each config has all required fields, non-empty nodeTypes
|
||||
2. **LanguageRegistry** — Registration, lookup by extension/id, duplicate handling
|
||||
3. **GenericTreeSitterPlugin per language** — Small fixture file per language verifying function/class/import extraction
|
||||
4. **Language lesson generation** — Concepts sourced from config
|
||||
|
||||
#### Integration Tests
|
||||
|
||||
5. **Multi-language project** — Mixed TS + Python fixture, verify graph contains nodes from both languages
|
||||
6. **Prompt injection** — Correct language `.md` injected based on detected language
|
||||
|
||||
#### Migration Tests
|
||||
|
||||
- Current tree-sitter-plugin tests rewritten for GenericTreeSitterPlugin with TS config
|
||||
- Must produce identical results to validate non-breaking migration
|
||||
|
||||
### 6. Error Handling & Graceful Degradation
|
||||
|
||||
#### Key Principle
|
||||
|
||||
**Every file always gets analyzed.** Tree-sitter is an enhancement, not a gate. The LLM is the primary analyzer; structural analysis enriches it.
|
||||
|
||||
#### Unknown Language
|
||||
|
||||
- Tree-sitter skipped (returns `null`)
|
||||
- LLM analysis still runs — file gets summary, tags, graph node
|
||||
- Debug log: `"No language config for .xyz, skipping structural analysis"`
|
||||
|
||||
#### Missing WASM Grammar
|
||||
|
||||
- Warning logged, that language degrades to LLM-only
|
||||
- Other languages unaffected
|
||||
|
||||
#### Malformed Language Config
|
||||
|
||||
- Validated at registration time via Zod schema
|
||||
- Invalid config throws at startup — fail fast
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,13 +19,31 @@ Start the Understand Anything dashboard to visualize the knowledge graph for the
|
||||
No knowledge graph found. Run /understand first to analyze this project.
|
||||
```
|
||||
|
||||
3. Find the dashboard code. The dashboard is at `packages/dashboard/` relative to this plugin's root directory. Use the Bash tool to resolve the path:
|
||||
3. Find the dashboard code. The dashboard is at `packages/dashboard/` relative to this plugin's root directory. Check these paths in order and use the first that exists:
|
||||
- `~/.understand-anything-plugin/packages/dashboard/` (universal symlink, all installs)
|
||||
- `${CLAUDE_PLUGIN_ROOT}/packages/dashboard/` (Claude Code plugin)
|
||||
- Two levels up from this skill file's real path: `../../packages/dashboard/` (self-relative fallback)
|
||||
|
||||
Use the Bash tool to resolve:
|
||||
```bash
|
||||
PLUGIN_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
SKILL_REAL=$(realpath ~/.agents/skills/understand-dashboard 2>/dev/null || readlink -f ~/.agents/skills/understand-dashboard 2>/dev/null || echo "")
|
||||
SELF_RELATIVE=$([ -n "$SKILL_REAL" ] && cd "$SKILL_REAL/../.." 2>/dev/null && pwd || echo "")
|
||||
|
||||
PLUGIN_ROOT=""
|
||||
for candidate in \
|
||||
"$HOME/.understand-anything-plugin" \
|
||||
"${CLAUDE_PLUGIN_ROOT}" \
|
||||
"$SELF_RELATIVE"; do
|
||||
if [ -n "$candidate" ] && [ -d "$candidate/packages/dashboard" ]; then
|
||||
PLUGIN_ROOT="$candidate"; break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$PLUGIN_ROOT" ]; then
|
||||
echo "Error: Cannot find the understand-anything plugin root. Make sure you followed the installation instructions and that ~/.understand-anything-plugin exists."
|
||||
exit 1
|
||||
fi
|
||||
```
|
||||
Or locate it by checking these paths in order:
|
||||
- `${CLAUDE_PLUGIN_ROOT}/packages/dashboard/`
|
||||
- The parent directory of this skill file, then `../../packages/dashboard/`
|
||||
|
||||
4. Install dependencies and build if needed:
|
||||
```bash
|
||||
|
||||
Reference in New Issue
Block a user