Skip to content

Release v2.1.0#65

Merged
AnExiledDev merged 40 commits intomainfrom
staging
Mar 25, 2026
Merged

Release v2.1.0#65
AnExiledDev merged 40 commits intomainfrom
staging

Conversation

@AnExiledDev
Copy link
Copy Markdown
Owner

Summary

Release v2.1.0 consolidating all work since v2.1.1 patch release.

Highlights

  • codeforge proxy — new CLI command to launch Claude Code through mitmproxy (mitmweb) for real-time API traffic inspection. Auto-installs mitmproxy, manages CA certificates, provides browser UI at port 8081. Useful for monitoring token usage and rate limit utilization via anthropic-ratelimit-unified-* response headers.
  • First-party dashboard — replaced third-party session dashboard with codeforge-dashboard built from monorepo
  • Per-hook disable mechanism — disable individual plugin hooks via disabled-hooks.json without disabling entire plugins
  • Version lock — pin Claude Code to a specific version via CLAUDE_VERSION_LOCK in .env
  • Plugin test suite — 241 pytest tests across 6 critical plugin scripts
  • Scope guard & dangerous command blocker fixes — eliminated false positives on system paths
  • Windows/macOS Docker Desktop compatibility — fixed claude-code-native install failures

Packages affected

  • cli/ — new proxy command, tests
  • container/ — changelog, docs, config, scripts, plugin fixes
  • dashboard/ — first-party dashboard package (added in prior commits)

Test plan

  • cd cli && bun test — 320 tests pass
  • cd cli && bun run build — builds successfully
  • codeforge proxy --setup installs mitmproxy and CA cert
  • codeforge proxy launches mitmweb + claude, traffic visible at :8081
  • Version lock: set CLAUDE_VERSION_LOCK=2.1.80 in .env, verify pinned on container start
  • Per-hook disable: add hook name to disabled-hooks.json, verify hook skipped
  • Dashboard launches on container start via codeforge-dashboard

