Local Context Exporter
Copy selected VS Code workspace files and folders as clean, structured Markdown context for LLMs — fully local, private, and offline.
Right-click a folder like src/ in the Explorer, choose Copy as LLM Context, and paste a complete directory tree plus every file's contents (in language-labeled fenced code blocks) straight into ChatGPT, Claude, Gemini, or any other LLM.
Local Context Exporter processes files only on your machine. It has no login, no API key, no backend, and no code upload.
Key features
- Copy as LLM Context — filtered directory tree first, then every file in its own fenced code block
- Preview LLM Context — inspect the exact output in a read-only editor tab before copying anything
- Copy Project Tree Only — just the filtered project structure
- Language-aware code fences (JS/TS/TSX/JSX/Python/PHP/Blade/JSON/CSS/Markdown and more), safe against broken fences
- Configurable exclusions, extension allowlist, per-file size limits
.gitignore support without Git installed
- Large-context warning with Copy Anyway / Preview Instead / Cancel
- 100% local: no login, no account, no API key, no AI API, no backend, no telemetry, no network requests
Installation
From source (development):
npm install
npm run compile
Press F5 in VS Code to launch an Extension Development Host, or build a VSIX with npm run package and install it via Extensions → … → Install from VSIX.
Quick start
- Install the extension.
- Open a project in VS Code.
- Right-click a file or folder in Explorer.
- Choose Copy as LLM Context.
- Paste the generated Markdown into your preferred LLM.
Commands
| Command |
Purpose |
| Copy as LLM Context |
Copies tree plus selected source files as structured Markdown |
| Preview LLM Context |
Opens generated Markdown in an editor before copying |
| Copy Project Tree Only |
Copies only the filtered project structure |
All three work on files, folders, and multi-selections. Multi-select de-duplicates nested selections; multi-root workspaces use each folder's own rules.
Output example
# LLM Context: `src`
Generated locally by Local Context Exporter.
No files were uploaded or sent to an external service.
## Directory Structure
```text
src/
├── components/
│ └── Navbar.jsx
├── services/
│ └── api.js
└── main.jsx
File: src/main.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
## Configuration
All settings are optional and all processing remains fully local — changing them never triggers any network activity.
```jsonc
{
"codepack.excludePatterns": [
"storage/**",
"public/uploads/**",
"*.log",
".env",
".env.*"
],
"codepack.includeExtensions": [
".ts",
".tsx",
".css",
".json"
],
"codepack.maxFileSizeKB": 300,
"codepack.showTokenEstimate": true,
"codepack.includeHeaderNotice": true
}
codepack.excludePatterns
Additional glob patterns for files or folders to exclude, on top of the built-in defaults (.git, node_modules, dist, build, binaries).
storage — excludes any folder named storage, at any depth; its contents are not scanned at all.
logs/** — excludes everything inside logs folders.
*.log — excludes .log files anywhere.
**/*.map — excludes .map files anywhere.
src/generated/** — excludes the generated subtree under a specific path.
.env, .env.* — excludes env files.
Patterns are matched case-insensitively; \ is normalized to /. Exclusions always win over includeExtensions.
codepack.includeExtensions
When empty (default), all supported text/code files are included. When set, only files with these extensions are included. Write extensions with or without the leading dot (ts or .ts); compound extensions like .blade.php and .d.ts work.
codepack.respectGitIgnore
When true (default), files and folders matched by .gitignore rules are excluded from the export. See .gitignore Support.
codepack.maxFileSizeKB
Maximum size of one file included in the export (default 500). Files exactly at the limit are included; larger files are skipped and reported in the notification.
codepack.showTokenEstimate
When false, notifications and warnings omit the ~N tokens estimate.
When true (default), generated output starts with:
Generated locally by Local Context Exporter.
No files were uploaded or sent to an external service.
Set to false to omit both lines cleanly.
codepack.sortOrder
Only value today: foldersFirstAlphabetical (directories before files, both alphabetical).
.gitignore Support
- Enabled by default via
codepack.respectGitIgnore.
- The extension reads
.gitignore files directly from the workspace file system. It does not invoke Git and Git does not need to be installed.
- Ignored files are removed from the directory tree, the copied context, file counts, and size/token estimates.
- Nested
.gitignore files are supported; their rules apply relative to the folder containing them.
- Negation rules (
!) work for common cases, including re-including a file inside a directory that is only partially matched (e.g. generated/** + !generated/keep.ts).
.gitignore files themselves are not exported while this setting is enabled — they are plumbing, not code context.
Filtering precedence, first match wins:
Custom excludePatterns
→ Default exclusions
→ .gitignore rules
→ includeExtensions
→ maxFileSizeKB
Large context safety
Before copying full LLM context, the extension measures the final output in UTF-8 bytes (tree, headings, and fences included) and compares it with your limit:
{
"codepack.maxTotalSizeKB": 5000,
"codepack.warnBeforeLargeCopy": true
}
If the output exceeds the limit (exactly-at-limit is allowed) you get a modal warning showing file count, approximate size, estimated tokens, and your configured limit, with three choices:
- Copy Anyway — copies the already-generated output as-is.
- Preview Instead — opens the same output read-only, without copying.
- Cancel — does nothing.
Set warnBeforeLargeCopy to false to copy large outputs without asking. The token count remains a local estimate (characters ÷ 4); no tokenizer service is contacted. The warning applies to full-context copy only, never to tree-only.
Privacy and security
Local Context Exporter processes selected workspace files only on your machine.
- No login
- No account
- No API key
- No AI API
- No backend
- No code upload
- No telemetry
- No network requests
Generated content lives only in your clipboard or an in-memory preview document; it is never written to disk by the extension. Diagnostics logged to the Local Context Exporter output channel contain counts and paths metadata only — never file contents.
Limitations
- Markdown output only (XML/plain text may come later).
- A file inside a fully ignored directory cannot be re-included by nested
.gitignore negation — this matches Git's own semantics.
- Symlinks are skipped rather than followed (cycle/outside-workspace safety).
- Token estimates are approximations (
chars / 4), not real tokenizer counts.
Development
npm run compile # type-check + emit to out/
npm run watch # incremental build
Project layout:
src/core/ scanner, tree builder, formatters, config, gitignore, context generator, types
src/utils/ safe fence logic, path helpers
src/commands/ thin UI layers for copy, preview, tree-only
test/ mocha unit tests over pure modules and stubbed vscode APIs
Testing
npm test
Unit tests cover scanning, exclusions, include filters, size limits, .gitignore evaluation, tree building, formatting, fence safety, notifications, preview parity, tree-only output, and the large-copy flow — all without launching VS Code.
Packaging
npx @vscode/vsce package --allow-missing-repository
Produces local-context-exporter-<version>.vsix (set your own publisher id before publishing). The only runtime dependency, ignore, is bundled into the VSIX.