HCode: Forking VS Code Into a Security IDE (work in progress)

This is not a release post. HCode is not done. It’s barely holding together right now — and that’s kind of the point of writing about it today.

I’m building a security-focused IDE by forking VS Code (Code-OSS). The idea is simple: instead of context-switching between your editor, four terminal tabs, Burp Suite, a hex editor, and whatever else your workflow needs — it all lives in one place. One window. One keybinding muscle memory. No friction.

The reality of building that? Way harder than I thought. This is where I’m at.


The Vision

graph LR A["You open HCode"] --> B["Target declared"] B --> C["Recon tools fire"] C --> D["Findings auto-logged"] D --> E["Report generated"] B --> F["Binary analysis"] B --> G["Web req builder"] B --> H["CTF utilities"] F & G & H --> D

One IDE. One workspace. Every tool a security researcher needs, integrated — not bolted on after the fact.

The nine extensions I’m building toward:

Extension What it does Status
hcode-tools Security tool runner (nmap, sqlmap, ffuf, gobuster, hydra…) 🔧 In dev
hcode-recon Recon panel: subdomains, port scan, fingerprinting 🔧 In dev
hcode-network HTTP request builder, response diff, proxy config 🔧 In dev
hcode-binary Hex viewer, ELF/PE parser, entropy heatmap 🔧 In dev
hcode-ctf Flag highlighter, encoder/decoder, hash ID, ciphers 🔧 In dev
hcode-bugbounty Scope manager, finding tracker, report exporter 🔧 In dev
hcode-devices SSH device manager, remote command runner 🔧 In dev
hcode-mcp-server MCP server — exposes all HCode tools to AI agents 🔧 In dev
hcode-skills Attack methodology playbooks 🔧 In dev

Every single one of those is in development. None of them are done. But the structure is there — the extension slots are wired into the fork, the extension API scaffolding is live, I can open HCode and see the sidebar panels. It’s just that most of the panels are either empty or half-implemented.


The Problem I Didn’t See Coming: Cross-OS Tool Compatibility

This is the thing that’s been eating my time.

The whole promise of HCode is that you click a button and nmap runs. But here’s what actually happens when you try to make that work on every operating system:

flowchart TD A["User clicks Run Nmap"] --> B{OS?} B -->|macOS| C["nmap installed via Homebrew?\nPath: /opt/homebrew/bin/nmap"] B -->|Linux| D["nmap installed via apt/pacman?\nPath: /usr/bin/nmap"] B -->|Windows| E["nmap installed via installer?\nPath: C:/Program Files (x86)/Nmap/nmap.exe\nOR WSL?\nOR PATH variable?"] C --> F{Found?} D --> F E --> G{Found? Which one?} F -->|Yes| H["Run it — great"] F -->|No| I["Tell user to install it\nBut how? brew? apt? winget?"] G -->|WSL| J["Spawn in WSL context"] G -->|Native| K["Run natively — but output encoding differs"] G -->|Not found| I J --> L["Output via WSL stdout — needs stripping"] K --> M["Works — usually"] H --> N["Parse output → UI"] L --> N M --> N

That flow is just for one tool. I’m trying to support nmap, sqlmap, ffuf, gobuster, hydra, hashcat, subfinder, amass, httpx, and nikto. Each one has its own installation story on each OS. Some are Homebrew-only on macOS. Some don’t have native Windows binaries at all and need WSL. Some exist in multiple versions with different flag syntax.

Right now, the hcode-tools extension does a path probe at startup — it checks a list of known install locations per OS and reports back which tools it can find. The ones it can’t find get greyed out in the UI with a “not installed” badge.

That probe works. The part I’m still figuring out is: what do I do when a tool isn’t installed? Do I show platform-specific install instructions inline? Do I try to auto-install? Auto-installing anything silently is a bad idea for a security tool. So right now it’s a badge and a tooltip. Not elegant.


The Architecture (What’s Actually Built)

graph TD subgraph Fork["HCode — Code-OSS Fork"] P["product.json\nIdentity + branding"] T["theme-hcode\nHCode Dark theme"] subgraph Exts["extensions/hcode-*/"] E1["hcode-tools"] E2["hcode-recon"] E3["hcode-network"] E4["hcode-binary"] E5["hcode-ctf"] E6["hcode-bugbounty"] E7["hcode-devices"] E8["hcode-mcp-server"] E9["hcode-skills"] end end subgraph Core["Untouched Code-OSS src/vs/"] C1["base/"] C2["platform/"] C3["editor/"] C4["workbench/"] end Fork --> Core E8 --> AI["AI Agents\n(Copilot, Cline, Kilo Code)"]