AnExiledDev and others added 30 commits February 27, 2026 06:46
Security guards, workspace scope enforcement, readonly bash guard,
and agent redirect logic had zero test coverage. This adds pytest
tests for the pure functions in each script, covering all regex
patterns, edge cases, bypass vectors, and false positive checks.
- Resolve CHANGELOG.md merge conflict (testing section + main's fixes)
- Fix run_main() return type in test_redirect_builtin_agents.py (CodeRabbit review)
- Update block-dangerous tests for new source patterns:
  - --force-with-lease now intentionally blocked (was documented as bug)
  - Bare force push message changed to FORCE_PUSH_SUGGESTION
  - Add tests for remote branch deletion patterns (--delete, colon-refspec)
Scope guard: resolve CWD with realpath to prevent symlink mismatches,
detect .claude/worktrees/ and expand scope to project root so sibling
worktrees aren't blocked, and improve error messages with resolved paths.

Stop hooks: add 5-minute per-session cooldown to commit-reminder and
spec-reminder to prevent repeated firing in team/agent scenarios.
resolve_scope_root() now walks up from CWD looking for .git to find the
repository root, preventing false positives when working in subdirectories
like cli/, src/, or tests/. Safety ceiling at /workspaces prevents scope
from escaping the workspace boundary.
Move .git/ to project root so the entire workspace is tracked in a
single repository. Git detects all container-root files as renames
into the container/ subdirectory. Root-level files (.github/,
LICENSE.txt, CLA.md, CONTRIBUTING.md, .gitattributes) remain at the
repository root. The docs/ package was already tracked at docs/ and
is unaffected by this change.

This is a structural reorganization — no code changes.
Add codeforge-cli v0.1.0 (Bun/TypeScript) — a CLI for CodeForge
development workflows including session search, plan management,
and task tracking. The docs package was already tracked from the
previous repository structure.
CI workflows:
- Add working-directory: container to all container job steps
- Add path filters (container/**, cli/**) to trigger workflows selectively
- Add test-cli job using Bun for CLI package
- Update changelog/package.json paths for container subdirectory
- Update devcontainer feature publish paths

Config:
- Add repository.directory to container and cli package.json
- Remove docs:* scripts from container (docs is now a sibling package)
- Simplify container/.gitignore (root handles shared patterns)
- Update dependabot directories for monorepo layout

Docs:
- Add root README.md with monorepo overview and package table
- Add root CLAUDE.md with branching strategy and dev rules
- Update container/CLAUDE.md to reference root for shared rules
Update sync-changelog.mjs to read from container/.devcontainer/CHANGELOG.md
instead of the old .devcontainer/CHANGELOG.md path. Regenerate the docs
changelog page with updated source reference.
Scope guard now only enforces isolation between workspace projects.
Paths outside the workspace (e.g. /dev/null, /usr/, /etc/) are not
this guard's jurisdiction — other guards handle system-level security.
Removes the complex system-command exemption logic that was insufficient
and fragile.
The redirect patterns matched text content inside command arguments
(e.g. PR body text containing example paths), causing false positives.
Write location enforcement is the scope guard's responsibility, not
the dangerous-command-blocker's.
- plugin list/show/enable/disable/hooks/agents/skills subcommands
- config show/apply subcommands with settings writer
- review command with headless Claude runner and prompt templates
- Plugin/config/review schemas, loaders, and output formatters
- Platform detection utility
- Tests for plugin loader, plugin list, review output, review runner,
  settings writer, and platform detection
- Register plugin, config, and review subcommands in index.ts
- Remove fast-glob dependency (use native Bun glob)
- Fix build output to single file (--outfile dist/codeforge.js)
- Add npm publish metadata (keywords, files, prepublishOnly)
- Fix search filter edge cases with new tests
- Fix plan-loader path resolution
- Update session list/show formatting
- release-cli.yml: tag-triggered (cli-v*) npm publish + GitHub release
- codeforge-cli devcontainer feature: installs CLI globally via npm
- Register codeforge-cli feature in devcontainer.json
- Remove dead codeforge alias, add codeforge to cc-tools list
- CI: cross-platform test matrix (ubuntu, windows, macos)
- Fix docs changelog sync paths for monorepo structure
Add plugin, config, and review commands to CLI
…weep

CLI (experimental):
- Add index command group (build, search, show, stats, tree, clean)
- Add container command group (up, down, rebuild, exec, ls, shell)
- Add container proxy — auto-proxies into devcontainer from host
- Remove review command (never shipped)
- Mark CLI as experimental in all metadata and docs

Container (v2.1.0 + v2.1.1):
- Spec workflow v2 "Spec Packages" — 8 commands replaced with 3
- Scope guard: fix /dev/null false positive, fix CWD drift
- Updated agents, skills, system prompts, and config

Docs:
- Add CLI commands to reference, tools, and changelog pages
- Sync docs changelog with container CHANGELOG (v2.1.0, v2.1.1)
- Update spec workflow, agents, skills, and rules docs
…weep (#58)

CLI (experimental):
- Add index command group (build, search, show, stats, tree, clean)
- Add container command group (up, down, rebuild, exec, ls, shell)
- Add container proxy — auto-proxies into devcontainer from host
- Remove review command (never shipped)
- Mark CLI as experimental in all metadata and docs

Container (v2.1.0 + v2.1.1):
- Spec workflow v2 "Spec Packages" — 8 commands replaced with 3
- Scope guard: fix /dev/null false positive, fix CWD drift
- Updated agents, skills, system prompts, and config

Docs:
- Add CLI commands to reference, tools, and changelog pages
- Sync docs changelog with container CHANGELOG (v2.1.0, v2.1.1)
- Update spec workflow, agents, skills, and rules docs

Co-authored-by: AnExiledDev <AnExiledDev@users.noreply.github.com>
- CLI CHANGELOG: "Ships with CodeForge v2.1.0" → "v2.1.1" to match
  the actual container release version
- Remove agent-system's inject-cwd.py and its SubagentStart hook —
  workspace-scope-guard already handles SubagentStart with superior
  scope-resolved CWD (worktree-aware, git-root-aware, session-persisted)
# Conflicts:
#	container/.devcontainer/CHANGELOG.md
#	container/package.json
Installer now falls back to HOME override when su is unavailable,
which happens on VM-based Docker (Docker Desktop). Also removes
unnecessary su call in version verification.
…iner runtime

- Switch status bar from 6-line ccburn layout to 3-line native
  session-usage and weekly-usage ccstatusline widgets
- Disable ccburn devcontainer feature (commented out in devcontainer.json)
- Remove preflight.sh — redundant with Docker's own error reporting
- Forward port 7847 for dashboard and add container name to runArgs
- Add autoMemoryDirectory setting for project-local .claude/memory/
- Add safety rules, hooks awareness, tool selection guidance, and
  anti-over-engineering directives to main and orchestrator prompts
- Add auto-memory system documentation with memory types and format
- Add context management notes for tool result persistence
New skill for headless browser automation with CLI reference and
workflow patterns. Bumps skill count from 22 to 23 across plugin
metadata, container docs, and site documentation. Also adds
CLAUDE_PLUGIN_DATA docs, npmignore hardening, and changelog entries.
New commands for viewing team tasks: `codeforge task list` shows all
tasks for a team, `codeforge task show` displays task detail with
dependencies. Includes text and JSON formatters and test coverage.
Also removes prompts/ from package files and adds CLI README.
Session list now shows plan slugs and task progress bars when sessions
have associated plans or team tasks. Loads plans once and indexes by
slug, caches task summaries per team name. Includes text and JSON
output support with full test coverage.
New Svelte 5 SPA + Bun backend for session analytics, conversation
replay, task/plan/agent views, and cost tracking. Updates root
CLAUDE.md to reflect four-package monorepo with dashboard-specific
test commands and Dashboard vs CLI guidance.
Spec packages are local working directories, not tracked in version control.
Dashboard package:
- Rename @codeforge/dashboard → codeforge-dashboard, remove private flag
- Add bin wrapper with --port/--host/--version/--help flags
- Add HOST env var support to Bun.serve for container port forwarding
- Add files, engines, prepublishOnly fields for npm publish
- Move build-time deps (Svelte, Vite, Tailwind) to devDependencies

Container feature:
- Rewrite install.sh: bun install -g replaces npm install -g
- Add autostart poststart hook (PID-guarded, nohup background launch)
- Rename command: claude-dashboard → codeforge-dashboard
- Remove persistence symlink hook (DB on bind mount)
- Update feature metadata, README, devcontainer.json, CLAUDE.md

CI/CD:
- Add release-dashboard.yml workflow (dashboard-v* tags → npm publish)
- Add test-dashboard job to ci.yml
- Add dashboard/CHANGELOG.md
- Add dashboard/.svelte-kit/, dashboard/build/, dashboard/mockups/, and
  .claude/ to .gitignore
- Untrack 817 committed build artifacts (git rm --cached)
- Replace git-changes statusline widget with cached custom-command that
  skips git diff when index.lock is held and caches results for 30s
- Add allow-list exception to protected-files-guard for .git/index.lock
  deletion
Container:
- Update devcontainer.json configuration
- Expand claude-code-headless skill documentation

Dashboard — Parser/Server:
- Add memory-sync service for background synchronization
- Update parser queries, types, and DB layer for memory filtering
- Extend API routes with memory and session endpoints

Dashboard — UI Components:
- Add ApproveModal, MaintenanceModal, and ConfirmModal components
- Enhance memory views: MemoriesPage, MemoriesTab, ObservationsTab,
  RunDetail, RunsTab with filtering and approval workflows
- Update session views: SessionList, SessionDetail, AgentsView
- Improve dashboard charts: ActivityHeatmap, DurationDistribution,
  HourlyHeatmap, ModelDistribution, OverviewCards, ToolUsage
- Update Sidebar, ProjectDetail, and global styles

Dashboard — Stores/Routes:
- Extend memory, sessions, and SSE stores for new data flows
- Update page routes for memories and session detail views
# Conflicts:
#	container/.devcontainer/CHANGELOG.md
#	container/package.json
# Conflicts:
#	.gitignore
#	cli/CHANGELOG.md
#	cli/src/index.ts
#	container/.codeforge/config/orchestrator-system-prompt.md
#	container/.devcontainer/CHANGELOG.md
#	container/.devcontainer/CLAUDE.md
… into staging

# Conflicts:
#	container/.devcontainer/CHANGELOG.md
#	container/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py
- Add dashboard and memories feature docs, update astro sidebar config
- Expand plugin guard tests with edge cases and new test fixtures
- Add pyproject.toml, dashboard README, CLI README task subcommands
- Update changelog, architecture, and getting-started docs
Include dashboard in the packages table and test instructions.
Hooks now check .codeforge/config/disabled-hooks.json at startup and
exit early if their script name appears in the disabled list. Disables
git-state-injector, ticket-linker, spec-reminder, and commit-reminder
by default. Also comments out legacy claude-session-dashboard feature
in devcontainer.json (replaced by first-party dashboard).

Fixed misplaced hook gate in syntax-validator.py (was inside try block).
New CLI command that launches Claude Code through mitmweb, enabling
raw API request/response inspection via a browser UI. Auto-installs
mitmproxy via pipx, manages CA certificate trust, and cleans up on exit.

Usage: codeforge proxy [--setup] [--no-web] [-- <claude-args>]
- Bump changelog to v2.1.0 with proxy feature, dashboard, hooks,
  scope guard fixes, and all unreleased changes
- Document codeforge proxy command in CLAUDE.md
- Add CLAUDE_VERSION_LOCK support to update script
- Add DISABLE_AUTOUPDATER to settings.json
- Export CLAUDE_VERSION_LOCK in setup.sh
- Add version lock docs to .env.example
- Fix syntax-validator.py formatting
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

Important

Review skipped

Too many files!

This PR contains 216 files, which is 66 over the limit of 150.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 10dce691-a895-4375-beb3-f178531dd025

📥 Commits

Reviewing files that changed from the base of the PR and between 178ad2a and fb7881e.

⛔ Files ignored due to path filters (2)
  • cli/bun.lock is excluded by !**/*.lock
  • dashboard/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (216)
  • .github/workflows/ci.yml
  • .github/workflows/release-dashboard.yml
  • .gitignore
  • CLAUDE.md
  • README.md
  • cli/README.md
  • cli/package.json
  • cli/src/commands/proxy.ts
  • cli/src/commands/session/list.ts
  • cli/src/commands/task/list.ts
  • cli/src/commands/task/show.ts
  • cli/src/index.ts
  • cli/src/output/session-list.ts
  • cli/src/output/task-text.ts
  • cli/src/utils/mitmproxy.ts
  • cli/tests/proxy.test.ts
  • cli/tests/session-list.test.ts
  • cli/tests/task-search.test.ts
  • container/.codeforge/config/ccstatusline-settings.json
  • container/.codeforge/config/disabled-hooks.json
  • container/.codeforge/config/main-system-prompt.md
  • container/.codeforge/config/orchestrator-system-prompt.md
  • container/.codeforge/config/settings.json
  • container/.codeforge/file-manifest.json
  • container/.devcontainer/.env.example
  • container/.devcontainer/CHANGELOG.md
  • container/.devcontainer/CLAUDE.md
  • container/.devcontainer/README.md
  • container/.devcontainer/devcontainer.json
  • container/.devcontainer/features/ccburn/README.md
  • container/.devcontainer/features/ccstatusline/README.md
  • container/.devcontainer/features/ccstatusline/install.sh
  • container/.devcontainer/features/claude-code-native/install.sh
  • container/.devcontainer/features/claude-session-dashboard/README.md
  • container/.devcontainer/features/claude-session-dashboard/devcontainer-feature.json
  • container/.devcontainer/features/claude-session-dashboard/install.sh
  • container/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/redirect-builtin-agents.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/task-completed-check.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/teammate-idle-check.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/verify-no-regression.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/verify-tests-pass.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/advisory-test-runner.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/collect-edited-files.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/format-on-stop.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/lint-file.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/syntax-validator.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected-bash.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/collect-session-edits.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/commit-reminder.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/git-state-injector.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/todo-harvester.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/.claude-plugin/plugin.json
  • container/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/README.md
  • container/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/agent-browser/SKILL.md
  • container/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/agent-browser/references/cli-reference.md
  • container/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/agent-browser/references/workflow-patterns.md
  • container/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-code-headless/SKILL.md
  • container/.devcontainer/plugins/devs-marketplace/plugins/spec-workflow/scripts/spec-reminder.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/scripts/ticket-linker.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py
  • container/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/inject-workspace-cwd.py
  • container/.devcontainer/scripts/preflight.sh
  • container/.devcontainer/scripts/setup-update-claude.sh
  • container/.devcontainer/scripts/setup.sh
  • container/.npmignore
  • container/README.md
  • container/package.json
  • container/tests/plugins/test_block_dangerous.py
  • container/tests/plugins/test_guard_workspace_scope.py
  • dashboard/CHANGELOG.md
  • dashboard/CLAUDE.md
  • dashboard/README.md
  • dashboard/bin/codeforge-dashboard
  • dashboard/mockups/dashboard-mockup.html
  • dashboard/package.json
  • dashboard/scripts/query-db.ts
  • dashboard/src/parser/analytics.ts
  • dashboard/src/parser/context-reader.ts
  • dashboard/src/parser/cost.ts
  • dashboard/src/parser/db.ts
  • dashboard/src/parser/history-reader.ts
  • dashboard/src/parser/index.ts
  • dashboard/src/parser/plan-reader.ts
  • dashboard/src/parser/project-detector.ts
  • dashboard/src/parser/queries.ts
  • dashboard/src/parser/session-reader.ts
  • dashboard/src/parser/task-reader.ts
  • dashboard/src/parser/types.ts
  • dashboard/src/server/event-bus.ts
  • dashboard/src/server/index.ts
  • dashboard/src/server/ingestion.ts
  • dashboard/src/server/memory-analyzer.ts
  • dashboard/src/server/memory-sync.ts
  • dashboard/src/server/retention.ts
  • dashboard/src/server/routes/api.ts
  • dashboard/src/server/routes/sse.ts
  • dashboard/src/server/watcher.ts
  • dashboard/src/web/app.css
  • dashboard/src/web/app.html
  • dashboard/src/web/lib/components/SearchModal.svelte
  • dashboard/src/web/lib/components/agents/AgentsList.svelte
  • dashboard/src/web/lib/components/context/ContextFilesList.svelte
  • dashboard/src/web/lib/components/dashboard/ActivityHeatmap.svelte
  • dashboard/src/web/lib/components/dashboard/CacheEfficiency.svelte
  • dashboard/src/web/lib/components/dashboard/CostChart.svelte
  • dashboard/src/web/lib/components/dashboard/DurationDistribution.svelte
  • dashboard/src/web/lib/components/dashboard/DurationTrendChart.svelte
  • dashboard/src/web/lib/components/dashboard/HourlyHeatmap.svelte
  • dashboard/src/web/lib/components/dashboard/InsightsBar.svelte
  • dashboard/src/web/lib/components/dashboard/ModelComparisonTable.svelte
  • dashboard/src/web/lib/components/dashboard/ModelDistribution.svelte
  • dashboard/src/web/lib/components/dashboard/OverviewCards.svelte
  • dashboard/src/web/lib/components/dashboard/ProjectCostChart.svelte
  • dashboard/src/web/lib/components/dashboard/RecentActivity.svelte
  • dashboard/src/web/lib/components/dashboard/SessionScatterPlot.svelte
  • dashboard/src/web/lib/components/dashboard/TimeRangeSelector.svelte
  • dashboard/src/web/lib/components/dashboard/TokenTrendChart.svelte
  • dashboard/src/web/lib/components/dashboard/ToolUsage.svelte
  • dashboard/src/web/lib/components/dashboard/TopFiles.svelte
  • dashboard/src/web/lib/components/layout/SearchResults.svelte
  • dashboard/src/web/lib/components/layout/Sidebar.svelte
  • dashboard/src/web/lib/components/layout/TopBar.svelte
  • dashboard/src/web/lib/components/memory/ApproveModal.svelte
  • dashboard/src/web/lib/components/memory/MaintenanceModal.svelte
  • dashboard/src/web/lib/components/memory/MemoriesPage.svelte
  • dashboard/src/web/lib/components/memory/MemoriesTab.svelte
  • dashboard/src/web/lib/components/memory/ObservationHistory.svelte
  • dashboard/src/web/lib/components/memory/ObservationsTab.svelte
  • dashboard/src/web/lib/components/memory/RunDetail.svelte
  • dashboard/src/web/lib/components/memory/RunsTab.svelte
  • dashboard/src/web/lib/components/plans/PlanHistory.svelte
  • dashboard/src/web/lib/components/plans/PlansList.svelte
  • dashboard/src/web/lib/components/projects/ProjectDetail.svelte
  • dashboard/src/web/lib/components/projects/ProjectList.svelte
  • dashboard/src/web/lib/components/sessions/AgentTimeline.svelte
  • dashboard/src/web/lib/components/sessions/AgentsView.svelte
  • dashboard/src/web/lib/components/sessions/ContextView.svelte
  • dashboard/src/web/lib/components/sessions/ConversationSearch.svelte
  • dashboard/src/web/lib/components/sessions/MessageBubble.svelte
  • dashboard/src/web/lib/components/sessions/PlanView.svelte
  • dashboard/src/web/lib/components/sessions/SessionDetail.svelte
  • dashboard/src/web/lib/components/sessions/SessionList.svelte
  • dashboard/src/web/lib/components/sessions/TasksView.svelte
  • dashboard/src/web/lib/components/sessions/ThinkingBlock.svelte
  • dashboard/src/web/lib/components/sessions/ToolCallBlock.svelte
  • dashboard/src/web/lib/components/shared/ConfirmModal.svelte
  • dashboard/src/web/lib/components/shared/CopyCommand.svelte
  • dashboard/src/web/lib/components/shared/DiffView.svelte
  • dashboard/src/web/lib/components/shared/Skeleton.svelte
  • dashboard/src/web/lib/components/shared/TimeAgo.svelte
  • dashboard/src/web/lib/components/shared/TokenBadge.svelte
  • dashboard/src/web/lib/components/tasks/TasksList.svelte
  • dashboard/src/web/lib/stores/agents.svelte.ts
  • dashboard/src/web/lib/stores/analytics.svelte.ts
  • dashboard/src/web/lib/stores/context.svelte.ts
  • dashboard/src/web/lib/stores/memory.svelte.ts
  • dashboard/src/web/lib/stores/plans.svelte.ts
  • dashboard/src/web/lib/stores/projects.svelte.ts
  • dashboard/src/web/lib/stores/search.svelte.ts
  • dashboard/src/web/lib/stores/sessions.svelte.ts
  • dashboard/src/web/lib/stores/sse.svelte.ts
  • dashboard/src/web/lib/stores/tasks.svelte.ts
  • dashboard/src/web/lib/utils/diff.ts
  • dashboard/src/web/lib/utils/format.ts
  • dashboard/src/web/lib/utils/markdown.ts
  • dashboard/src/web/lib/utils/pricing.ts
  • dashboard/src/web/routes/+layout.svelte
  • dashboard/src/web/routes/+layout.ts
  • dashboard/src/web/routes/+page.svelte
  • dashboard/src/web/routes/agents/+page.svelte
  • dashboard/src/web/routes/context/+page.svelte
  • dashboard/src/web/routes/memories/+page.svelte
  • dashboard/src/web/routes/plans/+page.svelte
  • dashboard/src/web/routes/projects/+page.svelte
  • dashboard/src/web/routes/projects/[project]/+page.svelte
  • dashboard/src/web/routes/sessions/+page.svelte
  • dashboard/src/web/routes/sessions/[id]/+page.svelte
  • dashboard/src/web/routes/tasks/+page.svelte
  • dashboard/svelte.config.js
  • dashboard/tests/parser/analytics.test.ts
  • dashboard/tests/parser/cost.test.ts
  • dashboard/tests/parser/project-detector.test.ts
  • dashboard/tests/parser/session-reader.test.ts
  • dashboard/tests/server/api.test.ts
  • dashboard/tests/server/event-bus.test.ts
  • dashboard/tests/server/file-snapshots.test.ts
  • dashboard/tsconfig.json
  • dashboard/vite.config.ts
  • docs/astro.config.mjs
  • docs/src/content/docs/customization/configuration.md
  • docs/src/content/docs/features/dashboard.md
  • docs/src/content/docs/features/index.md
  • docs/src/content/docs/features/memories.md
  • docs/src/content/docs/features/tools.md
  • docs/src/content/docs/getting-started/first-session.md
  • docs/src/content/docs/getting-started/index.md
  • docs/src/content/docs/getting-started/installation.md
  • docs/src/content/docs/plugins/index.md
  • docs/src/content/docs/plugins/skill-engine.md
  • docs/src/content/docs/reference/architecture.md
  • docs/src/content/docs/reference/changelog.md
  • docs/src/content/docs/reference/commands.md
  • docs/src/content/docs/reference/index.md
  • docs/src/content/docs/reference/troubleshooting.md
  • pyproject.toml
  • tests/plugins/plugins/__init__.py
  • tests/plugins/plugins/test_block_dangerous.py
  • tests/plugins/plugins/test_guard_protected.py
  • tests/plugins/plugins/test_guard_protected_bash.py
  • tests/plugins/plugins/test_guard_readonly_bash.py
  • tests/plugins/plugins/test_guard_workspace_scope.py
  • tests/plugins/plugins/test_redirect_builtin_agents.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch staging

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Security:
- Default mitmweb to 127.0.0.1 instead of 0.0.0.0
- Generate random per-session password for mitmweb UI
- Check claude binary exists before spawning

Reliability:
- Poll for CA cert with 500ms intervals (replaces unreliable 2s sleep)
- Replace lsof port check with Bun.listen probe (no external dep)
- Log proxy cleanup errors instead of swallowing silently

Tests:
- Extract buildClaudeEnv() as pure testable function (4 tests)
- Add generatePassword tests (2 tests)
- Add occupied port test for isPortInUse
- Fix environment-dependent isCaInstalled test

Docs:
- Add commit-reminder to disabled hooks changelog entry
# Conflicts:
#	.github/workflows/ci.yml
#	.gitignore
#	CLAUDE.md
#	README.md
#	cli/bun.lock
#	cli/package.json
#	cli/src/commands/session/list.ts
#	cli/src/index.ts
#	cli/src/output/session-list.ts
#	cli/src/output/task-text.ts
#	cli/tests/session-list.test.ts
#	cli/tests/task-search.test.ts
#	container/.codeforge/config/ccstatusline-settings.json
#	container/.codeforge/config/orchestrator-system-prompt.md
#	container/.devcontainer/CHANGELOG.md
#	container/.devcontainer/CLAUDE.md
#	container/.devcontainer/features/claude-session-dashboard/README.md
#	container/.devcontainer/features/claude-session-dashboard/devcontainer-feature.json
#	container/.devcontainer/features/claude-session-dashboard/install.sh
#	container/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/commit-reminder.py
#	container/.devcontainer/plugins/devs-marketplace/plugins/spec-workflow/scripts/spec-reminder.py
#	container/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py
#	container/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/inject-workspace-cwd.py
#	container/.devcontainer/scripts/preflight.sh
#	container/README.md
#	container/package.json
#	container/tests/plugins/test_guard_workspace_scope.py
#	docs/src/content/docs/reference/changelog.md
#	docs/src/content/docs/reference/commands.md
@AnExiledDev AnExiledDev merged commit 681d346 into main Mar 25, 2026
17 checks passed
@AnExiledDev AnExiledDev deleted the staging branch March 25, 2026 23:05
const s = this.getAttribute('data-sessions');
const t = this.getAttribute('data-tokens');
const dt = this.getAttribute('data-date');
tooltip.innerHTML = `<strong>${dt}</strong><br>${s} session${s !== '1' ? 's' : ''} | ${t} tokens`;

Check failure

Code scanning / CodeQL

DOM text reinterpreted as HTML High

DOM text
is reinterpreted as HTML without escaping meta-characters.
DOM text
is reinterpreted as HTML without escaping meta-characters.
DOM text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI 5 days ago

In general, the problem is that DOM text (attribute values) is being inserted into the DOM via innerHTML, which interprets the string as HTML. The robust fix is to avoid innerHTML for dynamic, potentially untrusted data and instead either:

  • Use textContent/innerText to insert plain text, or
  • Build the DOM tree explicitly (e.g., create <strong> and text nodes, insert <br> elements) so that untrusted values are only ever assigned as text, not as HTML.

For this specific case in dashboard/mockups/dashboard-mockup.html around line 2278, we should replace:

tooltip.innerHTML = `<strong>${dt}</strong><br>${s} session${s !== '1' ? 's' : ''} | ${t} tokens`;

with code that:

  1. Clears the tooltip’s existing children (tooltip.innerHTML = '' or similar).
  2. Creates a <strong> element, sets its textContent to dt, and appends it.
  3. Appends a <br> element.
  4. Creates a text node for the rest of the string, combining s, t, and the pluralization text, and appends it.

All untrusted pieces (dt, s, t) will then be treated as text, not HTML, eliminating XSS even if they contain HTML metacharacters. No new imports or external libraries are needed; we only use standard DOM APIs. The change is localized to the mouseenter event listener in the shown snippet of dashboard/mockups/dashboard-mockup.html.

Suggested changeset 1
dashboard/mockups/dashboard-mockup.html

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/dashboard/mockups/dashboard-mockup.html b/dashboard/mockups/dashboard-mockup.html
--- a/dashboard/mockups/dashboard-mockup.html
+++ b/dashboard/mockups/dashboard-mockup.html
@@ -2275,7 +2275,14 @@
           const s = this.getAttribute('data-sessions');
           const t = this.getAttribute('data-tokens');
           const dt = this.getAttribute('data-date');
-          tooltip.innerHTML = `<strong>${dt}</strong><br>${s} session${s !== '1' ? 's' : ''} | ${t} tokens`;
+          // Build tooltip content safely without using innerHTML with untrusted data
+          tooltip.innerHTML = '';
+          const strongEl = document.createElement('strong');
+          strongEl.textContent = dt;
+          tooltip.appendChild(strongEl);
+          tooltip.appendChild(document.createElement('br'));
+          const sessionsText = `${s} session${s !== '1' ? 's' : ''} | ${t} tokens`;
+          tooltip.appendChild(document.createTextNode(sessionsText));
           tooltip.classList.add('visible');
           const rect = this.getBoundingClientRect();
           tooltip.style.left = (rect.left + rect.width / 2 - tooltip.offsetWidth / 2) + 'px';
EOF
@@ -2275,7 +2275,14 @@
const s = this.getAttribute('data-sessions');
const t = this.getAttribute('data-tokens');
const dt = this.getAttribute('data-date');
tooltip.innerHTML = `<strong>${dt}</strong><br>${s} session${s !== '1' ? 's' : ''} | ${t} tokens`;
// Build tooltip content safely without using innerHTML with untrusted data
tooltip.innerHTML = '';
const strongEl = document.createElement('strong');
strongEl.textContent = dt;
tooltip.appendChild(strongEl);
tooltip.appendChild(document.createElement('br'));
const sessionsText = `${s} session${s !== '1' ? 's' : ''} | ${t} tokens`;
tooltip.appendChild(document.createTextNode(sessionsText));
tooltip.classList.add('visible');
const rect = this.getBoundingClientRect();
tooltip.style.left = (rect.left + rect.width / 2 - tooltip.offsetWidth / 2) + 'px';
Copilot is powered by AI and may make mistakes. Always verify output.
const EVENT_HANDLER_RE = /\s+on\w+\s*=\s*["'][^"']*["']/gi;

function sanitize(html: string): string {
return html.replace(DANGEROUS_TAG_RE, "").replace(EVENT_HANDLER_RE, "");

Check failure

Code scanning / CodeQL

Incomplete multi-character sanitization High

This string may still contain
on
, which may cause an HTML attribute injection vulnerability.

Copilot Autofix

AI 5 days ago

In general, to fix incomplete multi-character sanitization, we must ensure that applying the sanitizer cannot reveal new instances of the same unsafe pattern. This can be done either by (a) using a robust HTML sanitization library, or (b) repeatedly applying the existing regexes until the output no longer changes. Since we should avoid changing functionality and external behavior significantly, the best minimal change is to wrap the current two .replace calls in a loop that runs until no further replacements occur.

Concretely, in dashboard/src/web/lib/utils/markdown.ts, we will modify the sanitize(html: string) function (lines 7–9). Instead of a single return html.replace(...).replace(...);, we introduce a simple fixed-point loop:

  1. Keep a previous string.
  2. In each iteration, compute current = previous.replace(DANGEROUS_TAG_RE, "").replace(EVENT_HANDLER_RE, "");.
  3. Continue looping while current !== previous.
  4. Return the stable current.

This preserves the existing sanitization semantics for inputs that already stabilize in one pass, but fixes the multi-character sanitization issue for tricky inputs where new matches appear after earlier replacements. No new imports or helpers are required; we only change the body of sanitize.

Suggested changeset 1
dashboard/src/web/lib/utils/markdown.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/dashboard/src/web/lib/utils/markdown.ts b/dashboard/src/web/lib/utils/markdown.ts
--- a/dashboard/src/web/lib/utils/markdown.ts
+++ b/dashboard/src/web/lib/utils/markdown.ts
@@ -5,7 +5,17 @@
 const EVENT_HANDLER_RE = /\s+on\w+\s*=\s*["'][^"']*["']/gi;
 
 function sanitize(html: string): string {
-	return html.replace(DANGEROUS_TAG_RE, "").replace(EVENT_HANDLER_RE, "");
+	let previous: string;
+	let current = html;
+
+	do {
+		previous = current;
+		current = previous
+			.replace(DANGEROUS_TAG_RE, "")
+			.replace(EVENT_HANDLER_RE, "");
+	} while (current !== previous);
+
+	return current;
 }
 
 type Highlighter = HighlighterGeneric<string, string>;
EOF
@@ -5,7 +5,17 @@
const EVENT_HANDLER_RE = /\s+on\w+\s*=\s*["'][^"']*["']/gi;

function sanitize(html: string): string {
return html.replace(DANGEROUS_TAG_RE, "").replace(EVENT_HANDLER_RE, "");
let previous: string;
let current = html;

do {
previous = current;
current = previous
.replace(DANGEROUS_TAG_RE, "")
.replace(EVENT_HANDLER_RE, "");
} while (current !== previous);

return current;
}

type Highlighter = HighlighterGeneric<string, string>;
Copilot is powered by AI and may make mistakes. Always verify output.
const EVENT_HANDLER_RE = /\s+on\w+\s*=\s*["'][^"']*["']/gi;

function sanitize(html: string): string {
return html.replace(DANGEROUS_TAG_RE, "").replace(EVENT_HANDLER_RE, "");

Check failure

Code scanning / CodeQL

Incomplete multi-character sanitization High

This string may still contain
<script
, which may cause an HTML element injection vulnerability.

Copilot Autofix

AI 5 days ago

General fix: Stop relying on a single-pass multi-character regex replacement to enforce HTML safety. Instead, either (a) use a well-tested HTML sanitization library, or (b) make the regex-based approach robust by repeatedly sanitizing until a fixed point is reached so that no newly formed matches remain.

Best fix here without changing existing functionality: Wrap the current two-step .replace chain in a loop that keeps applying the same replacements until they no longer change the string. This preserves the exact semantics of the current regexes (we’re still removing the same patterns in the same way) while addressing the “incomplete multi-character sanitization” concern by eliminating residual dangerous tags or event handlers that might appear after the first pass.

Concretely, in dashboard/src/web/lib/utils/markdown.ts, modify sanitize (lines 7–9). Replace the single return html.replace(...).replace(...); line with a small loop: track the previous value, repeatedly apply .replace(DANGEROUS_TAG_RE, "").replace(EVENT_HANDLER_RE, ""), and stop when the result stops changing. No new imports are required, and the rest of the file remains unchanged. escapeHtml is already only used for code blocks, so it doesn’t need modification.

Suggested changeset 1
dashboard/src/web/lib/utils/markdown.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/dashboard/src/web/lib/utils/markdown.ts b/dashboard/src/web/lib/utils/markdown.ts
--- a/dashboard/src/web/lib/utils/markdown.ts
+++ b/dashboard/src/web/lib/utils/markdown.ts
@@ -5,7 +5,17 @@
 const EVENT_HANDLER_RE = /\s+on\w+\s*=\s*["'][^"']*["']/gi;
 
 function sanitize(html: string): string {
-	return html.replace(DANGEROUS_TAG_RE, "").replace(EVENT_HANDLER_RE, "");
+	let previous: string;
+	let current = html;
+
+	do {
+		previous = current;
+		current = previous
+			.replace(DANGEROUS_TAG_RE, "")
+			.replace(EVENT_HANDLER_RE, "");
+	} while (current !== previous);
+
+	return current;
 }
 
 type Highlighter = HighlighterGeneric<string, string>;
EOF
@@ -5,7 +5,17 @@
const EVENT_HANDLER_RE = /\s+on\w+\s*=\s*["'][^"']*["']/gi;

function sanitize(html: string): string {
return html.replace(DANGEROUS_TAG_RE, "").replace(EVENT_HANDLER_RE, "");
let previous: string;
let current = html;

do {
previous = current;
current = previous
.replace(DANGEROUS_TAG_RE, "")
.replace(EVENT_HANDLER_RE, "");
} while (current !== previous);

return current;
}

type Highlighter = HighlighterGeneric<string, string>;
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant