diff --git a/.devcontainer/CHANGELOG.md b/.devcontainer/CHANGELOG.md index f70cf68..eb2311f 100644 --- a/.devcontainer/CHANGELOG.md +++ b/.devcontainer/CHANGELOG.md @@ -2,6 +2,16 @@ ## [Unreleased] +### Changed + +#### Port Forwarding +- Dynamic port forwarding for all ports in VS Code — previously only port 7847 was statically forwarded; now all ports auto-forward with notification + +#### Documentation +- Updated prerequisites and installation docs to support all DevContainer clients (VS Code, CLI, JetBrains Gateway, DevPod, Codespaces) +- Added tabbed client-specific instructions on the installation page +- Added dedicated port forwarding reference page covering VS Code auto-detect, devcontainer-bridge, and SSH tunneling + ### Fixed #### Session Context Plugin @@ -12,6 +22,9 @@ #### Auto Code Quality Plugin - **Advisory test runner** now reads from the correct tmp file prefix (`claude-cq-edited` instead of `claude-edited-files`), fixing a mismatch that prevented it from ever finding edited files +#### Docs +- Removed stale merge conflict marker in first-session docs page + ### Added #### Startup diff --git a/.devcontainer/CLAUDE.md b/.devcontainer/CLAUDE.md index 12600ad..a295e71 100644 --- a/.devcontainer/CLAUDE.md +++ b/.devcontainer/CLAUDE.md @@ -184,11 +184,14 @@ Custom features in `./features/` follow the [devcontainer feature spec](https:// ## Port Forwarding -Two mechanisms handle port access: +Three mechanisms handle port access depending on your client: -| Mechanism | When Active | Dynamic Discovery | -|-----------|-------------|-------------------| -| `forwardPorts` (devcontainer.json) | VS Code / Codespaces only | No (static list; VS Code auto-detects separately) | -| devcontainer-bridge (`dbr`) | Any terminal client | Yes (polls `/proc/net/tcp`) | +| Mechanism | Client | Discovery | +|-----------|--------|-----------| +| VS Code auto-detect | VS Code only | Dynamic — all ports auto-forwarded with notification | +| devcontainer-bridge (`dbr`) | Any terminal client | Dynamic — polls `/proc/net/tcp` | +| SSH tunneling | Any SSH client | Manual — `ssh -L localPort:localhost:remotePort` | -`forwardPorts` is a no-op outside VS Code — the `devcontainer` CLI ignores it. `dbr` provides VS Code-independent dynamic port discovery via a reverse connection model (container→host). The container daemon auto-starts and is inert without the host daemon (`dbr host-daemon`). Both mechanisms coexist. See [devcontainer-bridge](https://github.com/bradleybeddoes/devcontainer-bridge). +VS Code auto-detects all ports opened inside the container (configured via `portsAttributes` in `devcontainer.json`). Outside VS Code, `dbr` provides dynamic port discovery via a reverse connection model (container→host). The container daemon auto-starts and is inert without the host daemon (`dbr host-daemon`). Both mechanisms coexist. See [devcontainer-bridge](https://github.com/bradleybeddoes/devcontainer-bridge). + +For full setup instructions, see the [Port Forwarding reference](https://anexileddev.github.io/CodeForge/reference/port-forwarding/) in the docs. diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 45dfdc1..e5e5623 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -1,6 +1,6 @@ # CodeForge Usage Guide -Everything you need to know once you're inside the devcontainer. +Everything you need to know once you're inside the devcontainer. These instructions apply regardless of which client you used to start the container — VS Code, the `devcontainer` CLI, JetBrains Gateway, DevPod, or GitHub Codespaces. ## Quick Start diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index b4705b0..20f40b2 100755 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -155,14 +155,14 @@ "ghcr.io/bradleybeddoes/devcontainer-bridge/dbr:0.2.0": {} }, - "forwardPorts": [7847], + "forwardPorts": [], "portsAttributes": { "7847": { "label": "Claude Dashboard", "onAutoForward": "notify" }, "*": { - "onAutoForward": "silent" + "onAutoForward": "notify" } }, diff --git a/README.md b/README.md index 19638e0..c2ae4b3 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,12 @@ npx codeforge-dev@1.2.3 ## Prerequisites - **Docker Desktop** (or compatible container runtime like Podman) -- **VS Code** with the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers), or **GitHub Codespaces** +- **A DevContainer client** — any of: + - **VS Code** with the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + - **DevContainer CLI** — `npm install -g @devcontainers/cli` ([docs](https://containers.dev/supporting#devcontainer-cli)) + - **GitHub Codespaces** — zero local setup + - **JetBrains Gateway** with [Dev Containers plugin](https://plugins.jetbrains.com/plugin/21962-dev-containers) + - **DevPod** — open-source, editor-agnostic ([devpod.sh](https://devpod.sh/)) - **Claude Code authentication** — run `claude` on first start to authenticate ## What's Included @@ -127,11 +132,14 @@ For the complete configuration guide, see the [documentation site](https://anexi ## Quick Start 1. **Install**: `npx codeforge-dev` -2. **Open in Container**: "Reopen in Container" in VS Code, or create a Codespace +2. **Open in Container**: + - **VS Code**: "Reopen in Container" from the Command Palette + - **CLI**: `devcontainer up --workspace-folder .` then `docker exec -it zsh` + - **Codespaces**: Create a Codespace from the repo 3. **Authenticate**: Run `claude` and follow prompts 4. **Start coding**: Run `cc` -For full usage documentation — authentication, configuration, tools, agents, and keybindings — see [`.devcontainer/README.md`](.devcontainer/README.md). +CodeForge uses the open [Dev Containers specification](https://containers.dev/) — any compatible client works. For full usage documentation — authentication, configuration, tools, agents, and keybindings — see [`.devcontainer/README.md`](.devcontainer/README.md). ## Contributing diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 1cad106..79aa12d 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -1,67 +1,71 @@ -import { defineConfig } from 'astro/config'; -import starlight from '@astrojs/starlight'; -import tailwindcss from '@tailwindcss/vite'; -import sitemap from '@astrojs/sitemap'; -import astroMermaid from 'astro-mermaid'; -import starlightSidebarTopics from 'starlight-sidebar-topics'; -import starlightImageZoom from 'starlight-image-zoom'; -import starlightLinksValidator from 'starlight-links-validator'; -import starlightKbd from 'starlight-kbd'; -import starlightScrollToTop from 'starlight-scroll-to-top'; -import starlightLlmsTxt from 'starlight-llms-txt'; +import sitemap from "@astrojs/sitemap"; +import starlight from "@astrojs/starlight"; +import tailwindcss from "@tailwindcss/vite"; +import { defineConfig } from "astro/config"; +import astroMermaid from "astro-mermaid"; +import starlightImageZoom from "starlight-image-zoom"; +import starlightKbd from "starlight-kbd"; +import starlightLinksValidator from "starlight-links-validator"; +import starlightLlmsTxt from "starlight-llms-txt"; +import starlightScrollToTop from "starlight-scroll-to-top"; +import starlightSidebarTopics from "starlight-sidebar-topics"; export default defineConfig({ - site: 'https://anexileddev.github.io', - base: '/CodeForge', + site: "https://anexileddev.github.io", + base: "/CodeForge", integrations: [ // astro-mermaid MUST be registered BEFORE starlight astroMermaid(), starlight({ - title: 'CodeForge', - tagline: 'Your AI dev environment, battle-tested.', + title: "CodeForge", + tagline: "Your AI dev environment, battle-tested.", logo: { - src: './src/assets/logo.png', + src: "./src/assets/logo.png", replacesTitle: false, }, social: [ - { icon: 'github', label: 'GitHub', href: 'https://github.com/AnExiledDev/CodeForge' }, - { icon: 'x.com', label: 'X', href: 'https://x.com/AnExiledDev' }, + { + icon: "github", + label: "GitHub", + href: "https://github.com/AnExiledDev/CodeForge", + }, + { icon: "x.com", label: "X", href: "https://x.com/AnExiledDev" }, ], - customCss: ['./src/styles/global.css'], + customCss: ["./src/styles/global.css"], components: { - Hero: './src/components/Hero.astro', - Header: './src/components/Header.astro', + Hero: "./src/components/Hero.astro", + Header: "./src/components/Header.astro", }, editLink: { - baseUrl: 'https://github.com/AnExiledDev/CodeForge/edit/main/docs/', + baseUrl: "https://github.com/AnExiledDev/CodeForge/edit/main/docs/", }, head: [ { - tag: 'meta', + tag: "meta", attrs: { - name: 'og:image', - content: '/CodeForge/og-image.png', + name: "og:image", + content: "/CodeForge/og-image.png", }, }, { - tag: 'link', + tag: "link", attrs: { - rel: 'icon', - type: 'image/png', - href: '/CodeForge/favicon.png', + rel: "icon", + type: "image/png", + href: "/CodeForge/favicon.png", }, }, { - tag: 'link', + tag: "link", attrs: { - rel: 'apple-touch-icon', - href: '/CodeForge/apple-touch-icon.png', + rel: "apple-touch-icon", + href: "/CodeForge/apple-touch-icon.png", }, }, { // Default to dark theme when no user preference is saved - tag: 'script', - attrs: { is: 'inline' }, + tag: "script", + attrs: { is: "inline" }, content: `(function(){var k='starlight-theme';if(!localStorage.getItem(k)){localStorage.setItem(k,'dark');document.documentElement.setAttribute('data-theme','dark');document.documentElement.style.colorScheme='dark'}})()`, }, ], @@ -150,6 +154,7 @@ export default defineConfig({ { label: 'Commands', slug: 'reference/commands' }, { label: 'Environment Variables', slug: 'reference/environment' }, { label: 'Architecture', slug: 'reference/architecture' }, + { label: 'Port Forwarding', slug: 'reference/port-forwarding' }, ], }, ], @@ -160,8 +165,13 @@ export default defineConfig({ }), starlightKbd({ types: [ - { id: 'mac', label: 'macOS', detector: 'apple', default: false }, - { id: 'windows', label: 'Windows / Linux', detector: 'windows', default: true }, + { id: "mac", label: "macOS", detector: "apple", default: false }, + { + id: "windows", + label: "Windows / Linux", + detector: "windows", + default: true, + }, ], }), starlightScrollToTop(), @@ -171,7 +181,7 @@ export default defineConfig({ sitemap(), ], server: { - host: '0.0.0.0', + host: "0.0.0.0", }, vite: { plugins: [tailwindcss()], diff --git a/docs/src/content/docs/getting-started/first-session.md b/docs/src/content/docs/getting-started/first-session.md index 68d40d5..c3a3043 100644 --- a/docs/src/content/docs/getting-started/first-session.md +++ b/docs/src/content/docs/getting-started/first-session.md @@ -105,6 +105,8 @@ CodeForge includes **21 specialized agents** and **38 skills** that activate aut If your terminal supports it, CodeForge provides a status line that shows session information at a glance. The `ccstatusline` feature adds session metadata to your terminal prompt, so you always know which session you're in and its current state. + + ## Tips for Effective Sessions :::tip[Be specific with requests] diff --git a/docs/src/content/docs/getting-started/installation.md b/docs/src/content/docs/getting-started/installation.md index 47f9bbe..1f85c5d 100644 --- a/docs/src/content/docs/getting-started/installation.md +++ b/docs/src/content/docs/getting-started/installation.md @@ -54,7 +54,14 @@ your-project/ └── ... (your existing files) ``` -## Step 2: Open in VS Code +## Step 2: Open in a DevContainer Client + +import { Tabs, TabItem } from '@astrojs/starlight/components'; + +CodeForge uses the open [Dev Containers specification](https://containers.dev/). Pick whichever client fits your workflow: + + + Open your project in VS Code. You should see a notification in the bottom-right corner: @@ -65,6 +72,51 @@ Click **Reopen in Container**. If you miss the notification, use the Command Pal 1. Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on macOS) 2. Type "Dev Containers" and select **Dev Containers: Reopen in Container** +You can watch the build progress in the "Dev Containers" output channel in the terminal panel. + + + + +Install the CLI if you haven't already: + +```bash +npm install -g @devcontainers/cli +``` + +Build and start the container: + +```bash +devcontainer up --workspace-folder . +``` + +Then connect to the running container: + +```bash +docker exec -it zsh +``` + +Use `docker ps` to find the container name. For port forwarding outside VS Code, see the [Port Forwarding reference](../reference/port-forwarding/). + + + + +1. Open **JetBrains Gateway** (or IntelliJ IDEA / PyCharm with the [Dev Containers plugin](https://plugins.jetbrains.com/plugin/21962-dev-containers)) +2. Select **Dev Containers** as the connection type +3. Point to your project directory containing `.devcontainer/` +4. Gateway builds the container and connects the IDE backend automatically + + + + +1. Push your project (with the `.devcontainer/` directory) to GitHub +2. Go to your repository on GitHub and click **Code → Codespaces → Create codespace** +3. Codespaces reads your `devcontainer.json` and builds the environment in the cloud + +No local Docker installation required. Port forwarding is handled automatically by Codespaces. + + + + ### What Happens During the First Build The first container build takes several minutes (typically 3-8 minutes depending on your internet speed and hardware). Here's what's happening behind the scenes: @@ -73,10 +125,10 @@ The first container build takes several minutes (typically 3-8 minutes depending 2. **Feature installation** — installs 21 DevContainer features in dependency order: Node.js and uv first (other tools depend on them), then Rust, Bun, Claude Code, and all custom features 3. **Post-start setup** — deploys configuration files, sets up shell aliases, and configures plugins -You can watch the progress in VS Code's log output. Look for the "Dev Containers" output channel in the terminal panel. - :::caution[Don't interrupt the first build] -If the build is interrupted, Docker may cache a partial state. Use **Dev Containers: Rebuild Container Without Cache** to start fresh. +If the build is interrupted, Docker may cache a partial state. Rebuild without cache to start fresh: +- **VS Code**: Dev Containers: Rebuild Container Without Cache +- **CLI**: `devcontainer up --workspace-folder . --remove-existing-container` ::: ## Step 3: Verify Installation @@ -162,8 +214,8 @@ npx codeforge-dev@latest This updates the `.devcontainer/` configuration. After updating, rebuild the container: -1. Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on macOS) -2. Select **Dev Containers: Rebuild Container** +- **VS Code**: Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on macOS) and select **Dev Containers: Rebuild Container** +- **CLI**: `devcontainer up --workspace-folder . --remove-existing-container` :::tip[Check what changed] Use `git diff .devcontainer/` after updating to review what changed before committing. This lets you verify the update didn't overwrite any customizations you want to keep. @@ -220,6 +272,10 @@ Use `git diff .devcontainer/` after updating to review what changed before commi - **Extension not installed** — install `ms-vscode-remote.remote-containers` from the Extensions marketplace, then reload VS Code - **`.devcontainer/` not at repo root** — VS Code looks for `.devcontainer/` in the workspace root folder. If your project is inside a subfolder, open that subfolder directly + +:::note[Using a different client?] +Not using VS Code? The DevContainer CLI, JetBrains Gateway, DevPod, and Codespaces all read the same `devcontainer.json`. See [Step 2](#step-2-open-in-a-devcontainer-client) for client-specific instructions. +::: - **VS Code version** — DevContainers requires VS Code 1.85 or later. Check **Help → About** and update if needed ### Docker permission errors (Linux) diff --git a/docs/src/content/docs/getting-started/requirements.md b/docs/src/content/docs/getting-started/requirements.md index a651e72..b68623a 100644 --- a/docs/src/content/docs/getting-started/requirements.md +++ b/docs/src/content/docs/getting-started/requirements.md @@ -29,15 +29,20 @@ Run `docker info` in your terminal. If you see container and image counts, Docke WSL 2 is required. Docker Desktop's legacy Hyper-V backend is not supported because DevContainers rely on WSL 2 for Linux container support. If you haven't enabled WSL 2, follow [Microsoft's WSL installation guide](https://learn.microsoft.com/en-us/windows/wsl/install) before proceeding. ::: -### VS Code +### DevContainer Client -- **Visual Studio Code** — version 1.85 or later -- **Dev Containers extension** — install `ms-vscode-remote.remote-containers` from the Extensions marketplace +CodeForge uses the open [Dev Containers specification](https://containers.dev/). Any compatible client works — pick whichever fits your workflow: -The Dev Containers extension is what makes VS Code able to open your project inside the container. Without it, the "Reopen in Container" prompt won't appear. +| Client | Notes | +|--------|-------| +| **VS Code** with [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) | Most popular option. Version 1.85+ required. | +| **DevContainer CLI** | Standalone CLI: `npm install -g @devcontainers/cli`. No editor required — connect via any terminal. | +| **GitHub Codespaces** | Zero local setup. Push your repo with `.devcontainer/` and create a Codespace. | +| **JetBrains Gateway** | Native devcontainer.json support via [Dev Containers plugin](https://plugins.jetbrains.com/plugin/21962-dev-containers). | +| **DevPod** | Open-source, editor-agnostic client. Supports local Docker, Kubernetes, and cloud backends. See [devpod.sh](https://devpod.sh/). | -:::note[Alternative: GitHub Codespaces] -If you prefer not to run Docker locally, you can use GitHub Codespaces. Push your project (with the `.devcontainer/` directory) to GitHub and create a Codespace from it. Codespaces use the same DevContainer configuration, so everything works the same way. +:::tip[Port forwarding outside VS Code] +VS Code auto-detects ports opened inside the container. Other clients don't. CodeForge includes `devcontainer-bridge` (`dbr`) for dynamic port forwarding from any terminal. See the [Port Forwarding reference](../reference/port-forwarding/) for setup details. ::: ### Claude Code diff --git a/docs/src/content/docs/reference/port-forwarding.md b/docs/src/content/docs/reference/port-forwarding.md new file mode 100644 index 0000000..a4d07ed --- /dev/null +++ b/docs/src/content/docs/reference/port-forwarding.md @@ -0,0 +1,114 @@ +--- +title: Port Forwarding +description: How to access ports from inside the CodeForge container — VS Code auto-detect, devcontainer-bridge, and SSH tunneling. +sidebar: + order: 5 +--- + +CodeForge runs inside a Docker container. When a service inside the container listens on a port (e.g., a dev server on port 3000 or the Claude Dashboard on port 7847), you need a forwarding mechanism to access it from your host machine. Which mechanism to use depends on your DevContainer client. + +## Mechanisms + +| Mechanism | Client | Discovery | Setup Required | +|-----------|--------|-----------|----------------| +| VS Code auto-detect | VS Code only | Dynamic — all ports | None | +| devcontainer-bridge (`dbr`) | Any terminal client | Dynamic — polls `/proc/net/tcp` | Host daemon required | +| SSH tunneling | Any SSH client | Manual | Per-port command | + +## VS Code Auto-Detect + +VS Code automatically detects ports opened inside the container and forwards them to your host. CodeForge configures this in `devcontainer.json`: + +- **All ports** are auto-forwarded with a notification prompt +- **Port 7847** (Claude Dashboard) gets a friendly label in the Ports panel + +No setup required — ports appear in the VS Code **Ports** panel as services start. Click the local address to open in your browser. + +:::note +This only works inside VS Code and GitHub Codespaces. The `devcontainer` CLI, JetBrains Gateway, and DevPod ignore `portsAttributes` in `devcontainer.json`. +::: + +## devcontainer-bridge (`dbr`) + +[devcontainer-bridge](https://github.com/bradleybeddoes/devcontainer-bridge) provides dynamic port forwarding for any terminal-based workflow. It works with the DevContainer CLI, SSH connections, or any other way you access the container. + +### How It Works + +1. A lightweight daemon inside the container polls `/proc/net/tcp` to discover listening ports +2. A host-side daemon maintains SSH tunnels for each discovered port +3. Ports are forwarded automatically as services start and stop — no manual configuration + +The container daemon **auto-starts** when the container boots and is inert (zero overhead) until the host daemon connects. + +### Setup + +**Inside the container** — already done. CodeForge installs `dbr` as a DevContainer feature. + +**On your host machine**, install and start the host daemon: + +```bash +# Install dbr on your host (see https://github.com/bradleybeddoes/devcontainer-bridge/releases) +# Then start the host daemon: +dbr host-daemon +``` + +The host daemon discovers running containers and establishes port forwarding automatically. Leave it running in the background while you work. + +### Verify + +Once the host daemon is running, any port opened inside the container becomes accessible on `localhost` on your host. Test with: + +```bash +# Inside the container +python -m http.server 8080 + +# On your host +curl http://localhost:8080 +``` + +## SSH Tunneling + +For one-off port forwarding or environments where `dbr` isn't available, use SSH tunneling directly: + +```bash +# Forward a single port +ssh -L 3000:localhost:3000 @ + +# Forward multiple ports +ssh -L 3000:localhost:3000 -L 7847:localhost:7847 @ +``` + +This requires SSH access to the container, which is available when connecting via the `devcontainer` CLI or any Docker SSH setup. + +## Which Should I Use? + +| If you use... | Recommended mechanism | +|---------------|----------------------| +| VS Code | Auto-detect (built-in, zero config) | +| DevContainer CLI | `dbr` (dynamic, automatic) | +| JetBrains Gateway | Gateway's built-in forwarding, or `dbr` as fallback | +| Codespaces | Auto-detect (built-in to Codespaces) | +| DevPod | DevPod's built-in SSH tunneling, or `dbr` | +| Direct SSH | SSH tunneling for specific ports, or `dbr` for all ports | + +## Configuration + +Port forwarding behavior is configured in `.devcontainer/devcontainer.json`: + +```jsonc +"forwardPorts": [], +"portsAttributes": { + "7847": { + "label": "Claude Dashboard", + "onAutoForward": "notify" + }, + "*": { + "onAutoForward": "notify" + } +} +``` + +- `forwardPorts` — static port list (empty by default; VS Code auto-detects dynamically instead) +- `portsAttributes` — labels and behavior for auto-detected ports (VS Code / Codespaces only) + +These settings are ignored by non-VS Code clients. Use `dbr` or SSH tunneling instead.