diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..94f8dbb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,87 @@ +name: Bug Report +description: Report a bug with Reference Graph +labels: ["bug"] +body: + - type: textarea + id: screenshot + attributes: + label: Screenshot + description: Please attach a screenshot or GIF showing the issue. This is critical for visual bugs. + placeholder: Drag and drop an image here + validations: + required: true + + - type: textarea + id: description + attributes: + label: Description + description: What happened? What did you expect to happen? + placeholder: | + When I run "Show Reference Graph" on a function... + + Expected: ... + Actual: ... + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to Reproduce + description: How can we reproduce this issue? + placeholder: | + 1. Open a TypeScript file + 2. Place cursor on function `foo` + 3. Right-click → "Show Reference Graph" + 4. See error... + validations: + required: true + + - type: input + id: language + attributes: + label: Language / File Type + description: What language or file type were you using? + placeholder: "TypeScript, Vue, Python, etc." + validations: + required: true + + - type: input + id: extension-version + attributes: + label: Extension Version + description: Reference Graph version (Extensions sidebar → Reference Graph → gear icon) + placeholder: "0.0.2" + validations: + required: true + + - type: textarea + id: vscode-version + attributes: + label: VS Code Version + description: "Copy from: Help → About" + placeholder: | + Version: 1.85.0 + Commit: ... + Date: ... + validations: + required: true + + - type: dropdown + id: os + attributes: + label: Operating System + options: + - macOS + - Windows + - Linux + validations: + required: true + + - type: textarea + id: additional + attributes: + label: Additional Context + description: Any other relevant information (console errors, related extensions, etc.) + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3ba13e0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..247bf9c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,23 @@ +name: Feature Request +description: Suggest a new feature or improvement +labels: ["enhancement"] +body: + - type: textarea + id: description + attributes: + label: Description + description: What feature or improvement would you like to see? + placeholder: | + I'd like to be able to... + + This would help because... + validations: + required: true + + - type: textarea + id: mockup + attributes: + label: Mockup / Example + description: If applicable, attach a mockup, screenshot, or example of how this might work + validations: + required: false diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..77f3f51 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,62 @@ +## Screenshot + + + +## Summary + + + +## Manual QA Checklist + + + +### Graph Rendering +- [ ] Nodes don't overlap each other +- [ ] Edges route cleanly (no edge-node overlaps) +- [ ] Root node has distinct styling +- [ ] Layout fits well for your test case + +### Navigation +- [ ] Click node → correct file opens at correct line +- [ ] Editor gains focus after click (not stuck in webview) + +### Node Expansion +- [ ] "expand" label appears on expandable nodes +- [ ] Clicking expand adds new nodes to graph +- [ ] Graph re-layouts smoothly after expansion + +### Search (Cmd/Ctrl+F) +- [ ] Search bar opens +- [ ] Matching nodes highlight +- [ ] Enter cycles to next match +- [ ] Shift+Enter cycles to previous match +- [ ] View auto-centers on focused match +- [ ] Escape closes search + +### File Filter +- [ ] Include pattern filters correctly (e.g., `src/**/*.ts`) +- [ ] Exclude pattern filters correctly +- [ ] "Hide filtered nodes" removes nodes (vs dimming) +- [ ] Node count updates correctly + +### Hide Imports +- [ ] Checkbox toggles import node visibility + +### Export PNG +- [ ] Button triggers save dialog +- [ ] Saved image contains visible nodes + +### Code Preview +- [ ] Syntax highlighting renders correctly +- [ ] Referenced symbol is highlighted in snippet + +### States +- [ ] Loading spinner shows while building graph +- [ ] Error message displays for invalid symbols + +### Console +- [ ] No errors in webview DevTools (F12 in Extension Host) + +## Notes + + diff --git a/AGENTS.md b/AGENTS.md index 3c9addf..06beddc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,71 +2,29 @@ VS Code extension that visualizes code references as an interactive graph. -## Commands - -```bash -npm install && cd webview-ui && npm install && cd .. # Install deps -npm run build # Build all (extension + webview) -npm run watch # Watch mode (extension only) -npm run lint # ESLint -npm run test # Run tests -``` - -Debug: Press F5 in VS Code to launch Extension Development Host. - -## Project Layout - -| Area | Entry Point | Look Here For | -|------|-------------|---------------| -| Extension | `src/extension.ts` | Command registration, activation | -| Graph logic | `src/graph/GraphBuilder.ts` | Reference traversal, node/edge building | -| File refs | `src/fileReferences/` | File reference provider architecture | -| Webview host | `src/webview/WebviewProvider.ts` | Panel creation, message handling | -| React app | `webview-ui/src/App.tsx` | UI state, message reception | -| Graph UI | `webview-ui/src/components/ReferenceGraph.tsx` | React Flow setup | -| Layout | `webview-ui/src/hooks/useElkLayout.ts` | ELK.js configuration | -| Types | `src/graph/types.ts` | All shared type definitions | - -## Architecture Notes - -- **Two runtimes**: Extension (Node.js) and Webview (Chromium) communicate via `postMessage` -- **Dual traversal strategy**: Call Hierarchy API for functions, References API for other symbols -- **File reference providers**: Language-agnostic architecture with priority-based selection (see below) -- **Build outputs**: `out/extension.js` (extension) + `out/webview-assets/` (webview bundle) - -For details, read the source files directly. Types and data flow are self-documenting. - -### File Reference Provider Architecture - -The file reference feature uses a provider pattern for language-specific optimizations: - -| Component | Path | Purpose | -|-----------|------|---------| -| Interface | `src/fileReferences/types.ts` | `FileReferenceProvider` contract | -| Registry | `src/fileReferences/FileReferenceRegistry.ts` | Singleton, priority-based selection | -| Resolver | `src/fileReferences/FileReferenceResolver.ts` | Entry point for lookups | -| Generic | `src/fileReferences/providers/GenericFileReferenceProvider.ts` | Fallback (priority: -10) | -| TypeScript | `src/fileReferences/providers/TypeScriptFileReferenceProvider.ts` | TS/JS optimized (priority: 10) | - -**Adding a new provider:** -1. Implement `FileReferenceProvider` interface -2. Register in `src/fileReferences/providers/index.ts` -3. Higher priority wins when multiple providers match +For commands, project structure, and architecture details, see **[docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)**. ## Documentation Rules (CRITICAL) **Single Source of Truth:** -- `README.md` — User-facing documentation (features, usage, shortcuts) -- `AGENTS.md` — Agent workflow instructions (this file) -- `package.json` — Extension manifest, commands, configuration schema + +| Document | Purpose | +|----------|---------| +| `README.md` | User-facing documentation (features, usage) | +| `CONTRIBUTING.md` | Contributor guidelines (PRs, tests, fixtures) | +| `docs/DEVELOPMENT.md` | Technical reference (commands, structure, architecture) | +| `AGENTS.md` | Agent workflow instructions (this file) | +| `package.json` | Extension manifest, commands, configuration schema | **When to update what:** + | Change | Update | |--------|--------| | New user-facing feature | `README.md` | | New command or config option | `package.json` contributes section | -| New npm script | `package.json` scripts section | -| Changed project structure | `AGENTS.md` Project Layout table | +| New npm script | `package.json` scripts, `docs/DEVELOPMENT.md` Commands | +| Changed project structure | `docs/DEVELOPMENT.md` Project Structure table | +| Test/fixture patterns | `CONTRIBUTING.md` | | Internal refactoring | Nothing (code is the documentation) | **Never duplicate information across files.** If something is defined in code (types, config), point to the file instead of copying content. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2fb7f78 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,86 @@ +# Contributing to Reference Graph + +PRs are welcome! This document explains how to contribute effectively. + +For commands and project structure, see **[docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)**. + +## Writing Tests + +### General Guidelines + +- **Add to existing test suites** when extending existing functionality +- **Create new fixtures** when testing new languages or patterns +- **Follow existing patterns** — look at similar tests for reference + +### Fixture Structure + +Fixtures live in `src/test/fixtures/`. Each fixture directory should be self-contained: + +``` +src/test/fixtures/ +├── file-references/ # TypeScript file import tests +│ ├── core.ts +│ ├── consumer.ts +│ ├── anotherConsumer.ts +│ └── tsconfig.json +├── vue-file-references/ # Vue file import tests +│ ├── core.vue +│ ├── consumer.vue +│ ├── anotherConsumer.vue +│ ├── tsconfig.json +│ └── package.json +└── symbol-references/ # Symbol reference tests + ├── utils.ts + ├── service.ts + ├── config.ts + └── tsconfig.json +``` + +**When adding a new language provider**, create a corresponding fixture directory with: +- Sample source files demonstrating import/export patterns +- Necessary config files (`tsconfig.json`, `package.json`, etc.) +- At least 3 files to test the reference chain (root → consumer → leaf) + +### Test Pattern + +```typescript +suite('MyLanguage FileReferenceResolver Test Suite', function () { + this.timeout(30000); // Language servers need time + + suiteSetup(async () => { + registerBuiltinProviders(); + await waitForLanguageServer(); // Wait for relevant extension + // Open fixture files to trigger language server + }); + + test('finds files that import core file', async () => { + const resolver = new FileReferenceResolver(); + const coreUri = vscode.Uri.file(path.join(fixturesPath, 'core.xyz')); + + const references = await resolver.findFileReferences(coreUri); + const referringFiles = references.map(r => path.basename(r.uri.fsPath)).sort(); + + assert.deepStrictEqual(referringFiles, ['consumer.xyz', 'other.xyz']); + }); +}); +``` + +## Adding a New Language Provider + +See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md#adding-a-new-provider) for the implementation guide. + +**After implementing, add tests:** + +1. Create fixture directory: `src/test/fixtures/mylang-file-references/` +2. Add test cases to `src/test/fileReferences.test.ts` or create a new test file +3. Test with real-world code, not just fixtures + +## Code Style + +- Run `npm run lint:all` before committing +- Follow existing patterns in the codebase +- TypeScript strict mode is enabled + +## Questions? + +Open an issue if you have questions or want to discuss a feature before implementing. diff --git a/README.ja.md b/README.ja.md new file mode 100644 index 0000000..9bf7af6 --- /dev/null +++ b/README.ja.md @@ -0,0 +1,45 @@ +# Reference Graph + +[English](README.md) | 日本語 | [简体中文](README.zh-CN.md) + +コード参照をインタラクティブなグラフで可視化します。 + +![Reference Graph Demo](screenshot.gif) + +## 機能 + +- **インタラクティブなグラフ表示**: React Flowを使用して、シンボルへの全ての参照を接続されたグラフとして表示 +- **コードプレビュー**: 各ノードに参照箇所の前後3行をシンタックスハイライト付きで表示 +- **シンボルハイライト**: コードスニペット内の参照されたシンボルをハイライト表示 +- **スマートレイアウト**: ELKjsによるノードサイズを考慮した自動グラフレイアウト +- **ファイルフィルタリング**: globパターンでノードをフィルタリング(例: `src/**/*.ts`, `**/test/**`) +- **PNG出力**: 現在のグラフ表示をPNG画像として保存 +- **クリックでナビゲート**: ノードをクリックしてエディタの該当位置にジャンプ + +## 使い方 + +1. 関数、変数、その他のシンボルにカーソルを置く +2. 右クリックして「Show Reference Graph」を選択、またはコマンドパレットから実行 +3. サイドパネルに全ての参照を示すグラフが表示されます + +### ノードのフィルタリング + +左上のフィルターパネルで特定のファイルに絞り込めます: +- **Files to include**: 指定パターンに一致するファイルのみ表示(例: `src/**/*.ts`) +- **Files to exclude**: 指定パターンに一致するファイルを非表示(例: `**/node_modules/**`) +- **Hide filtered nodes**: フィルタリングされたノードを薄暗くする代わりに完全に非表示にする + +パターンはglob構文を使用します — `**` は任意のディレクトリ階層、`*` は任意のファイル名にマッチします。 + +### PNGとして出力 + +右上の **Export PNG** ボタンをクリックすると、現在のグラフ表示を画像として保存できます。 + +## 要件 + +- VS Code 1.80.0 以上 +- "Find All References" をサポートする言語サーバー + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md). diff --git a/README.md b/README.md index c468805..4ce0dca 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,29 @@ # Reference Graph +English | [日本語](README.ja.md) | [简体中文](README.zh-CN.md) + Visualize code references as an interactive graph. +![Reference Graph Demo](screenshot.gif) + ## Features - **Interactive Graph View**: See all references to a symbol displayed as a connected graph using React Flow -- **File Reference Graph**: Visualize which files import a specific file (right-click in Explorer or use Command Palette) - **Code Preview**: Each node shows a syntax-highlighted code snippet (±3 lines) around the reference - **Symbol Highlighting**: The referenced symbol is highlighted within each code snippet - **Smart Layout**: Automatic graph layout using ELKjs that considers node sizes -- **Search**: Press `Cmd/Ctrl+F` to search nodes by symbol name or file path - **File Filtering**: Filter nodes by file path using glob patterns (e.g., `src/**/*.ts`, `**/test/**`) - **Export PNG**: Save the current graph view as a PNG image - **Click to Navigate**: Click any node to jump to that location in your editor ## Usage -### Symbol References 1. Place your cursor on a function, variable, or other symbol 2. Right-click and select "Show Reference Graph" or use the Command Palette 3. The graph will appear in a side panel showing all references -### File References -1. Right-click on a file in the Explorer sidebar -2. Select "Show File Reference Graph" -3. The graph shows all files that import the selected file - ### Filtering Nodes + Use the filter panel (top-left) to focus on specific files: - **Files to include**: Show only matching files (e.g., `src/**/*.ts`) - **Files to exclude**: Hide matching files (e.g., `**/node_modules/**`) @@ -35,18 +32,14 @@ Use the filter panel (top-left) to focus on specific files: Patterns use glob syntax — `**` matches any directory depth, `*` matches any filename. ### Exporting as PNG -Click the **Export PNG** button (top-right) to save the current graph view as an image. A save dialog will open to choose the destination. -## Keyboard Shortcuts - -| Shortcut | Action | -|----------|--------| -| `Cmd/Ctrl+F` | Open search | -| `Enter` | Next match | -| `Shift+Enter` | Previous match | -| `Escape` | Close search | +Click the **Export PNG** button (top-right) to save the current graph view as an image. ## Requirements - VS Code 1.80.0 or higher - A language server that supports "Find All References" + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md). diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 0000000..7187e31 --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,45 @@ +# Reference Graph + +[English](README.md) | [日本語](README.ja.md) | 简体中文 + +将代码引用可视化为交互式图表。 + +![Reference Graph Demo](screenshot.gif) + +## 功能 + +- **交互式图表视图**: 使用 React Flow 将符号的所有引用显示为连接的图表 +- **代码预览**: 每个节点显示引用位置前后3行的语法高亮代码片段 +- **符号高亮**: 在代码片段中高亮显示被引用的符号 +- **智能布局**: 使用 ELKjs 进行考虑节点大小的自动图表布局 +- **文件过滤**: 使用 glob 模式过滤节点(例如:`src/**/*.ts`、`**/test/**`) +- **导出 PNG**: 将当前图表视图保存为 PNG 图片 +- **点击导航**: 点击任意节点跳转到编辑器中的对应位置 + +## 使用方法 + +1. 将光标放在函数、变量或其他符号上 +2. 右键点击并选择「Show Reference Graph」,或使用命令面板 +3. 图表将显示在侧边面板中,展示所有引用 + +### 过滤节点 + +使用左上角的过滤面板聚焦特定文件: +- **Files to include**: 仅显示匹配的文件(例如:`src/**/*.ts`) +- **Files to exclude**: 隐藏匹配的文件(例如:`**/node_modules/**`) +- **Hide filtered nodes**: 切换为完全移除不匹配的节点(而不是将其变暗) + +模式使用 glob 语法 — `**` 匹配任意目录深度,`*` 匹配任意文件名。 + +### 导出为 PNG + +点击右上角的 **Export PNG** 按钮,将当前图表视图保存为图片。 + +## 系统要求 + +- VS Code 1.80.0 或更高版本 +- 支持「查找所有引用」的语言服务器 + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md). diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md new file mode 100644 index 0000000..8d3cd5f --- /dev/null +++ b/docs/DEVELOPMENT.md @@ -0,0 +1,82 @@ +# Development Guide + +## Commands + +```bash +npm install && cd webview-ui && npm install && cd .. # Install deps +npm run build # Build all (extension + webview) +npm run watch # Watch mode (extension only) +npm run lint # ESLint +npm run lint:all # ESLint (extension + webview) +npm run test # Run tests +``` + +**Debug**: Press F5 in VS Code to launch Extension Development Host. + +## Project Structure + +| Area | Entry Point | Description | +|------|-------------|-------------| +| Extension | `src/extension.ts` | Command registration, activation | +| Graph logic | `src/graph/GraphBuilder.ts` | Reference traversal, node/edge building | +| File refs | `src/fileReferences/` | File reference provider architecture | +| Webview host | `src/webview/WebviewProvider.ts` | Panel creation, message handling | +| React app | `webview-ui/src/App.tsx` | UI state, message reception | +| Graph UI | `webview-ui/src/components/ReferenceGraph.tsx` | React Flow setup | +| Layout | `webview-ui/src/hooks/useElkLayout.ts` | ELK.js configuration | +| Types | `src/graph/types.ts` | All shared type definitions | +| Tests | `src/test/`, `webview-ui/src/**/__tests__/` | Test files | +| Fixtures | `src/test/fixtures/` | Test fixture files | + +## Architecture + +- **Two runtimes**: Extension (Node.js) and Webview (Chromium) communicate via `postMessage` +- **Dual traversal strategy**: Call Hierarchy API for functions, References API for other symbols +- **File reference providers**: Language-agnostic architecture with priority-based selection +- **Build outputs**: `out/extension.js` (extension) + `out/webview-assets/` (webview bundle) + +## File Reference Provider Architecture + +The file reference feature uses a provider pattern for language-specific optimizations: + +| Component | Path | Purpose | +|-----------|------|---------| +| Interface | `src/fileReferences/types.ts` | `FileReferenceProvider` contract | +| Registry | `src/fileReferences/FileReferenceRegistry.ts` | Singleton, priority-based selection | +| Resolver | `src/fileReferences/FileReferenceResolver.ts` | Entry point for lookups | +| Generic | `src/fileReferences/providers/GenericFileReferenceProvider.ts` | Fallback (priority: -10) | +| TypeScript | `src/fileReferences/providers/TypeScriptFileReferenceProvider.ts` | TS/JS optimized (priority: 10) | + +### Adding a New Provider + +1. Create `src/fileReferences/providers/MyLanguageFileReferenceProvider.ts`: + +```typescript +import * as vscode from 'vscode'; +import type { FileReferenceProvider, FileReferenceResult } from '../types'; + +export class MyLanguageFileReferenceProvider implements FileReferenceProvider { + readonly id = 'mylanguage'; + readonly supportedLanguageIds = ['mylang']; // vscode languageId + readonly priority = 10; // Higher than generic (-10) + + async findFileReferences( + uri: vscode.Uri, + token?: vscode.CancellationToken + ): Promise { + // Implementation + } +} +``` + +2. Register in `src/fileReferences/providers/index.ts` + +3. Add tests and fixtures (see [CONTRIBUTING.md](../CONTRIBUTING.md)) + +### Priority Guidelines + +| Priority | Use Case | +|----------|----------| +| 10+ | Language-specific optimized provider | +| 0 | Default | +| -10 | Generic fallback | diff --git a/screenshot.gif b/screenshot.gif new file mode 100644 index 0000000..98ab18e Binary files /dev/null and b/screenshot.gif differ diff --git a/src/extension.ts b/src/extension.ts index 0d20f00..d30f21e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,7 +6,7 @@ export function activate(context: vscode.ExtensionContext) { const showGraphCmd = vscode.commands.registerCommand( 'referenceGraph.show', - (uri?: vscode.Uri) => webviewProvider.showReferenceGraph(uri) + (uri?: vscode.Uri) => webviewProvider.showReferenceGraph() ); context.subscriptions.push(showGraphCmd); diff --git a/src/webview/WebviewProvider.ts b/src/webview/WebviewProvider.ts index d3bfa65..fa1871a 100644 --- a/src/webview/WebviewProvider.ts +++ b/src/webview/WebviewProvider.ts @@ -14,11 +14,7 @@ export class WebviewProvider { registerBuiltinProviders(); } - async showReferenceGraph(explorerUri?: vscode.Uri): Promise { - if (explorerUri) { - return this.showFileReferenceGraph(explorerUri); - } - + async showReferenceGraph(): Promise { const editor = vscode.window.activeTextEditor; if (!editor) { vscode.window.showWarningMessage('No active editor. Place cursor on a symbol first.');