The discipline I set from day one: zero modifications to src/vs/. Everything HCode-specific lives in either product.json, the extensions/hcode-*/ folders, or resources/. The moment I touch core VS Code source I own merge conflicts forever — and I want to keep pulling upstream VS Code commits cleanly as long as possible.

That’s held so far. The fork is on main of microsoft/vscode. The custom stuff is clean.


Why It’s Heavy

VS Code is ~500k lines of TypeScript. The build uses a custom gulpfile.mjs with incremental watch compilation. Running a full build from scratch takes a while even on a decent machine.

But the real weight isn’t the build — it’s the extension surface area. Each of the 9 extensions needs to:

  1. Detect whether its required external tools exist on the current OS
  2. Spawn child processes safely and stream stdout into VS Code panels
  3. Parse wildly different tool output formats into structured data
  4. Handle the case where a tool isn’t installed gracefully, per platform

Point 3 is where most of my time goes. nmap XML output is parseable. ffuf JSON output is clean. hydra stdout is… a mess. Hashcat has like 6 different status line formats depending on the attack mode. Writing robust parsers for all of these, across versions, is genuinely tedious work.


The MCP Server Angle

The one piece I’m pretty happy with is hcode-mcp-server. It runs a local HTTP server that exposes every HCode tool as an MCP (Model Context Protocol) tool. Any AI agent that speaks MCP — Copilot agent mode, Cline, Kilo Code — can call HCode tools directly.

sequenceDiagram participant A as AI Agent (Copilot / Cline) participant M as hcode-mcp-server (localhost) participant T as hcode-tools extension participant OS as OS / Tool binary A->>M: POST /tools/call — tool nmap, target 10.0.0.1 M->>T: VS Code command hcode.tools.run T->>OS: spawn nmap with -sV flag OS-->>T: stdout stream T-->>M: parsed result JSON M-->>A: port 22 ssh, port 80 http, ...

The server only binds to 127.0.0.1 and currently has no auth token — which is fine for solo local use but something I need to fix before I’d ever recommend anyone expose it further. It’s on the list.

What this unlocks is genuinely cool though: you can ask an AI agent to “run a recon scan on this target and summarise the open services” and it will literally invoke ncode-recon through the MCP server, get back structured results, and summarise them. No copy-pasting. No switching windows. The AI loops back into the IDE.


Where I’m Stuck Right Now

Honest list:

1. Windows support is untested. I only have macOS. I’ve written the path detection logic for Windows and WSL but I haven’t been able to run it end-to-end. The product.json has all the Windows registry keys and AppID config, the build scripts have Windows targets — but until someone with a Windows machine tests it I don’t actually know what breaks.

2. Tool output parsers are inconsistent. Some tools have clean structured output (ffuf -o results.json). Others just dump raw text and I’m reverse-engineering the format. The parsers work for the versions I have installed locally. Different versions, or tools installed from different sources, may produce slightly different output.

3. The hcode-skills playbook runner is a stub. The extension exists and loads, but executing a multi-step playbook where each step triggers a different tool and passes output to the next step is a sequencing problem I haven’t fully solved yet.

4. The build is heavy. Not a bug, just a reality. This is not a lightweight project.


What’s Actually Working

  • Fork builds and runs on macOS
  • product.json identity is correct — it opens as HCode, not VS Code
  • HCode Dark theme loads
  • All 9 extension packages load without errors
  • Tool path probe runs at startup and correctly identifies installed/missing tools
  • hcode-mcp-server starts up and responds to MCP calls
  • Basic tool invocation (nmap, ffuf, subfinder) works on macOS with Homebrew installs
  • hcode-binary hex viewer renders binary files correctly
  • hcode-ctf encoder/decoder panel is functional

What’s Next

I’m going to keep grinding through the tool parsers and the cross-OS path detection. The Windows story needs someone to actually test it — if you’re on Windows and want to help, the repo is at github.com/vasanthadithya/hcode.

The bigger open question is how to handle tool installation. Right now I show “not installed” and leave it at that. The right UX might be a setup wizard that runs on first launch, detects your OS, and gives you the exact install command for each missing tool. That’s probably the next big thing I build.

Building a full IDE is a lot. But the idea is right. Your editor should know what you do for a living.

Still building.

— Vasanth