Code ContextCopy code with its actual dependencies. Install Now · Report a Bug · Request a Feature The ProblemWhen you paste code into an AI chat, the AI only sees what you copied. Your function imports from three files. The AI sees none of them. It guesses. You get a hallucinated answer. The obvious fix — copying the whole folder — just trades one problem for another. Test files, unrelated utilities, 2,000 lines of noise for a 40-line question. Code Context reads your actual import graph and copies exactly what's needed. Nothing more. Three Levels of PrecisionRight-click any file. One menu. Three modes.
|
| Folder copy tools | Code Context | |
|---|---|---|
| Copies file content | ✅ | ✅ |
| Skips unrelated files | ❌ | ✅ |
| Follows the actual import graph | ❌ | ✅ |
| Dependency-first ordering | ❌ | ✅ |
| Function-level granularity | ❌ | ✅ |
Respects tsconfig path aliases |
❌ | ✅ |
| Excludes test files by default | ❌ | ✅ |
Installation
From the Marketplace:
- Open VS Code
- Press
Ctrl+P/Cmd+P - Paste:
ext install code-context.code-context - Hit Enter
Or open the Extensions panel (Ctrl+Shift+X) and search Code Context.
Usage
All commands appear in both the Explorer context menu and the Editor context menu. Right-click any .ts, .tsx, .js, or .jsx file.
| Command | Where | What happens |
|---|---|---|
| Code Context: Copy File | Explorer · Editor | Copies the file with a path header |
| Code Context: Copy with Dependencies | Explorer · Editor | Prompts for depth, walks the import graph |
| Code Context: Copy Function + Dependencies | Editor (cursor inside function) | Copies just that function + its used imports |
Depth Prompt (Level 2)
A quick-input appears pre-filled with your configured default:
How many levels of imports should be followed? (1 = direct imports only)
> 2
| Depth | What you get |
|---|---|
1 |
Root file + its direct imports |
2 |
Root + imports + imports-of-imports |
N |
Full transitive graph up to N hops |
Circular imports are handled safely — each file is visited at most once.
Status Bar Feedback
Every copy shows a brief summary in the status bar, then fades after 5 seconds:
$(copy) Copied 3 files (247 lines)
Configuration
All settings live under the codeContext namespace. Search Code Context in Settings (Ctrl+,) or edit settings.json directly.
| Setting | Type | Default | Description |
|---|---|---|---|
codeContext.defaultDepth |
number (1–10) |
2 |
Depth pre-filled in the Level 2 prompt |
codeContext.outputFormat |
"comment-path" · "markdown-codeblock" |
"comment-path" |
How each file is wrapped in the output |
codeContext.excludePatterns |
string[] |
test & spec files | Glob patterns for files to skip |
codeContext.followTsConfigPaths |
boolean |
true |
Resolve tsconfig.json path aliases |
Example settings.json:
{
"codeContext.defaultDepth": 3,
"codeContext.outputFormat": "markdown-codeblock",
"codeContext.excludePatterns": [
"**/*.test.ts",
"**/*.spec.ts",
"**/mocks/**"
],
"codeContext.followTsConfigPaths": true
}
Output Formats
comment-path (default) — clean, works in any AI chat:
// src/utils/auth.ts
export async function verifyToken(token: string): Promise<Payload> {
// ...
}
markdown-codeblock — renders beautifully in Markdown-aware tools:
```typescript
// src/utils/auth.ts
export async function verifyToken(token: string): Promise<Payload> {
// ...
}
```
Supported Languages
| Extension | Language |
|---|---|
.ts · .tsx |
TypeScript · TypeScript + JSX |
.js · .jsx |
JavaScript · JavaScript + JSX |
.mts · .cts |
TypeScript ESM · CommonJS |
.mjs · .cjs |
JavaScript ESM · CommonJS |
tsconfigpath aliases (@/,~, custom prefixes) are fully resolved whencodeContext.followTsConfigPathsis enabled and atsconfig.jsonexists in the workspace root.
How It Works
Import Graph Walking (Level 2)
- Parses the file's AST using
@typescript-eslint/typescript-estree— handles TS and JS without invoking the full TypeScript compiler. - Extracts all
ImportDeclarationnodes and resolves specifiers to absolute paths on disk. - Skips
node_modulesand anything matching yourexcludePatterns. - Performs a BFS walk up to
maxDepth, tracking visited files in aSetto handle circular imports safely. - Reverses the collection so dependencies appear before the files that consume them.
Surgical Function Copy (Level 3)
- Parses the full file AST.
- Finds the innermost function node (declaration, expression, or arrow function) containing the cursor position.
- Traverses that function's AST subtree, collecting every
Identifierit references. - Cross-references those identifiers against the file's import declarations — only imports whose exported names appear inside the function are kept.
- Resolves those import paths to disk and reads each dependency file.
Path Resolution
resolveImport probes each candidate in order:
- Exact match (specifier already has an extension)
- With each extension:
.ts→.tsx→.js→.jsx→.mts→.cts→.mjs→.cjs - As a directory index file (
index.ts,index.js, etc.) - Via
tsconfig.jsonpath aliases (whenfollowTsConfigPathsis enabled)
Project Structure
code-context/
├── src/
│ ├── extension.ts # Entry point — registers commands & status bar
│ ├── commands/
│ │ ├── copyFile.ts # Level 1 — single file copy
│ │ ├── copyWithDeps.ts # Level 2 — dependency graph copy
│ │ └── copyFunction.ts # Level 3 — function + surgical imports
│ ├── core/
│ │ ├── astParser.ts # AST parsing: imports, function nodes, identifiers
│ │ ├── dependencyResolver.ts # BFS graph walker + import resolver
│ │ ├── pathResolver.ts # Import specifier → absolute path on disk
│ │ └── formatter.ts # Output formatting
│ └── test/
│ ├── fixtures/
│ │ ├── simple/ # main.ts → utils.ts, date-helper.ts
│ │ ├── nested/ # a.ts → b.ts → c.ts
│ │ ├── circular/ # x.ts ↔ y.ts (circular guard)
│ │ └── function-level/ # multi-function with selective imports
│ └── unit/
│ ├── pathResolver.test.ts
│ ├── dependencyResolver.test.ts
│ ├── astParser.test.ts
│ └── formatter.test.ts
├── esbuild.js
├── tsconfig.json
└── package.json
Development
Prerequisites
- Node.js 18+
- pnpm —
npm install -g pnpm - VS Code 1.114.0+
Setup
git clone https://github.com/adan-ayaz-stan/code-context
cd code-context
pnpm install
Run in Development
Press F5 in VS Code to launch an Extension Development Host with the extension loaded.
Or start the watch build manually:
pnpm run watch
Run Tests
pnpm test
The test suite runs inside a real VS Code instance via @vscode/test-electron. All 33 tests must pass before a PR is merged.
pathResolver
✔ resolves a relative .ts import without extension
✔ resolves a relative .ts import with a sibling
✔ resolves a deeper relative path
✔ returns null for node_modules imports
✔ returns null for non-existent files
✔ findWorkspaceRoot walks up to find package.json
✔ loadTsConfigPaths returns empty paths gracefully
formatter — formatFiles
✔ comment-path format: single file
✔ comment-path format: multiple files separated by blank line
✔ markdown-codeblock format: wraps in triple backticks
...
dependencyResolver
✔ depth 0 — returns only the root file
✔ depth 1 — returns root + direct imports (simple)
✔ depth 2 — walks nested chain a → b → c
✔ depth 1 — stops at depth limit
✔ handles circular imports without infinite loop
✔ returns files in dependency-first order
33 passing
Build for Production
pnpm run package
Produces dist/extension.js via esbuild — minified, tree-shaken, fast.
Lint
pnpm run lint
Contributing
Pull requests are welcome. For significant changes, open an issue first to discuss direction.
- Fork the repo
- Create your branch:
git checkout -b feat/my-feature - Make your changes with test coverage
- Run
pnpm test— all 33 tests must pass - Open a PR with a clear description of the change
License
MIT — free to use, modify, and distribute.