PUPThe prompt engineering tool for LLMs — build clean, structured prompts for Cursor, Copilot, Claude & ChatGPT without leaving your editor.
✨ Why?LLMs respond better to structured prompts — role, context, task, examples, output format, constraints. PUP gives you a form-based builder that compiles your inputs into a clean copy-pasteable prompt. No AI is run inside the extension — it's a pure compiler. Your prompt, your model, your editor. 🚀 Features
📦 InstallFrom a
|
| Command | Description |
|---|---|
PUP: Open Builder |
Opens the prompt builder in a new editor tab |
PUP: Open Selected .md as Prompt |
Opens an existing saved prompt (parses frontmatter) |
Right-click any .md inside .prompts/ to use the second command.
⚙️ Settings
| Setting | Default | Description |
|---|---|---|
pup.savedPromptsDir |
.prompts |
Workspace-relative folder for saved prompts |
pup.defaultOutputFormat |
markdown |
Format used on first open |
pup.fileSearch.maxResults |
20 |
Max items in @-mention dropdown (1–200) |
pup.fileSearch.excludeGlobs |
["**/node_modules/**", …] |
Globs excluded from file search |
🧭 Quick Start
- Open the builder —
Cmd/Ctrl+Shift+P→PUP: Open Builder - Pick a preset — e.g. Bug Fix. Sections are pre-populated with help text.
- Fill the sections —
@to reference any file in your workspace. - Toggle format / model — preview updates live with token usage.
- Copy or save — bottom action bar. Saved files round-trip on re-open.
🏗️ Architecture
Two-realm design. The host (Node, VS Code API) and the webview (React, browser sandbox) communicate only via typed postMessage.
src/
extension.ts # activate() — registers commands + invalidators
host/
panel.ts # webview lifecycle + message bus + CSP
fileSearch.ts # findFiles + fuzzy + 5s URI cache
validate.ts # message + path guards (vscode-free, testable)
uriValidate.ts # URI-aware path helpers (vscode-aware)
shared/ # PURE TS — used by both realms
types.ts # message + doc shapes (single source of truth)
validate.ts # PromptDoc deep guards
presets.ts # built-in role presets
compile.ts # PromptDoc → string in 4 formats
frontmatter.ts # round-trip serialise / parse
tokens.ts # model-agnostic token estimator
fuzzy.ts # tiny fuzzy scorer
webview/
index.tsx, App.tsx # React 18 entry
components/ # PresetPicker · SectionList · AtMentionTextarea · TokenCounter · ErrorBoundary · …
index.css # VS Code CSS-var themed styles
🔒 Security
- 🛡️ Strict CSP —
default-src 'none', scripts only via per-rendercrypto.randomBytes(16)nonce. - 🚪 Sandboxed save path —
pup.savedPromptsDirvalidated for..and absolute traversal, plus arealpathsymlink check on local file systems. - 🧾 Deep message validation — every
postMessagefrom the webview runs throughisValidPromptDocbefore any host-side action. - 📏 Bounded reads —
openFromFilerejects files larger than 1 MiB. - 🌐 Cross-environment IO — saves and reads use
vscode.workspace.fs.*; nevernode:fs.*. Works on Remote-SSH and virtual workspaces without escaping the sandbox. - 🚫 Webview can't touch the filesystem — every file enumeration goes through the host.
🧪 Develop
pnpm install
pnpm run watch # esbuild watch (host + webview)
pnpm run compile # tsc --noEmit (type check only)
pnpm test # node:test against shared + host validators
pnpm run package # builds and writes pup.vsix
🤝 Contributing
Issues and PRs welcome. Before opening a PR:
pnpm run compile && pnpm test && pnpm run build
📜 License
MIT © Ali Malik
