Skip to content

Commit 22ce835

Browse files
committed
init
0 parents  commit 22ce835

27 files changed

+4348
-0
lines changed

.eslintrc.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"root": true,
3+
"parser": "@typescript-eslint/parser",
4+
"parserOptions": {
5+
"ecmaVersion": 6,
6+
"sourceType": "module"
7+
},
8+
"plugins": [
9+
"@typescript-eslint"
10+
],
11+
"rules": {
12+
"@typescript-eslint/naming-convention": [
13+
"warn",
14+
{
15+
"selector": "import",
16+
"format": [ "camelCase", "PascalCase" ]
17+
}
18+
],
19+
"@typescript-eslint/semi": "warn",
20+
"curly": "warn",
21+
"eqeqeq": "warn",
22+
"no-throw-literal": "warn",
23+
"semi": "off"
24+
},
25+
"ignorePatterns": [
26+
"dist",
27+
"**/*.d.ts"
28+
]
29+
}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
out
2+
dist
3+
node_modules
4+
.vscode-test/
5+
*.vsix

.vscode/extensions.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
// See http://go.microsoft.com/fwlink/?LinkId=827846
3+
// for the documentation about the extensions.json format
4+
"recommendations": [
5+
"dbaeumer.vscode-eslint"
6+
]
7+
}

.vscode/launch.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// A launch configuration that compiles the extension and then opens it inside a new window
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
{
6+
"version": "0.2.0",
7+
"configurations": [
8+
{
9+
"name": "Run Extension",
10+
"type": "extensionHost",
11+
"request": "launch",
12+
"args": [
13+
"--extensionDevelopmentPath=${workspaceFolder}"
14+
],
15+
"outFiles": [
16+
"${workspaceFolder}/out/**/*.js"
17+
],
18+
"preLaunchTask": "${defaultBuildTask}"
19+
},
20+
{
21+
"name": "Extension Tests",
22+
"type": "extensionHost",
23+
"request": "launch",
24+
"args": [
25+
"--extensionDevelopmentPath=${workspaceFolder}",
26+
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
27+
],
28+
"outFiles": [
29+
"${workspaceFolder}/out/test/**/*.js"
30+
],
31+
"preLaunchTask": "${defaultBuildTask}"
32+
}
33+
]
34+
}

.vscode/settings.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Place your settings in this file to overwrite default and user settings.
2+
{
3+
"files.exclude": {
4+
"dist": false
5+
},
6+
"search.exclude": {
7+
"dist": true
8+
},
9+
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
10+
"typescript.tsc.autoDetect": "off",
11+
"workbench.colorCustomizations": {
12+
"activityBar.activeBackground": "#2a2a2a",
13+
"activityBar.background": "#2a2a2a",
14+
"activityBar.foreground": "#e7e7e7",
15+
"activityBar.inactiveForeground": "#e7e7e799",
16+
"activityBarBadge.background": "#606020",
17+
"activityBarBadge.foreground": "#e7e7e7",
18+
"commandCenter.border": "#e7e7e799",
19+
"sash.hoverBorder": "#2a2a2a",
20+
"statusBar.background": "#111111",
21+
"statusBar.foreground": "#e7e7e7",
22+
"statusBarItem.hoverBackground": "#2a2a2a",
23+
"statusBarItem.remoteBackground": "#111111",
24+
"statusBarItem.remoteForeground": "#e7e7e7",
25+
"titleBar.activeBackground": "#111111",
26+
"titleBar.activeForeground": "#e7e7e7",
27+
"titleBar.inactiveBackground": "#11111199",
28+
"titleBar.inactiveForeground": "#e7e7e799"
29+
},
30+
"peacock.color": "#111"
31+
}

.vscode/tasks.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// See https://go.microsoft.com/fwlink/?LinkId=733558
2+
// for the documentation about the tasks.json format
3+
{
4+
"version": "2.0.0",
5+
"tasks": [
6+
{
7+
"type": "npm",
8+
"script": "watch",
9+
"problemMatcher": "$tsc-watch",
10+
"isBackground": true,
11+
"presentation": {
12+
"reveal": "never"
13+
},
14+
"group": {
15+
"kind": "build",
16+
"isDefault": true
17+
}
18+
}
19+
]
20+
}

.vscodeignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.vscode/**
2+
.vscode-test/**
3+
src/**
4+
.gitignore
5+
.yarnrc
6+
vsc-extension-quickstart.md
7+
**/tsconfig.json
8+
**/.eslintrc.json
9+
**/*.map
10+
**/*.ts
11+
assets/**

AGENTS.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Repository Guidelines
2+
3+
## Project Structure & Module Organization
4+
- Sources: `src/`
5+
- Core (AST extractors): `src/core/{definitions.ts,calls.ts}`
6+
- Analyzer (editor-agnostic orchestration): `src/analyzer/compute.ts` (+ `src/analyzer/types.ts`)
7+
- Extension (VS Code adapter): `src/extension/{controller.ts,decorator.ts,updater.ts,resolver.ts,extension.ts}`
8+
- Tests: Vitest, colocated as `src/**/__tests__/*.test.ts` (top-most layer tests at `src/analyzer/__tests__/compute.test.ts`)
9+
- Build output: `dist/` by `tsc` (do not edit generated artifacts)
10+
- Entry point: `package.json``main: ./dist/extension.js`; commands are defined in `contributes.commands`
11+
12+
## Build, Test, and Development Commands
13+
- `npm run compile` — Type-checks and compiles TS to `dist/`
14+
- `npm run lint` — ESLint on `src/**/*.ts`
15+
- `npm test` — Vitest (unit/integration)
16+
- `npm run test:unit:watch` — Vitest watch
17+
- `npm run vscode:prepublish` — Production compile (for packaging)
18+
- Tip: Run in VS Code with `F5` (Extension Development Host)
19+
20+
## Coding Style & Naming Conventions
21+
- Language: TypeScript (strict). Module: NodeNext, Target: ESNext (per tsconfig)
22+
- Indentation: 2 spaces; prefer early returns and braces (`curly` rule enabled).
23+
- Imports: follow ESLint `@typescript-eslint/naming-convention` for import aliases (camelCase or PascalCase).
24+
- Semicolons: required (enforced by `@typescript-eslint/semi`).
25+
- Namespacing: prefix command IDs with `nextjs-server-functions-visualizer.*`.
26+
- Do not commit generated files (`dist/`) or `.vscode-test/` artifacts.
27+
28+
## Testing Guidelines
29+
- Framework: Vitest (globals enabled)
30+
- Location: `src/**/__tests__/*.test.ts`
31+
- Focus: Ensure visualization behavior via parameterized tests at the upper layer (analyzer/compute)
32+
- Run: `npm test` / `npm run test:unit:watch`
33+
34+
## Commit & Pull Request Guidelines
35+
- Commits: Prefer Conventional Commits (e.g., `feat:`, `fix:`, `chore:`) and scope when helpful (e.g., `feat(commands): add action scan`).
36+
- PRs: Include a clear description, linked issue(s), reproduction or screenshots (when UI-visible), and test coverage for new behavior.
37+
- Quality gate: CI checklist — run `npm run lint` and `npm test` locally; update `README.md` and `CHANGELOG.md` when user-facing changes occur.
38+
39+
## Security & Configuration Tips
40+
- Minimum VS Code engine: see `package.json` (currently `^1.100.0`)
41+
- Prefer static analysis; avoid executing workspace code
42+
- Limit code to `src/**`. Add new commands in `package.json` and initialize them from `src/extension.ts`
43+
44+
## Architecture for Agents
45+
- Layer boundaries
46+
- Core (syntax extraction): editor/LSP-independent AST extractors. No side effects.
47+
- Analyzer (composition/decision): applies policy and resolution to Core results and outputs offset ranges (pure function). Depends only on `ResolveFn` (DI).
48+
- Extension (application/wiring): converts to VS Code Ranges, applies decorations, wires events. Uses `makeVsCodeResolveFn()` as the resolver.
49+
- Dependency direction: Core ← Analyzer ← Extension (no backflow)
50+
- Documentation: see `docs/ARCHITECTURE.md` (includes a Mermaid diagram)

LICENSE.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Copyright (c) 2025 makotot
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Next.js Server Functions Visualizer
2+
3+
> A VS Code extension that visualizes the “definitions” and “call sites” of Server Functions (`'use server'`) to help you understand them quickly in the editor.
4+
5+
<img src="./assets/screenshot.png" alt="Screenshot" width="800" />
6+
7+
## Motivation
8+
Server Functions are transformed into framework‑managed endpoints (POST), which makes the network boundary implicit and hard to see in code. By visualizing these definitions and call sites directly in the editor, this extension aims to improve readability and reduce review friction.
9+
10+
## Features
11+
- Highlight definitions (blue‑purple line background)
12+
- Highlights the entire line range of the server function body
13+
- Shows 🌐 inline at the end of the line that starts the block “{”
14+
- Highlight call sites (expression range)
15+
- Blue‑purple background + solid underline on the same range + 🚪 inline at the end
16+
- Patterns: direct calls (`id(...)`/`obj.id(...)`), `<form action={...}>`/`formAction`, `startTransition(() => id(...))`, `useActionState(id, ...)`
17+
- Auto filtering to reduce false positives
18+
- Only identifiers that are callables from imports or declared in the same file are considered
19+
- Uses the TypeScript Language Service to resolve definitions and decorates only when they match a Server Function
20+
21+
## Usage
22+
1. Install this extension and open a Next.js (React Server Components) project
23+
2. Open any `.ts/.tsx` file and visualization activates automatically (JS/JSX are not supported)
24+
3. Server Function definitions are highlighted with a blue‑purple line background; call sites are highlighted by expression range
25+
26+
Tips
27+
- Definitions target functions that satisfy both `'use server'` and `async`
28+
- Also supports builder patterns (e.g., `createServerAction(async () => {...})`) and JSX inline `action={async () => {'use server'}}`
29+
30+
## Settings
31+
You can tweak the background intensity and theme colors.
32+
33+
```jsonc
34+
// Example (settings.json)
35+
{
36+
"nextjs-server-functions-visualizer.highlight.definition.tintLight": "rgba(138, 99, 255, 0.14)",
37+
"nextjs-server-functions-visualizer.highlight.definition.tintDark": "rgba(138, 99, 255, 0.18)",
38+
"nextjs-server-functions-visualizer.highlight.definition.tintHighContrast": "rgba(138, 99, 255, 0.22)",
39+
"nextjs-server-functions-visualizer.highlight.call.tintLight": "rgba(118, 129, 255, 0.14)",
40+
"nextjs-server-functions-visualizer.highlight.call.tintDark": "rgba(118, 129, 255, 0.18)",
41+
"nextjs-server-functions-visualizer.highlight.call.tintHighContrast": "rgba(118, 129, 255, 0.22)",
42+
"nextjs-server-functions-visualizer.highlight.call.underlineColorLight": "rgba(118, 129, 255, 0.85)",
43+
"nextjs-server-functions-visualizer.highlight.call.underlineColorDark": "rgba(118, 129, 255, 0.85)",
44+
"nextjs-server-functions-visualizer.highlight.call.underlineColorHighContrast": "rgba(118, 129, 255, 0.9)"
45+
}
46+
```
47+
48+
## Supported Detections
49+
- Definitions (`'use server'` + async)
50+
- `export async function foo() {}` / `export default async function ...`
51+
- `export const x = async () => {}` / `async function() {}`
52+
- Async function literals inside initializers of builder patterns
53+
- JSX inline: `action={async () => {'use server'}}`
54+
- Call sites
55+
- Direct: `id(...)`, `obj.id(...)`
56+
- JSX: `<form action={...}>`, `formAction={...}`
57+
- `startTransition(() => id(...))`
58+
- `useActionState(id, ...)`
59+
60+
## Known Limitations
61+
- Namespace imports: single-level calls like `ns.action()` are supported; multi-level chains like `ns.group.action()` are not.
62+
- Element access (`obj['action']()`) is not supported.
63+
- Does not track indirect calls (via props/HOF) or `bind/apply`
64+
- Async functions that don’t satisfy `'use server'` are not treated as definitions
65+
66+
## Troubleshooting
67+
- Expected locations aren’t highlighted
68+
- Ensure the function meets `'use server'` + `async`
69+
- Ensure it’s declared as an imported or same‑file function
70+
- Use “Go to Definition” (F12) to check if it resolves to the intended Server Function
71+
- If decorations conflict with other extensions, adjust background/underline intensity in settings
72+
73+
## How It Works (High level)
74+
- Extracts definition and call candidates via AST (TypeScript Compiler API)
75+
- Pre‑filters imports/local declarations to exclude global APIs (e.g., `alert`/`console`)
76+
- Uses VS Code’s TypeScript Language Service to resolve definitions and decorate only when they match a Server Function (identifier/body range)
77+
78+
## License / Contributions
79+
- Issues/PRs welcome. Proposals for UI/colors and unsupported patterns (e.g., namespace import/element access) are appreciated.
80+
81+
## Related
82+
- Next.js Component Boundary Visualizer: https://github.com/makotot/vscode-nextjs-component-boundary-visualizer — A VS Code extension that visualizes component execution environments (client/server) via the 'use client' directive.

0 commit comments

Comments
 (0)