diff --git a/.gitignore b/.gitignore index 106c9ab..db0fb87 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ node_modules/ .hooks/ .agent-memory/ hooks/ -.tmp/ \ No newline at end of file +.tmp/ +package-lock.json diff --git a/CLAUDE.md b/CLAUDE.md index d780846..572c217 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -41,7 +41,7 @@ docs/ ## Key architecture decisions -- **Zero dependencies** — only Node.js stdlib + system `sqlite3` CLI for SQLite agents +- **Zero dependencies for the core** — dashboard/CLI use only Node.js stdlib + system `sqlite3` CLI for SQLite agents. The optional browser terminal (Workspace) is the sole exception: it lazily loads `@lydell/node-pty` (declared in `optionalDependencies`, prebuilt-only, never runs node-gyp). If it is absent the dashboard still runs and the terminal reports itself disabled. Do NOT add core dependencies. - **Node >= 18** — minimum supported version - **Single process** — server + static HTML in one process - **Template injection** — `html.js` reads CSS/JS files and injects via `split/join` (not `String.replace` which breaks on `$` characters in JS code) diff --git a/package.json b/package.json index b123970..ccb1b13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codbash-app", - "version": "7.6.0", + "version": "7.7.0", "description": "Dashboard + CLI for AI coding agents — Claude Code, Codex, Cursor, OpenCode, Kiro. View, search, resume, convert, sync sessions.", "bin": { "codbash": "./bin/cli.js", @@ -38,5 +38,9 @@ "license": "MIT", "engines": { "node": ">=18" + }, + "comment:optionalDependencies": "Browser terminal (Workspace) only. @lydell/node-pty ships prebuilt binaries and never invokes node-gyp; if no prebuilt exists for the platform it is simply skipped and the dashboard still runs — the terminal feature stays disabled with a friendly notice. The core dashboard remains dependency-free.", + "optionalDependencies": { + "@lydell/node-pty": "^1.2.0-beta.12" } } diff --git a/src/changelog.js b/src/changelog.js index e080de9..be92d5e 100644 --- a/src/changelog.js +++ b/src/changelog.js @@ -1,6 +1,17 @@ 'use strict'; const CHANGELOG = [ + { + version: '7.7.0', + date: '2026-07-19', + title: 'Workspace — browser terminal (preview)', + changes: [ + 'New "Workspace" view: a real terminal right in the browser (xterm.js) — run shells and agents without leaving codbash', + 'Optional feature: the core dashboard stays dependency-free; the terminal lazily loads @lydell/node-pty, which ships prebuilt binaries (no compiler / node-gyp needed)', + 'Secured by a per-process token + same-origin check on the WebSocket, so it is safe to run the dashboard in server mode', + 'This is the first step (single pane); splits, reattach across reload, saved commands and per-project workspaces are coming next', + ], + }, { version: '7.6.0', date: '2026-07-19', diff --git a/src/frontend/app.js b/src/frontend/app.js index 77b3a7f..577f0e3 100644 --- a/src/frontend/app.js +++ b/src/frontend/app.js @@ -1594,6 +1594,12 @@ function render() { var stats = document.getElementById('stats'); if (!content) return; + // Tear down the live terminal when navigating away from the Workspace view + // so the pty + WebSocket don't leak in the background. + if (currentView !== 'workspace' && typeof teardownWorkspaceIfActive === 'function') { + teardownWorkspaceIfActive(); + } + // Preserve scroll + collapsed state across re-renders var scrollTop = content.scrollTop; var collapsedGroups = new Set(); @@ -1665,6 +1671,11 @@ function render() { return; } + if (currentView === 'workspace') { + renderWorkspace(content); + return; + } + if (currentView === 'settings') { renderSettings(content); return; diff --git a/src/frontend/index.html b/src/frontend/index.html index d2899ea..7d74930 100644 --- a/src/frontend/index.html +++ b/src/frontend/index.html @@ -61,6 +61,10 @@ All Sessions +