Skip to content

v1.14.0: Nuclear scope enforcement, plugin overhaul, config externalization#2

Merged
AnExiledDev merged 2 commits intomainfrom
v1.14.0
Feb 24, 2026
Merged

v1.14.0: Nuclear scope enforcement, plugin overhaul, config externalization#2
AnExiledDev merged 2 commits intomainfrom
v1.14.0

Conversation

@AnExiledDev
Copy link
Owner

@AnExiledDev AnExiledDev commented Feb 24, 2026

Summary

  • Nuclear workspace scope enforcement — blacklist system for /workspaces/.devcontainer/, two-layer bash detection (20+ write-target patterns + workspace path scan), fail-closed error handling, CWD context injection via 4 hook events
  • Agent system enhancements — quality gate hooks (TaskCompleted, TeammateIdle), debug skill replacing slash command, permissionMode on all 17 agents
  • Skill engine overhaul — 6 new matchers, team skill v0.2.0, all 21+ skills rewritten with USE WHEN / DO NOT USE guidance
  • Ticket workflow migration — 4 slash commands replaced by skill-based approach
  • Hook output schema migration — all hooks use hookSpecificOutput wrapper; commit-reminder, spec-reminder, advisory-test-runner upgraded to blocking
  • ccstatusline config externalized — widget layout extracted from inline jq -n in install.sh to config/defaults/ccstatusline-settings.json, deployed via file-manifest with if-changed semantics. ${HOME} variable expansion added to setup-config.sh
  • Remote install docs — all 11 plugin READMEs and features README updated with GitHub clone and GHCR installation instructions
  • Documentation site — Astro/Starlight docs portal with plugin reference, feature docs, customization guides
  • Development rules — CLAUDE.md updated to require changelog entries and docs updates for all changes
  • New features — chromaterm (terminal colorizer), kitty-terminfo (Kitty terminal compatibility)
  • Removed — auto-formatter and auto-linter plugins (consolidated into auto-code-quality)

Test plan

  • Container rebuilds successfully with all features
  • ccstatusline config deploys from config/defaults/ to ~/.config/ccstatusline/settings.json
  • Status bar renders correctly after rebuild
  • Workspace scope guard blocks reads/writes outside working directory
  • Workspace scope guard blocks bash commands targeting /workspaces/.devcontainer/
  • Plugin remote install instructions are accurate (clone + enabledPlugins)
  • Docs site builds (cd docs && npm run build)

Summary by CodeRabbit

Release Notes

  • New Features

    • Added ChromaTerm and Kitty terminal support for enhanced terminal compatibility.
    • Introduced quality gates (TeammateIdle, TaskCompleted) for team workflows.
    • Launched documentation portal with comprehensive guides.
  • Changes

    • Reorganized plugins: code-directive replaced by agent-system and skill-engine.
    • Expanded skill catalog from 17 to 21 with enhanced auto-suggestion.
    • Updated Claude Dashboard port to 7847.
    • Enhanced workspace scope enforcement with permanent blacklist for protected paths.
  • Documentation

    • Added extensive docs site covering features, plugins, customization, and architecture.

…fig externalization

Major security hardening, plugin architecture changes, and developer experience improvements:

- Nuclear workspace scope enforcement: blacklist system, two-layer bash detection, fail-closed error handling, CWD context injection
- Agent system: quality gate hooks (TaskCompleted, TeammateIdle), debug skill, permissionMode on all agents
- Skill engine: 6 new matchers, team skill v0.2.0, all skills rewritten with USE WHEN guidance
- Ticket workflow: migrated from slash commands to skill-based approach
- Hook output schema: all hooks migrated to hookSpecificOutput wrapper
- ccstatusline config externalized to .devcontainer/config/defaults/ via file-manifest deployment
- Remote install docs added to all 11 plugin READMEs and features README
- Astro/Starlight documentation site, GitHub Actions, logos
- Development rules added to CLAUDE.md (changelog + docs update requirements)
- Removed auto-formatter and auto-linter plugins (consolidated into auto-code-quality)
@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

Important

Review skipped

Too many files!

This PR contains 184 files, which is 34 over the limit of 150.

📥 Commits

Reviewing files that changed from the base of the PR and between f5e181c and e68327f.

⛔ Files ignored due to path filters (10)
  • docs/package-lock.json is excluded by !**/package-lock.json
  • docs/public/apple-touch-icon.png is excluded by !**/*.png
  • docs/public/favicon.png is excluded by !**/*.png
  • docs/public/favicon.svg is excluded by !**/*.svg
  • docs/public/og-image.png is excluded by !**/*.png
  • docs/src/assets/logo.png is excluded by !**/*.png
  • docs/src/assets/logo.svg is excluded by !**/*.svg
  • logos/CodeForgeLogo.png is excluded by !**/*.png
  • logos/CodeForgeLogoTr.png is excluded by !**/*.png
  • logos/github-avatar.png is excluded by !**/*.png
📒 Files selected for processing (184)
  • .devcontainer/CHANGELOG.md
  • .devcontainer/CLAUDE.md
  • .devcontainer/README.md
  • .devcontainer/config/defaults/ccstatusline-settings.json
  • .devcontainer/config/defaults/main-system-prompt.md
  • .devcontainer/config/defaults/rules/spec-workflow.md
  • .devcontainer/config/file-manifest.json
  • .devcontainer/devcontainer.json
  • .devcontainer/docs/optional-features.md
  • .devcontainer/docs/plugins.md
  • .devcontainer/features/README.md
  • .devcontainer/features/biome/install.sh
  • .devcontainer/features/ccms/install.sh
  • .devcontainer/features/ccstatusline/install.sh
  • .devcontainer/features/chromaterm/README.md
  • .devcontainer/features/chromaterm/chromaterm.yml
  • .devcontainer/features/chromaterm/devcontainer-feature.json
  • .devcontainer/features/chromaterm/install.sh
  • .devcontainer/features/claude-session-dashboard/README.md
  • .devcontainer/features/claude-session-dashboard/devcontainer-feature.json
  • .devcontainer/features/claude-session-dashboard/install.sh
  • .devcontainer/features/kitty-terminfo/README.md
  • .devcontainer/features/kitty-terminfo/devcontainer-feature.json
  • .devcontainer/features/kitty-terminfo/install.sh
  • .devcontainer/features/shellcheck/install.sh
  • .devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json
  • .devcontainer/plugins/devs-marketplace/.gitignore
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/architect.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/bash-exec.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/claude-guide.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/debug-logs.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/dependency-analyst.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/doc-writer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/explorer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/generalist.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/git-archaeologist.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/migrator.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/perf-profiler.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/refactorer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/researcher.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/security-auditor.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/spec-writer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/statusline-config.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/test-writer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/inject-cwd.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/task-completed-check.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/teammate-idle-check.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/verify-no-regression.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/verify-tests-pass.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/skills/debug/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/advisory-test-runner.py
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py
  • .devcontainer/plugins/devs-marketplace/plugins/codeforge-lsp/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py
  • .devcontainer/plugins/devs-marketplace/plugins/notify-hook/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected-bash.py
  • .devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/commit-reminder.py
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/git-state-injector.py
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/todo-harvester.py
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/api-design/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/ast-grep-patterns/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-agent-sdk/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-code-headless/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/debugging/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/dependency-management/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/docker-py/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/docker/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/documentation-patterns/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/fastapi/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/git-forensics/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/migration-patterns/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/performance-profiling/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/pydantic-ai/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/refactoring-patterns/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/security-checklist/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/skill-building/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/sqlite/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/svelte5/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/team/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/testing/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/scripts/spec-reminder.py
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-build/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-check/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-init/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-new/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-refine/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-review/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-update/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/specification-writing/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/system-prompt.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/scripts/ticket-linker.py
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/skills/ticketcreate-pr/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/skills/ticketnew/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/skills/ticketreview-commit/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/skills/ticketwork/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py
  • .devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/inject-workspace-cwd.py
  • .devcontainer/scripts/setup-aliases.sh
  • .devcontainer/scripts/setup-config.sh
  • .github/workflows/deploy-docs.yml
  • .github/workflows/docs-ci.yml
  • .github/workflows/publish-features.yml
  • .github/workflows/release.yml
  • .gitignore
  • .npmignore
  • CLAUDE.md
  • README.md
  • docs/astro.config.mjs
  • docs/package.json
  • docs/scripts/sync-changelog.mjs
  • docs/src/components/FeatureCard.astro
  • docs/src/components/Header.astro
  • docs/src/components/Hero.astro
  • docs/src/components/InstallCommand.astro
  • docs/src/content.config.ts
  • docs/src/content/docs/customization/configuration.md
  • docs/src/content/docs/customization/hooks.md
  • docs/src/content/docs/customization/index.md
  • docs/src/content/docs/customization/rules.md
  • docs/src/content/docs/customization/system-prompts.md
  • docs/src/content/docs/features/agents.md
  • docs/src/content/docs/features/code-intelligence.md
  • docs/src/content/docs/features/index.md
  • docs/src/content/docs/features/skills.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/getting-started/requirements.md
  • docs/src/content/docs/index.mdx
  • docs/src/content/docs/plugins/agent-system.md
  • docs/src/content/docs/plugins/auto-code-quality.md
  • docs/src/content/docs/plugins/codeforge-lsp.md
  • docs/src/content/docs/plugins/dangerous-command-blocker.md
  • docs/src/content/docs/plugins/frontend-design.md
  • docs/src/content/docs/plugins/index.md
  • docs/src/content/docs/plugins/notify-hook.md
  • docs/src/content/docs/plugins/protected-files-guard.md
  • docs/src/content/docs/plugins/session-context.md
  • docs/src/content/docs/plugins/skill-engine.md
  • docs/src/content/docs/plugins/spec-workflow.md
  • docs/src/content/docs/plugins/ticket-workflow.md
  • docs/src/content/docs/plugins/workspace-scope-guard.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/environment.md
  • docs/src/content/docs/reference/index.md
  • docs/src/styles/global.css
  • docs/tsconfig.json
  • package.json
  • setup.js

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
  • Post copyable unit tests in a comment
  • Commit unit tests in branch v1.14.0

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (21)
.devcontainer/features/ccms/install.sh (1)

56-64: ⚠️ Potential issue | 🔴 Critical

Avoid predictable /tmp cache paths to prevent binary injection.

/tmp is world-writable; with a fixed path, an attacker can pre-place ${CACHE_DIR}/ccms, and this script (typically running as root) will copy it into /usr/local/bin. Use a unique mktemp -d (and clean it up) or enforce strict ownership/permissions checks before trusting the cache.

🔒 Safer per-run cache directory + cleanup
- CACHE_DIR="${TMPDIR:-/tmp}/ccms-build-cache"
+ CACHE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/ccms-build-cache.XXXXXX")"
 cleanup() {
-    :
+    if [ -n "${CACHE_DIR:-}" ] && [ -d "${CACHE_DIR}" ]; then
+        rm -rf "${CACHE_DIR}"
+    fi
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/features/ccms/install.sh around lines 56 - 64, The current
CACHE_DIR value (CACHE_DIR="${TMPDIR:-/tmp}/ccms") is predictable and allows
TOCTOU/binary injection; change the install logic in
.devcontainer/features/ccms/install.sh so you either (a) create a per-run secure
temp dir with mktemp -d and use that instead of CACHE_DIR, cleaning it up after
use, or (b) if reusing a cache path, validate ownership and mode before trusting
the file (check that "${CACHE_DIR}/ccms" is owned by root or expected user and
is not writable by others and is a regular file) before copying to
/usr/local/bin/ccms; update the code paths that reference CACHE_DIR and the
conditional that tests -x "${CACHE_DIR}/ccms" accordingly.
.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/api-design/SKILL.md (1)

68-68: ⚠️ Potential issue | 🟡 Minor

OPTIONS success code should be 200, not 204

RFC 7231 §4.3.7 defines a successful OPTIONS response as 200 OK, with the response body or Allow header communicating server capabilities. 204 implies no content, which conflicts with the spec-defined purpose of OPTIONS (returning capability information).

🛠️ Proposed fix
-| **OPTIONS** | Describe capabilities | Yes | No | 204 |
+| **OPTIONS** | Describe capabilities | Yes | No | 200 |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/api-design/SKILL.md
at line 68, Update the OPTIONS success status in the SKILL.md table row that
starts with "**OPTIONS**" and description "Describe capabilities" from 204 to
200; edit the table cell containing "204" to "200" so the documented successful
OPTIONS response matches RFC 7231 §4.3.7.
.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/migration-patterns/SKILL.md (1)

89-94: ⚠️ Potential issue | 🟡 Minor

"Never fix forward" is too absolute for database/data migrations.

This rule is correct for code changes but conflicts with real-world database migrations where the down-migration may be destructive (e.g., a DROP COLUMN rollback would lose data). The Rollback Strategy section (Line 102) already acknowledges down-migrations, but it doesn't resolve the tension — an agent following both sections will receive contradictory guidance in exactly the scenarios where it matters most.

Consider scoping the rule:

📝 Suggested wording
-4. Never fix forward by making changes intended for later steps.
+4. Never fix forward by making changes intended for later steps. Exception: for
+   deployed database/data migrations where rollback would cause data loss, fix
+   forward with a corrective migration and document the deviation.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/migration-patterns/SKILL.md
around lines 89 - 94, Update the "Never fix forward" rule in SKILL.md so it is
scoped for database/data migrations: change the absolute prohibition to a
conditional guideline that allows forward-fixing only when a down-migration is
destructive or unsafe (e.g., DROP COLUMN), and require explicit steps when doing
so — document the decision, create backups/snapshots, obtain stakeholder/owner
approval, run in a controlled maintenance window, and record the migration plan
and post-checks; also add a cross-reference to the existing "Rollback Strategy"
section to reconcile the guidance and make the expected decision flow
deterministic for agents.
.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/git-forensics/SKILL.md (1)

107-110: ⚠️ Potential issue | 🟡 Minor

Misleading comment: git log --follow -p is not git blame

Line 109's comment # Blame through renames is inaccurate — the command is git log, which produces commit/patch history, not per-line attribution. git blame has no --follow flag. Readers looking for blame-style output will be confused.

📝 Proposed fix
-# Blame through renames
-git log --follow -p -- path/to/file.py
+# Show patch history of a file through renames
+git log --follow -p -- path/to/file.py
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/git-forensics/SKILL.md
around lines 107 - 110, The comment "# Blame through renames" is incorrect for
the command shown; update the text around the command "git log --follow -p --
path/to/file.py" to say it shows commit/patch history through renames (not
per-line blame), and remove or replace any instruction implying git blame
supports --follow; if you want per-line attribution suggest using "git blame"
separately or note that git blame does not have --follow and that rename/copy
detection must be handled via heuristics (e.g., use "git blame -C -M" or use
"git log --follow -p" for history).
setup.js (1)

9-15: ⚠️ Potential issue | 🟠 Major

Add config/defaults/ccstatusline-settings.json to DEFAULT_PRESERVE.

The file is documented as user-customizable ("edit .devcontainer/config/defaults/ccstatusline-settings.json"), but currently lacks source-level protection during package updates. The file-manifest's if-changed semantics protect only the deployed destination (~/.config/ccstatusline/settings.json), not the source file in the package. During a --force update, user edits to the source will be lost. Since other customizable files like settings.json, main-system-prompt.md, and keybindings.json are all protected in DEFAULT_PRESERVE, ccstatusline-settings.json should be added alongside them.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup.js` around lines 9 - 15, DEFAULT_PRESERVE does not include
"config/defaults/ccstatusline-settings.json", so package updates with --force
can overwrite user-edited source defaults; update the DEFAULT_PRESERVE array
constant to add "config/defaults/ccstatusline-settings.json" alongside the other
preserved files (e.g., "config/defaults/settings.json",
"config/defaults/main-system-prompt.md", "config/defaults/keybindings.json") so
the source file is protected during updates.
.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-agent-sdk/SKILL.md (3)

365-376: ⚠️ Potential issue | 🟡 Minor

forkSession is absent from the Key Options Fields table.

forkSession: true is introduced only in this example but is not listed in the options table at lines 93–110. Readers (and AI agents) treating that table as the canonical reference will have no knowledge of the option.

📋 Suggested table addition
 | `resume`          | `string`                                          | `undefined`   | Session ID to resume                            |
+| `forkSession`     | `boolean`                                         | `false`       | Preserve context but diverge session history    |
 | `settingSources`  | `SettingSource[]`                                 | `[]`          | Which filesystem settings to load              |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-agent-sdk/SKILL.md
around lines 365 - 376, Add the missing forkSession option to the "Key Options
Fields" table: document the new boolean option forkSession (default false) under
the options object used by query, describe that forkSession: true creates a new
session ID while inheriting conversation context from options.resume/sessionId
(i.e., forks the conversation), and include expected type, default, and a short
example reference to where it's used in the query(...) for clarity.

258-271: ⚠️ Potential issue | 🟡 Minor

"Read-Only Agent Pattern" should use plan mode, not bypassPermissions.

The document's own permissions table (line 210) defines 'plan' as "Planning mode — read-only, no execution", which is the purpose-built, safe choice here. Using bypassPermissions + allowDangerouslySkipPermissions: true skips all permission checks and requires a dangerous opt-in flag — if the allowedTools list ever drifts to include a write-capable tool, there is no safety net. Because AI agents consuming this skill will treat this example as the canonical read-only pattern, the weaker choice will propagate.

🛡️ Proposed fix
-for await (const message of query({
-  prompt: "Review this code for best practices",
-  options: {
-    allowedTools: ["Read", "Glob", "Grep"],
-    permissionMode: "bypassPermissions",
-    allowDangerouslySkipPermissions: true,
-  },
-})) {
+for await (const message of query({
+  prompt: "Review this code for best practices",
+  options: {
+    allowedTools: ["Read", "Glob", "Grep"],
+    permissionMode: "plan",
+  },
+})) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-agent-sdk/SKILL.md
around lines 258 - 271, The example using query(...) with options currently sets
permissionMode to "bypassPermissions" and allowDangerouslySkipPermissions: true
which is unsafe for a read-only pattern; update the options in the Read-Only
Agent Pattern example to set permissionMode: "plan" (the read-only planning
mode) and remove allowDangerouslySkipPermissions (and any bypass usage), keeping
allowedTools: ["Read","Glob","Grep"] intact so the example enforces safe
read-only behavior; locate the example by the query(...) call in the SKILL.md
snippet.

439-451: ⚠️ Potential issue | 🟡 Minor

Overly narrow regex in blockDestructive hook creates false security.

/rm\s+-rf\s+\//.test(cmd) requires a space + / immediately after the flags, blocking only absolute-path patterns like rm -rf /tmp/…. It silently passes rm -rf ./important-dir, rm -rf ~/data, rm -rf some-dir, and flag variants like rm -rfd …. The canUseTool example earlier (line 234) correctly uses the broader /rm\s+-rf/.test(...). Readers copying the hook example for real protection will be left with a gap.

🛡️ Proposed fix
-  if (/rm\s+-rf\s+\//.test(cmd)) {
+  if (/rm\s+-rf/.test(cmd)) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-agent-sdk/SKILL.md
around lines 439 - 451, The current blockDestructive HookCallback uses a
too-narrow regex (/rm\s+-rf\s+\//) to detect destructive rm invocations; update
the detection in the blockDestructive hook (inspect the cmd variable inside
blockDestructive) to use a broader pattern that matches rm followed by -rf (and
flag permutations like -rfd) anywhere after the command (not requiring an
immediate '/'), e.g., replace the regex check with one that looks for "rm"
followed by whitespace and a flag token containing both r and f (or simply
/rm\s+-?[^ ]*r[^ ]*f|rm\s+-?[^ ]*f[^ ]*r/ or the simpler /rm\s+-rf/ style used
elsewhere), so it also catches forms like "rm -rf.", "rm -rfd", "rm -rf
some-dir", and "rm -rf ~/path".
.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/sqlite/SKILL.md (4)

288-300: ⚠️ Potential issue | 🟡 Minor

Cloudflare D1 example references undeclared variables email, now, and userId.

All three variables are used without being extracted from request or declared anywhere in scope. Since this SKILL.md drives AI code generation, incomplete examples risk propagating the same undefined-variable pattern into real codebases.

📝 Suggested fix (illustrative extraction)
 export default {
   async fetch(request, env) {
+    const url = new URL(request.url);
+    const email = url.searchParams.get("email");
+    const { userId } = await request.json();
+    const now = new Date().toISOString();
+
     const { results } = await env.DB.prepare(
       "SELECT * FROM users WHERE email = ?"
     ).bind(email).all();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/sqlite/SKILL.md
around lines 288 - 300, The example fetch handler uses undeclared variables
(email, now, userId) causing runtime errors; update the fetch function to
extract/compute these values before using them (e.g., parse email from
request.body or request.query and compute now and userId from request or DB
lookup) and then pass them into env.DB.prepare(...).bind(...).all() and into the
batch statements so that email, now, and userId are defined in the scope of
fetch when calling env.DB.prepare, env.DB.batch, and Response.json.

288-300: ⚠️ Potential issue | 🟡 Minor

D1 example references undeclared variables email, now, and userId.

The Cloudflare D1 snippet uses three variables that are never extracted from request or declared anywhere, leaving the example non-functional as written. Since this SKILL.md drives AI code generation, incomplete examples risk propagating the same pattern.

📝 Proposed fix (illustrative extraction)
 export default {
   async fetch(request, env) {
+    const { searchParams } = new URL(request.url);
+    const email = searchParams.get("email");
+    const { userId } = await request.json();
+    const now = new Date().toISOString();
+
     const { results } = await env.DB.prepare(
       "SELECT * FROM users WHERE email = ?"
     ).bind(email).all();

     // Batch multiple statements in one round-trip
     const batch = await env.DB.batch([
       env.DB.prepare("INSERT INTO logs (action) VALUES (?)").bind("login"),
       env.DB.prepare("UPDATE users SET last_login = ? WHERE id = ?").bind(now, userId),
     ]);

     return Response.json(results);
   },
 };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/sqlite/SKILL.md
around lines 288 - 300, The example in export default's async fetch uses
undeclared variables email, now, and userId; fix by extracting/declaring them
before use (e.g., parse request body or URL params to obtain email and userId,
and compute now via Date.now() or new Date()), then pass those variables into
env.DB.prepare(...).bind(...) and into the batch calls so env.DB.prepare, fetch,
and batch references are valid and the example is functional.

28-28: ⚠️ Potential issue | 🟡 Minor

Version baseline of 3.35 does not include STRICT tables — that requires 3.37.

STRICT table support was added in SQLite 3.37.0 (2021-11-27), two minor releases after 3.35. The body of the skill uses STRICT on every schema example, so the stated minimum is understated by two releases and could cause confusion or silent failures for developers targeting 3.35/3.36.

📝 Proposed fix
-Assume SQLite 3.35+ (2021) for all new code, which includes `RETURNING`, `INSERT ... ON CONFLICT`, and `STRICT` tables.
+Assume SQLite 3.37+ (2021) for all new code, which includes `RETURNING`, `INSERT ... ON CONFLICT`, and `STRICT` tables.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/sqlite/SKILL.md
at line 28, The README incorrectly states the baseline as "SQLite 3.35+" while
the examples use STRICT tables; update the version baseline to at least 3.37.0
(2021-11-27) in SKILL.md so the line "Assume SQLite 3.35+ ..." reads "Assume
SQLite 3.37+ ..." (or explicitly call out that STRICT requires 3.37) and ensure
any mentions of schema examples using the STRICT keyword are annotated to
require 3.37+.

28-28: ⚠️ Potential issue | 🟡 Minor

Incorrect SQLite version baseline — STRICT tables require 3.37, not 3.35.

Line 28 claims the 3.35+ baseline "includes … STRICT tables," but STRICT table support was introduced in SQLite 3.37.0 (2021-11-27), two releases after 3.35. Since the body of the skill relies heavily on STRICT (every schema example uses it), the minimum version stated here understates the actual requirement.

📝 Proposed fix
-Assume SQLite 3.35+ (2021) for all new code, which includes `RETURNING`, `INSERT ... ON CONFLICT`, and `STRICT` tables.
+Assume SQLite 3.37+ (2021) for all new code, which includes `RETURNING`, `INSERT ... ON CONFLICT`, and `STRICT` tables.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/sqlite/SKILL.md
at line 28, Update the documented SQLite baseline version to accurately reflect
the requirement for STRICT tables: change the sentence that reads "Assume SQLite
3.35+ (2021) for all new code, which includes `RETURNING`, `INSERT ... ON
CONFLICT`, and `STRICT` tables." to state SQLite 3.37+ (2021-11-27) as the
minimum, or otherwise call out that `STRICT` requires 3.37 while `RETURNING` and
`INSERT ... ON CONFLICT` are available earlier; ensure the reference to `STRICT`
in the SKILL.md content is consistent with the new minimum.
.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/commit-reminder.py (1)

3-11: ⚠️ Potential issue | 🟡 Minor

Update docstring to match blocking output.
The description still mentions additionalContext even though the hook now emits a block decision.

Suggested fix
-On Stop, checks for uncommitted changes (staged + unstaged) and injects
-an advisory reminder as additionalContext. Claude sees it and can
-naturally ask the user if they want to commit.
+On Stop, checks for uncommitted changes (staged + unstaged) and blocks
+with a decision/reason message so Claude addresses them before finishing.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/commit-reminder.py
around lines 3 - 11, Update the module docstring in commit-reminder.py to
reflect that the stop hook emits a blocking JSON decision (including "decision"
and "reason") instead of injecting "additionalContext"; mention that it reads
hook input from stdin (JSON), writes a blocking decision JSON to stdout, and
respects the stop_hook_active guard to avoid loops (referencing
stop_hook_active). Ensure the docstring language around "On Stop" and the output
format matches the current behavior (blocking decision/reason) and remove or
replace references to "additionalContext".
.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/team/SKILL.md (1)

55-63: ⚠️ Potential issue | 🟡 Minor

Immediate Mode steps omit plan approval — agent will be surprised by it mid-execution.

The 7-step Immediate Mode checklist (lines 57–63) skips plan approval entirely. When CLAUDE_CODE_PLAN_MODE_REQUIRED is true, an agent following these steps will encounter a plan_approval_request with no prior guidance in the section it's operating from. Section 5a is only discoverable in the Team Lifecycle section, which comes later in the document.

Consider adding a note under step 4 (Spawn teammates) or step 6 (Coordinate) pointing to the Plan Approval sub-flow.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/team/SKILL.md
around lines 55 - 63, The Immediate Mode checklist (steps using TeamCreate,
TaskCreate, TaskUpdate, Task, TaskList, SendMessage, shutdown_request,
TeamDelete) omits guidance about handling the plan_approval_request when
CLAUDE_CODE_PLAN_MODE_REQUIRED is true; add a brief note under step 4 (Spawn
teammates) or step 6 (Coordinate) that instructs agents to consult the Plan
Approval sub-flow (referencing Section 5a / Team Lifecycle) before spawning or
coordinating teammates and to await or trigger plan_approval_request handling as
required by CLAUDE_CODE_PLAN_MODE_REQUIRED so the agent won’t be surprised
mid-execution.
.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/verify-tests-pass.py (1)

8-9: ⚠️ Potential issue | 🟡 Minor

Module docstring is stale after the stdout → stderr migration.

Line 8 still says "Reads hook input from stdin (JSON). Returns JSON on stdout." but the script no longer writes anything to stdout — failures now go to stderr (plain text), and success produces no output at all.

📝 Proposed fix
-Reads hook input from stdin (JSON). Returns JSON on stdout.
-Non-blocking on detection failures: always exits 0 if no framework found.
+Reads hook input from stdin (JSON). Signals failure via stderr (plain text).
+Non-blocking on detection failures: always exits 0 if no framework found.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/verify-tests-pass.py
around lines 8 - 9, Update the module docstring that currently reads "Reads hook
input from stdin (JSON). Returns JSON on stdout." to reflect the current
behavior: it reads JSON from stdin, produces no stdout on success, writes
human-readable failure messages to stderr, and exits 0 when no framework is
detected (non-blocking on detection failures); locate and edit the top-level
module docstring string to replace the stale sentence with this accurate
description.
.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/README.md (1)

82-95: ⚠️ Potential issue | 🟠 Major

Update the hook lifecycle diagram and Plugin Structure section to include advisory-test-runner.py.

The advisory-test-runner.py script exists in the plugin and is registered in hooks.json to run after lint-file.py on the Stop event, but both the hook lifecycle diagram (lines 82–95) and the Plugin Structure tree (lines 127–139) in the README are missing it.

Hook lifecycle diagram should show advisory-test-runner.py as a third command in the Stop event after lint-file.py.

Plugin Structure should add advisory-test-runner.py to the scripts/ list.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/README.md
around lines 82 - 95, Update the README's hook lifecycle diagram to include
advisory-test-runner.py as the third command under the Stop event after
lint-file.py (so the Stop event shows format-on-stop.py, lint-file.py,
advisory-test-runner.py), and update the Plugin Structure tree to add
advisory-test-runner.py to the scripts/ list; verify this matches the hooks.json
registration for advisory-test-runner.py so the diagram and structure reflect
the actual hook order and presence.
.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py (1)

202-333: ⚠️ Potential issue | 🔴 Critical

Prevent ~ / env-var path expansion from bypassing scope checks.

Write targets and tool paths are resolved with realpath() directly. In Bash, ~/... and $HOME/... expand before execution, but your guard treats them as literals and may allow out-of-scope writes. This is a bypass of the scope guard.

Proposed fix
+def resolve_path(raw_path: str, cwd: str) -> str:
+    """Expand ~ and env vars, then resolve against cwd."""
+    expanded = os.path.expandvars(os.path.expanduser(raw_path))
+    if not os.path.isabs(expanded):
+        expanded = os.path.join(cwd, expanded)
+    return os.path.realpath(expanded)
-        resolved = os.path.realpath(target.strip("'\""))
+        resolved = resolve_path(target.strip("'\""), cwd)
-        resolved = os.path.realpath(path_str)
+        resolved = resolve_path(path_str, cwd)
-    resolved = os.path.realpath(target_path)
+    resolved = resolve_path(target_path, cwd)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py
around lines 202 - 333, The guard currently calls os.path.realpath() directly
and thus misses shell-style expansions (~/ and $VAR), allowing bypass; update
check_bash_scope and main path handling to first run os.path.expanduser() and
os.path.expandvars() on every path string before calling os.path.realpath():
apply this to entries in write_targets and workspace_paths in check_bash_scope
(the resolved and resolved_targets calculations) and to target_path resolution
in main (the resolved = ... assignment after get_target_path), ensuring all
places that call realpath use expanded strings so ~ and env vars are correctly
resolved prior to blacklist/scope/allowlist checks.
.devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py (1)

449-480: ⚠️ Potential issue | 🟠 Major

Hook event name should reflect the actual trigger.

If this script is still invoked for SubagentStart, always emitting hookEventName: "UserPromptSubmit" can cause the hook output to be ignored or misrouted. Set the event name based on the input shape.

Proposed fix
-    output = {
+    event_name = "SubagentStart" if "subagent_type" in data else "UserPromptSubmit"
+    output = {
         "hookSpecificOutput": {
-            "hookEventName": "UserPromptSubmit",
+            "hookEventName": event_name,
             "additionalContext": (
                 f"MANDATORY — Skill activation required. The user's prompt matches: {skill_list}. "
                 f"Before responding, evaluate each matched skill: is it relevant to this specific request? "
                 f"For each relevant skill, activate it using the Skill tool NOW. "
                 f"Skip any that are not relevant to the user's actual intent. "
                 f"Do not proceed with implementation until relevant skills are loaded."
             ),
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py
around lines 449 - 480, The code always sets hookEventName to "UserPromptSubmit"
in main() which mislabels events when the script is invoked for other triggers
(e.g., SubagentStart); change main() to derive the event name from the incoming
payload (inspect keys such as "event", "hookEventName", "trigger", or a
"type"/"name" field on the parsed data) and use that value for
output["hookSpecificOutput"]["hookEventName"], falling back to
"UserPromptSubmit" only if no recognizable event field exists; update the
creation of output (the hookEventName assignment) so the emitted hook matches
the actual input trigger.
.devcontainer/features/ccstatusline/install.sh (1)

205-223: ⚠️ Potential issue | 🟡 Minor

Make the jq pipeline failure path actually reachable under set -euo pipefail.

As written, a pipeline failure exits before the $? check, so cleanup and the explicit error message may not run. Wrap the pipeline in an if block to handle failure cleanly.

Proposed fix
-jq '.statusLine //= {}' "${SETTINGS_FILE}" | \
-jq '.statusLine = {
-    type: "command",
-    command: "/usr/local/bin/ccstatusline-wrapper"
-}' > "${SETTINGS_FILE}.tmp"
-
-# Atomic move (only if jq succeeded)
-if [ $? -eq 0 ]; then
+if jq '.statusLine //= {}' "${SETTINGS_FILE}" | \
+   jq '.statusLine = {
+       type: "command",
+       command: "/usr/local/bin/ccstatusline-wrapper"
+   }' > "${SETTINGS_FILE}.tmp"; then
     mv "${SETTINGS_FILE}.tmp" "${SETTINGS_FILE}"
     if ! chown "${USERNAME}:${USERNAME}" "${SETTINGS_FILE}" 2>/dev/null; then
         echo "[ccstatusline] WARNING: Could not set ownership on ${SETTINGS_FILE}"
     fi
     echo "[ccstatusline] ✓ Configured in ${SETTINGS_FILE}"
     echo "[ccstatusline] Verify: cat ${SETTINGS_FILE} | jq '.statusLine'"
 else
     rm -f "${SETTINGS_FILE}.tmp"
     echo "[ccstatusline] ERROR: Configuration failed"
     exit 1
 fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/features/ccstatusline/install.sh around lines 205 - 223, The
jq pipeline that writes to "${SETTINGS_FILE}.tmp" can fail under set -euo
pipefail before the subsequent $? check; change it to an explicit conditional:
run the pipeline inside an if ... then ... else ... fi so success proceeds to
mv, chown and success messages and failure runs rm -f "${SETTINGS_FILE}.tmp" and
prints the ERROR message and exits non‑zero. Refer to the existing pipeline that
uses jq '.statusLine //= {}' and jq '.statusLine = { type: "command", command:
"/usr/local/bin/ccstatusline-wrapper" }' writing to "${SETTINGS_FILE}.tmp", and
preserve the atomic mv of "${SETTINGS_FILE}.tmp" to "${SETTINGS_FILE}" and the
chown/echo logic that references SETTINGS_FILE and USERNAME.
.devcontainer/docs/plugins.md (2)

172-175: ⚠️ Potential issue | 🟠 Major

workspace-scope-guard description is stale — reads are now blocked, not warned.

This description was written for the pre-v1.14.0 behavior. The v1.14.0 changelog explicitly states: "Reads (Read, Glob, Grep) now hard-blocked outside scope — upgraded from warning (exit 0) to block (exit 2)".

📝 Proposed fix
-**Purpose**: Enforces workspace scope by blocking writes outside the working directory and warning on out-of-scope reads.
-
-Runs as a PreToolUse hook on Write, Edit, and Read operations. Compares file paths against the current working directory and rejects modifications to files outside the project scope. Read operations outside scope produce a warning but are not blocked. Resolves symlinks and worktree paths correctly via `os.path.realpath()`.
+**Purpose**: Nuclear workspace scope enforcement — blocks ALL operations (read, write, bash) outside the current project directory. Permanently blacklists `/workspaces/.devcontainer/`.
+
+Runs as a PreToolUse hook on Write, Edit, Read, Glob, Grep, and Bash operations. All out-of-scope operations are hard-blocked (exit 2). Includes two-layer Bash enforcement and CWD context injection across four hook events.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/docs/plugins.md around lines 172 - 175, Update the
"workspace-scope-guard" plugin description to reflect current behavior: replace
the claim that it "warn[s] on out-of-scope reads" with a statement that reads
(Read, Glob, Grep) are now hard-blocked (exit 2) outside the workspace scope;
reference the plugin name "workspace-scope-guard" and the changelog note about
v1.14.0 when updating the Purpose text so it accurately states that both writes
and reads are blocked outside the working directory.

46-49: ⚠️ Potential issue | 🟡 Minor

Stale auto-linter reference in PLUGIN_BLACKLIST example.

auto-linter was deleted in this PR (consolidated into auto-code-quality). The example should reference a plugin that still exists.

📝 Proposed fix
-PLUGIN_BLACKLIST="ticket-workflow,auto-linter"
+PLUGIN_BLACKLIST="ticket-workflow,notify-hook"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/docs/plugins.md around lines 46 - 49, Update the example
PLUGIN_BLACKLIST string so it no longer references the removed "auto-linter"
plugin: locate the sample value PLUGIN_BLACKLIST="ticket-workflow,auto-linter"
and replace "auto-linter" with the consolidated plugin name "auto-code-quality"
(or another currently supported plugin), ensuring the example reflects existing
plugins.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f5e181c and 2c26e3e.

⛔ Files ignored due to path filters (10)
  • docs/package-lock.json is excluded by !**/package-lock.json
  • docs/public/apple-touch-icon.png is excluded by !**/*.png
  • docs/public/favicon.png is excluded by !**/*.png
  • docs/public/favicon.svg is excluded by !**/*.svg
  • docs/public/og-image.png is excluded by !**/*.png
  • docs/src/assets/logo.png is excluded by !**/*.png
  • docs/src/assets/logo.svg is excluded by !**/*.svg
  • logos/CodeForgeLogo.png is excluded by !**/*.png
  • logos/CodeForgeLogoTr.png is excluded by !**/*.png
  • logos/github-avatar.png is excluded by !**/*.png
📒 Files selected for processing (184)
  • .devcontainer/CHANGELOG.md
  • .devcontainer/CLAUDE.md
  • .devcontainer/README.md
  • .devcontainer/config/defaults/ccstatusline-settings.json
  • .devcontainer/config/defaults/main-system-prompt.md
  • .devcontainer/config/defaults/rules/spec-workflow.md
  • .devcontainer/config/file-manifest.json
  • .devcontainer/devcontainer.json
  • .devcontainer/docs/optional-features.md
  • .devcontainer/docs/plugins.md
  • .devcontainer/features/README.md
  • .devcontainer/features/biome/install.sh
  • .devcontainer/features/ccms/install.sh
  • .devcontainer/features/ccstatusline/install.sh
  • .devcontainer/features/chromaterm/README.md
  • .devcontainer/features/chromaterm/chromaterm.yml
  • .devcontainer/features/chromaterm/devcontainer-feature.json
  • .devcontainer/features/chromaterm/install.sh
  • .devcontainer/features/claude-session-dashboard/README.md
  • .devcontainer/features/claude-session-dashboard/devcontainer-feature.json
  • .devcontainer/features/claude-session-dashboard/install.sh
  • .devcontainer/features/kitty-terminfo/README.md
  • .devcontainer/features/kitty-terminfo/devcontainer-feature.json
  • .devcontainer/features/kitty-terminfo/install.sh
  • .devcontainer/features/shellcheck/install.sh
  • .devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json
  • .devcontainer/plugins/devs-marketplace/.gitignore
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/architect.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/bash-exec.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/claude-guide.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/debug-logs.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/dependency-analyst.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/doc-writer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/explorer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/generalist.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/git-archaeologist.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/migrator.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/perf-profiler.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/refactorer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/researcher.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/security-auditor.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/spec-writer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/statusline-config.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/test-writer.md
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/inject-cwd.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/task-completed-check.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/teammate-idle-check.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/verify-no-regression.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/verify-tests-pass.py
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/skills/debug/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/advisory-test-runner.py
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py
  • .devcontainer/plugins/devs-marketplace/plugins/codeforge-lsp/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py
  • .devcontainer/plugins/devs-marketplace/plugins/notify-hook/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected-bash.py
  • .devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/commit-reminder.py
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/git-state-injector.py
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/todo-harvester.py
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/api-design/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/ast-grep-patterns/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-agent-sdk/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-code-headless/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/debugging/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/dependency-management/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/docker-py/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/docker/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/documentation-patterns/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/fastapi/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/git-forensics/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/migration-patterns/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/performance-profiling/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/pydantic-ai/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/refactoring-patterns/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/security-checklist/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/skill-building/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/sqlite/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/svelte5/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/team/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/testing/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/scripts/spec-reminder.py
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-build/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-check/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-init/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-new/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-refine/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-review/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-update/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/specification-writing/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/system-prompt.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/scripts/ticket-linker.py
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/skills/ticketcreate-pr/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/skills/ticketnew/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/skills/ticketreview-commit/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/skills/ticketwork/SKILL.md
  • .devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py
  • .devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/inject-workspace-cwd.py
  • .devcontainer/scripts/setup-aliases.sh
  • .devcontainer/scripts/setup-config.sh
  • .github/workflows/deploy-docs.yml
  • .github/workflows/docs-ci.yml
  • .github/workflows/publish-features.yml
  • .github/workflows/release.yml
  • .gitignore
  • .npmignore
  • CLAUDE.md
  • README.md
  • docs/astro.config.mjs
  • docs/package.json
  • docs/scripts/sync-changelog.mjs
  • docs/src/components/FeatureCard.astro
  • docs/src/components/Header.astro
  • docs/src/components/Hero.astro
  • docs/src/components/InstallCommand.astro
  • docs/src/content.config.ts
  • docs/src/content/docs/customization/configuration.md
  • docs/src/content/docs/customization/hooks.md
  • docs/src/content/docs/customization/index.md
  • docs/src/content/docs/customization/rules.md
  • docs/src/content/docs/customization/system-prompts.md
  • docs/src/content/docs/features/agents.md
  • docs/src/content/docs/features/code-intelligence.md
  • docs/src/content/docs/features/index.md
  • docs/src/content/docs/features/skills.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/getting-started/requirements.md
  • docs/src/content/docs/index.mdx
  • docs/src/content/docs/plugins/agent-system.md
  • docs/src/content/docs/plugins/auto-code-quality.md
  • docs/src/content/docs/plugins/codeforge-lsp.md
  • docs/src/content/docs/plugins/dangerous-command-blocker.md
  • docs/src/content/docs/plugins/frontend-design.md
  • docs/src/content/docs/plugins/index.md
  • docs/src/content/docs/plugins/notify-hook.md
  • docs/src/content/docs/plugins/protected-files-guard.md
  • docs/src/content/docs/plugins/session-context.md
  • docs/src/content/docs/plugins/skill-engine.md
  • docs/src/content/docs/plugins/spec-workflow.md
  • docs/src/content/docs/plugins/ticket-workflow.md
  • docs/src/content/docs/plugins/workspace-scope-guard.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/environment.md
  • docs/src/content/docs/reference/index.md
  • docs/src/styles/global.css
  • docs/tsconfig.json
  • package.json
  • setup.js
💤 Files with no reviewable changes (18)
  • .devcontainer/docs/optional-features.md
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/system-prompt.md
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/agent-system/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py
  • .devcontainer/plugins/devs-marketplace/plugins/skill-engine/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/session-context/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/README.md
  • .devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/spec-workflow/hooks/hooks.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json
  • .devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json

Comment on lines 16 to 18
if [ -f /usr/local/share/nvm/nvm.sh ]; then
source /usr/local/share/nvm/nvm.sh
fi
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

nvm.sh unbound variable set -u nounset bash compatibility issue

💡 Result:

When you source nvm.sh in a Bash session/script that has set -u / set -o nounset enabled, any reference inside nvm.sh to an unset variable can abort with unbound variable. A known example in nvm.sh was checking mirrors like NVM_IOJS_ORG_MIRROR using "$VAR" instead of a nounset-safe expansion; it was fixed by switching to ${VAR-} (treat unset as empty). [1]

Fix options

  1. Upgrade nvm
    If you’re on an older nvm release, update to a version that includes the nounset fix(es). (The fix pattern is shown in the referenced commit.) [1]

  2. Temporarily disable nounset just for sourcing nvm.sh (common workaround)

set +u
# or: set +o nounset
. "$NVM_DIR/nvm.sh"
set -u

(You can then re-enable nounset for the rest of your script.) This aligns with standard “default/guarded expansion” practices for nounset. [2]

  1. Patch locally (if you must stay pinned)
    Change unsafe tests like:
if [ -z "$NVM_IOJS_ORG_MIRROR" ]; then

to nounset-safe:

if [ -z "${NVM_IOJS_ORG_MIRROR-}" ]; then

This is exactly the fix style used in nvm’s nounset-related change. [1]

Sources: [1] [2]


🏁 Script executed:

head -30 .devcontainer/features/biome/install.sh

Repository: AnExiledDev/CodeForge

Length of output: 772


source nvm.sh under set -u will abort the script with an unbound-variable error

set -euo pipefail at line 2 keeps nounset active for the entire script. NVM's nvm.sh references variables that may be unset during initialization (e.g., NVM_IOJS_ORG_MIRROR, internal intermediaries). With set -u in effect, the first such reference kills the script immediately with a terse shell error—before the npm validation at line 21 ever runs—making the failure hard to diagnose.

Suspend nounset around the source call:

Proposed fix
 if [ -f /usr/local/share/nvm/nvm.sh ]; then
+    set +u
     source /usr/local/share/nvm/nvm.sh
+    set -u
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ -f /usr/local/share/nvm/nvm.sh ]; then
source /usr/local/share/nvm/nvm.sh
fi
if [ -f /usr/local/share/nvm/nvm.sh ]; then
set +u
source /usr/local/share/nvm/nvm.sh
set -u
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/features/biome/install.sh around lines 16 - 18, The script
currently runs with set -euo pipefail (nounset enabled) which causes sourcing
/usr/local/share/nvm/nvm.sh to fail if nvm.sh references unset variables; fix by
temporarily disabling nounset around the source call: before sourcing, run set
+u, then source /usr/local/share/nvm/nvm.sh, then restore nounset with set -u
(keep errexit/pipefail active). Update the block that checks [ -f
/usr/local/share/nvm/nvm.sh ] to use set +u; source ...; set -u so the rest of
the script behavior remains unchanged.

Comment on lines 21 to 29
if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
for u in vscode node codespace; do
if id -u "$u" >/dev/null 2>&1; then
USERNAME="$u"
break
fi
done
USERNAME="${USERNAME:-root}"
fi
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Username auto-detection fails to fall back to root when no candidate user is found.

USERNAME="${USERNAME:-root}" only substitutes when the variable is unset or empty. After the loop, USERNAME is still "automatic" (non-empty), so the :-root expansion is silently skipped. Any subsequent sudo -u "automatic" call will fail with "unknown user".

This matches the canonical pattern used in Microsoft's devcontainer feature scripts: reset the variable to empty before the loop so the fallback works.

🐛 Proposed fix
 if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
+    USERNAME=""
     for u in vscode node codespace; do
         if id -u "$u" >/dev/null 2>&1; then
             USERNAME="$u"
             break
         fi
     done
     USERNAME="${USERNAME:-root}"
 fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
for u in vscode node codespace; do
if id -u "$u" >/dev/null 2>&1; then
USERNAME="$u"
break
fi
done
USERNAME="${USERNAME:-root}"
fi
if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
USERNAME=""
for u in vscode node codespace; do
if id -u "$u" >/dev/null 2>&1; then
USERNAME="$u"
break
fi
done
USERNAME="${USERNAME:-root}"
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/features/chromaterm/install.sh around lines 21 - 29, The
USERNAME auto-detection leaves USERNAME as the literal "auto"/"automatic" so the
fallback USERNAME="${USERNAME:-root}" never triggers; change the block so when
USERNAME is "auto" or "automatic" you first clear/reset USERNAME (e.g.,
USERNAME="") before iterating over candidates (the for u in vscode node
codespace loop) so that if no candidate is found the subsequent
USERNAME="${USERNAME:-root}" correctly falls back to root; update the
conditional branch containing the loop that sets USERNAME to ensure the variable
is emptyed prior to searching.

Comment on lines 603 to 605
if error:
json.dump({"error": error}, sys.stdout)
print(error, file=sys.stderr)
sys.exit(2)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, examine the file to confirm the docstring issue
head -n 620 ".devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py" | tail -n +1 | head -n 30

Repository: AnExiledDev/CodeForge

Length of output: 1094


🏁 Script executed:

# Also check the error path around lines 603-605
sed -n '600,610p' ".devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py"

Repository: AnExiledDev/CodeForge

Length of output: 241


🏁 Script executed:

# Search for Claude Code hook references in the codebase
rg -i "preToolUse|claude.*code.*hook|hookSpecificOutput" --max-count 20

Repository: AnExiledDev/CodeForge

Length of output: 26012


🏁 Script executed:

# Search for how other hooks handle output after the migration
rg -i "hookSpecificOutput" -A 3 -B 3 --max-count 30

Repository: AnExiledDev/CodeForge

Length of output: 14769


🏁 Script executed:

# Check for any hook documentation or integration code
fd -type f -name "*.py" -o -name "*.md" -o -name "*.json" | xargs rg -l "PreToolUse|preToolUse" 2>/dev/null | head -20

Repository: AnExiledDev/CodeForge

Length of output: 1496


🏁 Script executed:

# Find and examine the hooks.json for agent-system to see how guard-readonly-bash is registered
find ".devcontainer/plugins/devs-marketplace/plugins/agent-system" -name "hooks.json" -exec cat -n {} +

Repository: AnExiledDev/CodeForge

Length of output: 1349


🏁 Script executed:

# Check how other blocking PreToolUse hooks format their output (e.g., block-dangerous.py)
cat -n ".devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py" | head -n 100

Repository: AnExiledDev/CodeForge

Length of output: 4216


🏁 Script executed:

# Search for guard-readonly-bash output handling to see if it should emit JSON
rg -A 10 -B 5 "sys.exit\(2\)" ".devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py"

Repository: AnExiledDev/CodeForge

Length of output: 252


🏁 Script executed:

# Search for guard-readonly-bash registration across all hooks.json files
find . -name "hooks.json" -exec rg -l "guard-readonly-bash" {} +

Repository: AnExiledDev/CodeForge

Length of output: 47


🏁 Script executed:

# Check if guard-readonly-bash is mentioned in agent-system plugin documentation
rg -i "guard-readonly-bash" ".devcontainer/plugins/devs-marketplace/plugins/agent-system/" -A 2

Repository: AnExiledDev/CodeForge

Length of output: 4025


🏁 Script executed:

# Examine the complete structure of agent-system to see if it's registered elsewhere
find ".devcontainer/plugins/devs-marketplace/plugins/agent-system" -type f \( -name "*.json" -o -name "*.md" -o -name "*.py" \) | head -20

Repository: AnExiledDev/CodeForge

Length of output: 1703


🏁 Script executed:

# Inspect one of the agent files to see exactly how guard-readonly-bash.py is invoked
sed -n '1,100p' ".devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/security-auditor.md"

Repository: AnExiledDev/CodeForge

Length of output: 5238


🏁 Script executed:

# Look for hook output format documentation in the customization/hooks documentation
cat -n "docs/src/content/docs/customization/hooks.md" | head -n 150

Repository: AnExiledDev/CodeForge

Length of output: 7273


🏁 Script executed:

# Check the exact definition of how PreToolUse hooks should output when blocking
rg -A 15 "PreToolUse.*only" "docs/src/content/docs/customization/hooks.md"

Repository: AnExiledDev/CodeForge

Length of output: 629


🏁 Script executed:

# Check what block-dangerous.py outputs on the blocking path
sed -n '95,150p' ".devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py"

Repository: AnExiledDev/CodeForge

Length of output: 1171


🏁 Script executed:

# Look for the complete hooks.md section on PreToolUse output format and JSON structure
sed -n '150,250p' "docs/src/content/docs/customization/hooks.md"

Repository: AnExiledDev/CodeForge

Length of output: 2524


🏁 Script executed:

# Search for any recent changes to guard-readonly-bash.py to understand the intent of the stderr change
git log --oneline -20 -- ".devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py" 2>/dev/null || echo "Git log not available"

Repository: AnExiledDev/CodeForge

Length of output: 161


Fix the docstring and implement the documented PreToolUse output contract.

Lines 15–17 incorrectly state "Returns JSON on stdout." The actual implementation outputs plain text to stderr. Additionally, the implementation diverges from the documented PreToolUse hook specification: blocking hooks (exit 2) should output JSON to stdout in the format {"decision": "block", "message": "..."}, not plain text to stderr. If Claude Code expects the documented format, the block reason may not reach the user.

📝 Corrected implementation
-Reads tool input from stdin (JSON). Returns JSON on stdout.
-Exit 0: Command is safe (allowed)
-Exit 2: Command would modify state (blocked)
+Reads tool input from stdin (JSON). Returns JSON to stdout on block.
+Exit 0: Command is safe (allowed)
+Exit 2: Command would modify state (blocked) — outputs JSON with block reason

And update the error path to emit JSON as documented:

     if error:
-        print(error, file=sys.stderr)
+        print(json.dumps({"decision": "block", "message": error}))
         sys.exit(2)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py
around lines 603 - 605, Update the docstring around the PreToolUse hook to state
it writes JSON to stdout (not plain text to stderr), and change the error path
where 'error' is handled so it emits the documented JSON object to stdout like
{"decision":"block","message":"..."} instead of printing to stderr; ensure the
handler for the 'error' variable (the block case that currently calls
print(error, file=sys.stderr) and sys.exit(2)) writes the JSON string to stdout
and then exits with code 2 so the PreToolUse contract is satisfied.

Comment on lines +343 to +417
"spec-check": {
"phrases": [
"check spec health",
"audit specs",
"which specs are stale",
"find missing specs",
"review spec quality",
"run spec-check",
"are my specs up to date",
],
"terms": ["spec-check"],
},
"spec-init": {
"phrases": [
"initialize specs",
"specs directory",
"set up specs",
"bootstrap specs",
"start using specs",
"create spec directory",
"init specs",
"set up .specs",
],
"terms": ["spec-init"],
},
"spec-new": {
"phrases": [
"create a spec",
"new spec",
"new feature spec",
"write a spec for",
"spec this feature",
"start a new spec",
"plan a feature",
"add a spec",
],
"terms": ["spec-new"],
},
"spec-refine": {
"phrases": [
"refine the spec",
"review spec assumptions",
"validate spec decisions",
"approve the spec",
"walk me through the spec",
"check spec for assumptions",
"iterate on the spec",
],
"terms": ["spec-refine"],
},
"spec-update": {
"phrases": [
"update the spec",
"mark spec as implemented",
"as-built update",
"finish the spec",
"close the spec",
"update spec status",
"sync spec with code",
],
"terms": ["spec-update"],
},
"team": {
"phrases": [
"spawn a team",
"create a team",
"team of agents",
"use a swarm",
"work in parallel",
"coordinate multiple agents",
"split this across agents",
"team up",
],
"terms": ["TeamCreate", "SendMessage"],
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the structure of the skill-engine plugin to find skills directories
echo "=== Checking for skills directories under skill-engine ==="
fd --type d 'skills' .devcontainer/plugins/devs-marketplace/plugins/skill-engine

echo ""
echo "=== Listing skill folders (one level below skills directory) ==="
fd --type d --max-depth 3 . .devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills | head -50

echo ""
echo "=== Specifically searching for spec-* and team directories ==="
fd --type d '(spec-check|spec-init|spec-new|spec-refine|spec-update|team)' .devcontainer/plugins/devs-marketplace/plugins/skill-engine

Repository: AnExiledDev/CodeForge

Length of output: 3991


🏁 Script executed:

#!/bin/bash
# Search for spec-* directories across all plugins
echo "=== Searching for spec-* directories across all plugins ==="
fd --type d '(spec-check|spec-init|spec-new|spec-refine|spec-update)' .devcontainer/plugins/devs-marketplace/plugins

echo ""
echo "=== List all plugins to understand structure ==="
fd --type d --max-depth 1 . .devcontainer/plugins/devs-marketplace/plugins | grep -v '^\.$' | sort

Repository: AnExiledDev/CodeForge

Length of output: 1287


Move spec-* skill keywords to the correct plugin suggester.

The spec-check, spec-init, spec-new, spec-refine, and spec-update skills are defined in the spec-workflow plugin, not in skill-engine. Suggesting them from this plugin's suggester will cause runtime failures when the skill-engine tries to load them. Move these five entries to the spec-workflow plugin's suggester. The team skill is correctly placed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py
around lines 343 - 417, The spec-related suggester entries "spec-check",
"spec-init", "spec-new", "spec-refine", and "spec-update" are defined here in
the skill-engine suggester but belong to the spec-workflow plugin; remove these
five entries from the skill-engine suggester and add the exact objects
(including their "phrases" and "terms" arrays) into the spec-workflow plugin's
suggester so the suggester for spec-workflow exposes those skills at runtime;
leave the "team" entry as-is in the skill-engine suggester and verify no other
references to "spec-*" remain in this file.

Comment on lines 3 to +11
description: >-
This skill should be used when the user asks to "run Claude Code in headless mode",
"use claude -p for automation", "parse stream-json output from Claude Code",
"use the Claude Agent SDK", "run Claude Code in CI/CD",
"configure MCP servers for headless Claude",
"set up Claude Code permissions for scripts",
"track Claude Code costs programmatically", or discusses Claude Code
print mode, non-interactive pipelines, SDK integration in TypeScript or Python,
structured output with json-schema, or session management for automation.
version: 0.1.0
Guides non-interactive Claude Code usage via the -p flag, stream-json output
parsing, and CI/CD pipeline integration. USE WHEN the user asks to "run
Claude Code in headless mode", "use claude -p for automation", "parse
stream-json output", "run Claude Code in CI/CD", "track costs
programmatically", "set up permissions for scripts", or works with
--output-format stream-json, --permission-mode, --json-schema, --resume.
DO NOT USE for the TypeScript SDK API — use claude-agent-sdk instead.
version: 0.2.0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Resolve the SDK guidance contradiction in this doc.

The description says “DO NOT USE for the TypeScript SDK API — use claude-agent-sdk instead,” but the “Agent SDK” section later still provides TypeScript usage with @anthropic-ai/claude-agent-sdk. This is internally inconsistent and will mislead users. Please align the description with the SDK section (or update/remove the SDK examples to match the new guidance).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/claude-code-headless/SKILL.md
around lines 3 - 11, The doc text currently contradicts itself by saying "DO NOT
USE for the TypeScript SDK API — use claude-agent-sdk instead" while the "Agent
SDK" section still includes TypeScript examples using
`@anthropic-ai/claude-agent-sdk`; update SKILL.md to be consistent by either
removing or replacing the "Agent SDK" TypeScript examples (and any references to
`@anthropic-ai/claude-agent-sdk`) to match the top-level directive, or conversely
change the description to allow TypeScript SDK usage; ensure the unique
identifiers "Agent SDK" section and the package name
"@anthropic-ai/claude-agent-sdk" are updated accordingly so the doc no longer
contradicts itself.

Comment on lines +4 to +9
Guides Svelte 5 development with runes, SvelteKit SPA configuration, and
component architecture. USE WHEN the user asks to "build a Svelte component",
"use Svelte 5 runes", "set up a SvelteKit SPA", "migrate from Svelte 4
to 5", "manage state with $state", "add drag and drop to Svelte", or works
with $state, $derived, $effect, $props, @ai-sdk/svelte, svelte-dnd-action.
DO NOT USE for Svelte 4 legacy codebases or React/Vue development.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check that the layercake reference file exists
find . -name "layercake.md" -type f 2>/dev/null | head -20

# Also check the svelte5 skill directory structure
fd -t f . '.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/svelte5/' 2>/dev/null | head -30

Repository: AnExiledDev/CodeForge

Length of output: 986


🏁 Script executed:

# Check how skill-suggester.py reads skill descriptions/keywords
find . -name "skill-suggester.py" -type f 2>/dev/null

# Also search for how skills are parsed/matched
rg -l 'description' --type py | grep -i skill | head -10

Repository: AnExiledDev/CodeForge

Length of output: 240


🏁 Script executed:

wc -l .devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py

Repository: AnExiledDev/CodeForge

Length of output: 155


🏁 Script executed:

cat -n .devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py

Repository: AnExiledDev/CodeForge

Length of output: 17811


The skill-suggester.py has a hardcoded keyword list, not extracted from SKILL.md descriptions.

layercake is missing from the svelte5 skill activation keywords in skill-suggester.py (line 134), not in the SKILL.md description. The skill-suggester uses a hardcoded SKILLS dictionary with "phrases" and "terms"—it does not read from SKILL.md descriptions. Adding layercake to the SKILL.md description (lines 4–9) will not enable skill activation; the fix must be applied to skill-suggester.py instead.

✏️ Required fix location

In .devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py, line 134, add layercake to the terms list:

-        "terms": ["sveltekit", "svelte", "svelte-dnd-action", "@ai-sdk/svelte"],
+        "terms": ["sveltekit", "svelte", "svelte-dnd-action", "@ai-sdk/svelte", "layercake"],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
@.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/svelte5/SKILL.md
around lines 4 - 9, The SKILL.md change is insufficient because
skill-suggester.py uses a hardcoded SKILLS dictionary; update the SKILLS entry
for the "svelte5" skill in
.devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py
by adding "layercake" to that skill's "terms" list (the SKILLS dict -> "svelte5"
key -> "terms" array) so the skill activation recognizes the keyword; leave
SKILL.md as-is.

Comment on lines +16 to +19
- uses: actions/checkout@v4

- name: "Publish Features"
uses: devcontainers/action@v1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check the current state of the workflow file
cat -n .github/workflows/publish-features.yml | head -25

Repository: AnExiledDev/CodeForge

Length of output: 802


🌐 Web query:

devcontainers/action@v1 latest release GitHub

💡 Result:

The latest release of devcontainers/action@v1 on GitHub is v1.4.3, published Oct 4, 2024. [1]

Recommended tag to use: devcontainers/action@v1 (major-version tag) or pin to devcontainers/action@v1.4.3. [1]

Sources: [1]


🌐 Web query:

actions/checkout@v4 latest stable release SHA GitHub

💡 Result:

Latest stable actions/checkout@v4 release is v4.3.1, which points to commit SHA:

34e114876b0b11c390a56381ad16ebd13914f8d5 (github.com)

Citations:


Pin action references to immutable SHAs to prevent supply-chain attacks.

Both actions/checkout@v4 and devcontainers/action@v1 use mutable floating major-version tags. This job holds packages: write, so a compromised or re-pointed tag could publish malicious images to GHCR using the workflow's GITHUB_TOKEN.

🔒 Proposed fix: pin to immutable SHAs
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5  # v4.3.1

       - name: "Publish Features"
-        uses: devcontainers/action@v1
+        uses: devcontainers/action@HEAD  # or pin to latest v1.4.3 release SHA when available
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
- name: "Publish Features"
uses: devcontainers/action@v1
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- name: "Publish Features"
uses: devcontainers/action@HEAD # or pin to latest v1.4.3 release SHA when available
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-features.yml around lines 16 - 19, Replace the
mutable action tags with pinned immutable SHAs: update the checkout usage
"actions/checkout@v4" and the devcontainer usage in the "Publish Features" job
"uses: devcontainers/action@v1" to their corresponding commit SHAs (e.g.,
actions/checkout@<sha> and devcontainers/action@<sha>); fetch the current secure
SHA from each action's repository (GitHub releases or the action's default
branch commit) and replace the version tags so the workflow uses fixed SHAs to
prevent supply-chain re-pointing while keeping the same inputs and behavior.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the latest release info from GitHub for both actions
curl -s https://api.github.com/repos/actions/checkout/releases/tags/v4.2.2 | jq -r '.target_commitish' > /tmp/checkout_sha.txt
curl -s https://api.github.com/repos/devcontainers/action/releases/tags/v1.3.1 | jq -r '.target_commitish' > /tmp/devcontainers_sha.txt

echo "=== actions/checkout@v4.2.2 commit SHA ==="
cat /tmp/checkout_sha.txt

echo "=== devcontainers/action@v1.3.1 commit SHA ==="
cat /tmp/devcontainers_sha.txt

Repository: AnExiledDev/CodeForge

Length of output: 164


🌐 Web query:

actions/checkout v4.2.2 release GitHub commit SHA

💡 Result:

actions/checkout@v4.2.2 points to commit SHA:

11bd71901bbe5b1630ceea73d27597364c9af683 [1][2]


🌐 Web query:

devcontainers/action v1.3.1 release GitHub commit SHA

💡 Result:

devcontainers/action v1.3.1 tag points to commit SHA 79f4dee22a716245ebe89961ea56744a00741992. [1]

Sources:
[1] (github.com)

Citations:


Pin action references to immutable SHAs to prevent supply-chain attacks.

Both actions/checkout@v4 and devcontainers/action@v1 use mutable floating tags. This job holds packages: write, so a compromised or re-pointed tag could publish malicious images to GHCR using the workflow's GITHUB_TOKEN. Pin both actions to the full commit SHA of their latest releases:

-      - uses: actions/checkout@v4
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

       - name: "Publish Features"
-        uses: devcontainers/action@v1
+        uses: devcontainers/action@79f4dee22a716245ebe89961ea56744a00741992  # v1.3.1
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/publish-features.yml around lines 16 - 19, Replace the
mutable action refs in the workflow ("actions/checkout@v4" and
"devcontainers/action@v1") with their corresponding immutable commit SHAs (the
full 40‑char commit hashes from each action's latest release) so the job that
has packages: write cannot be hijacked by repointed tags; update the uses lines
to use the full SHA refs and document/update those SHAs whenever you
intentionally upgrade the action versions.

Comment on lines +47 to +56
- name: Publish to npm
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Create git tag
run: |
VERSION="v${{ needs.check-version.outputs.version }}"
git tag "$VERSION"
git push origin "$VERSION"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Non-atomic release: npm publish succeeds but tag/release creation can fail, leaving inconsistent state.

If npm publish succeeds (line 48) but git tag or git push origin fails (e.g., the tag already exists from a prior manual run or a partially failed workflow), the package is live on npm with no corresponding GitHub release or tag. There's no rollback for the npm publish.

Consider either:

  1. Creating the tag before publishing to npm (tags are cheap to delete on failure), or
  2. Checking for an existing tag before creating one, and adding error handling.
Proposed fix: reorder to tag-first, publish-second
+     - name: Create git tag
+       run: |
+         VERSION="v${{ needs.check-version.outputs.version }}"
+         if git ls-remote --tags origin "$VERSION" | grep -q "$VERSION"; then
+           echo "Tag $VERSION already exists, skipping"
+           exit 1
+         fi
+         git tag "$VERSION"
+         git push origin "$VERSION"
+
      - name: Run tests
        run: npm test

      - name: Publish to npm
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

-     - name: Create git tag
-       run: |
-         VERSION="v${{ needs.check-version.outputs.version }}"
-         git tag "$VERSION"
-         git push origin "$VERSION"
-
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/release.yml around lines 47 - 56, The workflow is
non-atomic: "Publish to npm" runs npm publish before the "Create git tag" step
so a failed tag/push can leave a published package without a repo tag; move the
tag creation step (the shell that sets VERSION and runs git tag/git push) to run
before the npm publish step, and in that tag step add a pre-check for existing
tag (e.g., using git rev-parse --verify or git ls-remote --tags origin) to avoid
failing on duplicate tags and fail fast on other git errors; ensure the step
that creates the tag exits non-zero on unrecoverable errors so the publish step
never runs if tagging fails.

Comment on lines 126 to 139
### Full-Access Agents

These agents can read and write files, run commands, and make changes to your codebase.

| Agent | Role | Model | Isolation | Skills |
|-------|------|-------|-----------|--------|
| **generalist** | General-purpose development tasks | Inherited | No | spec skills |
| **test-writer** | Test creation, coverage analysis, framework detection | Opus | Worktree | testing |
| **refactorer** | Behavior-preserving code transformations | Opus | Worktree | refactoring-patterns |
| **doc-writer** | Documentation writing and maintenance | Opus | Worktree | documentation-patterns |
| **migrator** | Code migration, framework upgrades | Opus | Worktree | migration-patterns |
| **spec-writer** | Specification authoring and refinement | Opus | No | specification-writing |
| **bash-exec** | Shell command execution and scripting | Sonnet | No | — |
| **statusline-config** | Statusline customization | Sonnet | No | — |
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's check the agent-system.md file around the mentioned lines
echo "=== Checking agent-system.md lines 126-139 ==="
sed -n '126,139p' docs/src/content/docs/plugins/agent-system.md

# Now let's check agents.md for spec-writer references
echo -e "\n=== Checking agents.md for spec-writer ==="
rg -n "spec-writer" docs/src/content/docs/features/agents.md -A 2 -B 2

# Find the actual agent definition file
echo -e "\n=== Looking for agent definition files ==="
find . -type f \( -name "*spec-writer*" -o -path "*/agents/*" \) | grep -v node_modules | head -20

Repository: AnExiledDev/CodeForge

Length of output: 4088


🏁 Script executed:

# Let's search more broadly for the agents configuration
echo "=== Searching for permissionMode in agent definitions ==="
rg "spec-writer" -t md --type-add="yml:*.{yml,yaml}" --type-list | head -5
rg "permissionMode" -t md -t yml -i --max-count 20

# Also check if there's an agents directory or agent definitions
echo -e "\n=== Looking for agent definition structure ==="
fd "agent" --type f --extension json --extension yaml --extension md | grep -v node_modules | head -20

Repository: AnExiledDev/CodeForge

Length of output: 883


🏁 Script executed:

# Check the full structure around spec-writer in both files
echo "=== Full context from agent-system.md ==="
sed -n '110,145p' docs/src/content/docs/plugins/agent-system.md

echo -e "\n=== Full context from agents.md ==="
sed -n '260,290p' docs/src/content/docs/features/agents.md

Repository: AnExiledDev/CodeForge

Length of output: 4684


🏁 Script executed:

cat ".devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/spec-writer.md"

Repository: AnExiledDev/CodeForge

Length of output: 19908


Move spec-writer from Full-Access to Read-Only agents table

The spec-writer is incorrectly categorized as a Full-Access agent in this file. According to its agent definition (permissionMode: plan, tools: Read/Glob/Grep/WebSearch only), spec-writer is read-only—it creates specifications without modifying files. This matches the correct categorization in agents.md. Move spec-writer to the Read-Only Agents table.

Proposed fix
 ### Read-Only Agents
 
 These agents investigate, analyze, and report — they never modify files.
 
 | Agent | Role | Model | Skills |
 |-------|------|-------|--------|
 | **architect** | System design, implementation planning, trade-off analysis | Opus | api-design, spec skills |
 | **explorer** | Fast codebase navigation, file discovery, pattern matching | Haiku | ast-grep-patterns |
 | **researcher** | Deep investigation, information gathering, web research | Sonnet | documentation-patterns |
 | **claude-guide** | Claude Code usage guidance and best practices | Haiku | claude-code-headless, claude-agent-sdk |
 | **debug-logs** | Log analysis, error diagnosis, debugging | Sonnet | debugging |
 | **dependency-analyst** | Dependency analysis, version conflicts, upgrade paths | Haiku | dependency-management |
 | **git-archaeologist** | Git history analysis, blame, bisect, forensics | Haiku | git-forensics |
 | **perf-profiler** | Performance profiling, bottleneck identification | Sonnet | performance-profiling |
 | **security-auditor** | Security audit, vulnerability assessment, OWASP checks | Sonnet | security-checklist |
+| **spec-writer** | Specification authoring and refinement | Opus | specification-writing |
 
 ### Full-Access Agents
 
 These agents can read and write files, run commands, and make changes to your codebase.
 
 | Agent | Role | Model | Isolation | Skills |
 |-------|------|-------|-----------|--------|
 | **generalist** | General-purpose development tasks | Inherited | No | spec skills |
 | **test-writer** | Test creation, coverage analysis, framework detection | Opus | Worktree | testing |
 | **refactorer** | Behavior-preserving code transformations | Opus | Worktree | refactoring-patterns |
 | **doc-writer** | Documentation writing and maintenance | Opus | Worktree | documentation-patterns |
 | **migrator** | Code migration, framework upgrades | Opus | Worktree | migration-patterns |
-| **spec-writer** | Specification authoring and refinement | Opus | No | specification-writing |
 | **bash-exec** | Shell command execution and scripting | Sonnet | No | — |
 | **statusline-config** | Statusline customization | Sonnet | No | — |
🧰 Tools
🪛 LanguageTool

[style] ~128-~128: Consider shortening or rephrasing this to strengthen your wording.
Context: ...read and write files, run commands, and make changes to your codebase. | Agent | Role | Model ...

(MAKE_CHANGES)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/src/content/docs/plugins/agent-system.md` around lines 126 - 139, The
spec-writer agent row is miscategorized under the "Full-Access Agents" table;
update the documentation by removing the spec-writer row from the Full-Access
Agents table and adding that same row to the "Read-Only Agents" table, ensuring
the entry reflects its permissionMode: plan and tools: Read/Glob/Grep/WebSearch
(i.e., read-only behavior) so the spec-writer row appears with the other
read-only agents.

Comment on lines +1 to +49
/* CodeForge Documentation — Ember/Charcoal Brand Theme */

/* Cascade layer order — MUST be first */
@layer base, starlight, theme, components, utilities;

/* Starlight + Tailwind compatibility */
@import '@astrojs/starlight-tailwind';

/* Tailwind v4 */
@import 'tailwindcss/theme.css' layer(theme);
@import 'tailwindcss/utilities.css' layer(utilities);

/* Web font */
@import '@fontsource-variable/plus-jakarta-sans';

/* ============================================
Tailwind v4 Theme Tokens
============================================ */
@theme {
/* Typography */
--font-sans: 'Plus Jakarta Sans Variable', 'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;

/* Ember accent palette */
--color-ember-50: #fff7ed;
--color-ember-100: #ffedd5;
--color-ember-200: #fed7aa;
--color-ember-300: #fdba74;
--color-ember-400: #fb923c;
--color-ember-500: #f97316;
--color-ember-600: #ea580c;
--color-ember-700: #c2410c;
--color-ember-800: #9a3412;
--color-ember-900: #7c2d12;
--color-ember-950: #431407;

/* Charcoal/stone palette */
--color-charcoal-50: #fafaf9;
--color-charcoal-100: #f5f5f4;
--color-charcoal-200: #e7e5e4;
--color-charcoal-300: #d6d3d1;
--color-charcoal-400: #a8a29e;
--color-charcoal-500: #78716c;
--color-charcoal-600: #57534e;
--color-charcoal-700: #44403c;
--color-charcoal-800: #292524;
--color-charcoal-900: #1c1917;
--color-charcoal-950: #0c0a09;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect lint configs for Tailwind v4 support / custom syntax.

fd -a -H -t f '(^|/)\.stylelintrc(\.|$)|stylelint\.(config|rc)\.|(^|/)stylelint\.config\.(js|cjs|mjs|json)|(^|/)biome\.json$|(^|/)biome\.config\.(js|cjs|mjs|json)$' \
  -E node_modules -E dist -E build

# Print relevant sections if found
for f in $(fd -a -H -t f '(^|/)\.stylelintrc(\.|$)|stylelint\.(config|rc)\.|(^|/)stylelint\.config\.(js|cjs|mjs|json)|(^|/)biome\.json$|(^|/)biome\.config\.(js|cjs|mjs|json)$' \
  -E node_modules -E dist -E build); do
  echo "----- $f -----"
  sed -n '1,200p' "$f"
done

Repository: AnExiledDev/CodeForge

Length of output: 1911


🌐 Web query:

Biome 2.4.4 Tailwind v4 @theme at-rule support CSS linting

💡 Result:

Biome v2.4.4 can lint Tailwind CSS v4’s @theme (and other Tailwind v4 directives), but it’s opt-in: you must enable Tailwind-directive parsing in the CSS parser. (next.biomejs.dev)

Fix (Biome ≥ 2.3, including 2.4.4): add this to biome.json:

{
  "css": {
    "parser": {
      "tailwindDirectives": true
    }
  }
}

With that enabled, Biome recognizes Tailwind v4 directives like @theme, so lint/suspicious/noUnknownAtRules shouldn’t flag them as unknown anymore. (next.biomejs.dev)

If you don’t enable it, Biome will treat @theme as a non-standard at-rule and noUnknownAtRules will report it (the exact error many people hit in Tailwind v4 projects). (github.com)

Citations:


🏁 Script executed:

#!/bin/bash
# Check for CI/lint workflow files
fd -a -H -t f '(^|/)\.github/workflows' -E node_modules | head -20

# Check for any existing lint configs or ignore patterns
find . -maxdepth 3 -name '.stylelintignore' -o -name '.biomeignore' -o -name 'stylelint.ignore' 2>/dev/null

# Look for any Tailwind config that might affect linting
fd -a -H -t f '(tailwind\.config|tailwind\.preset)' -E node_modules -E dist -E build | head -10

Repository: AnExiledDev/CodeForge

Length of output: 47


Add Tailwind v4 directive support to Biome CSS parser configuration.

Biome 2.4.4 supports Tailwind v4 directives like @theme, but this support is opt-in. The current biome.json is missing the required configuration, which means Biome's CSS linter will flag @theme as an unknown at-rule and fail linting.

Update biome.json to add:

biome.json CSS parser fix
{
  "css": {
    "linter": {
      "enabled": true
    },
    "parser": {
      "cssModules": true,
      "tailwindDirectives": true
    }
  }
}
🧰 Tools
🪛 Biome (2.4.4)

[error] 19-49: Tailwind-specific syntax is disabled.

(parse)

🪛 Stylelint (17.3.0)

[error] 19-19: Unexpected unknown at-rule "@theme" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/src/styles/global.css` around lines 1 - 49, The Biome CSS parser is not
configured to accept Tailwind v4 directives like `@theme`, so add/update the "css"
section in biome.json to enable the linter and set parser.tailwindDirectives to
true (and keep cssModules as needed); specifically ensure biome.json contains
"css": { "linter": { "enabled": true }, "parser": { "cssModules": true,
"tailwindDirectives": true } } so Biome stops flagging `@theme` as an unknown
at-rule.

- chromaterm: username auto-detection fallback to root now works
- biome: nvm.sh sourcing no longer aborts under set -u
- setup.js: ccstatusline-settings.json added to DEFAULT_PRESERVE
- docs: spec-writer moved to Read-Only agents table (matches definition)
- guard-readonly-bash.py: docstring corrected (stderr, not JSON stdout)
- git-forensics SKILL.md: misleading "blame" comment fixed
@AnExiledDev
Copy link
Owner Author

CodeRabbit Review — Response

Fixed (commit e68327f)

# File Fix Severity
1 features/chromaterm/install.sh Username auto-detection reset to empty before candidate loop — ${USERNAME:-root} fallback now triggers correctly Critical
2 features/biome/install.sh nvm.sh sourcing wrapped in set +u / set -u to prevent unbound variable abort Major
3 setup.js ccstatusline-settings.json added to DEFAULT_PRESERVE — user customizations survive --force updates Major
4 docs/plugins/agent-system.md spec-writer moved from Full-Access to Read-Only table (matches permissionMode: plan definition) Critical docs
5 agent-system/scripts/guard-readonly-bash.py Docstring corrected: "Returns JSON on stdout" → "Outputs block reason to stderr" Minor
6 skill-engine/skills/git-forensics/SKILL.md Comment fixed: "Blame through renames" → "Show patch history through renames" Minor

Dismissed (with justification)

ccms predictable /tmp cache path (Critical)

Runs during docker build as root in an isolated container layer. No multi-user attack surface — /tmp is fresh per build. Binary ends up in /usr/local/bin, not /tmp. False positive for devcontainer context.

skill-suggester spec-* skills "in wrong plugin" (Critical)

The skill-suggester is a centralized keyword matcher that outputs suggestion messages. The Skill tool then searches ALL plugins by name. Cross-plugin suggestions work by design — the spec-workflow plugin has no suggester of its own (only spec-reminder.py). This is not a bug.

claude-code-headless SDK "contradiction" (Major)

The description says "DO NOT USE for the TypeScript SDK API — use claude-agent-sdk instead." This is routing guidance for skill selection, not a content prohibition. The headless skill includes Agent SDK context because headless automation and the SDK overlap. If users want SDK-only docs, they should load claude-agent-sdk. No contradiction.

OPTIONS success code 204 vs 200 (Minor)

RFC 7231 §4.3.7 says 200, but in practice 204 is the standard response for CORS preflight OPTIONS requests — the most common real-world use case. The skill doc teaches practical REST design. Both are valid; keeping 204.

migration-patterns "never fix forward" too absolute (Minor)

The rule is about step sequencing during code migrations ("do not make changes intended for later steps"), not database rollback strategy. The Rollback Strategy section already covers DB-specific concerns separately. Adding exceptions would add noise without clarity.

GitHub Actions SHA pinning (Major)

Major version tags (@v4, @v1) are standard for personal projects and auto-receive security patches. SHA pinning is a supply-chain hardening measure for production CI — overkill for this project's threat model.

release.yml non-atomic publish ordering (Major)

npm publish before git tag is acceptable for a personal project. Tag failures are rare and easily fixed manually. Reordering introduces the opposite risk (tag exists but npm publish fails, requiring manual cleanup).

biome.json for Tailwind v4 @theme (Major)

Biome is installed as a devcontainer feature for general development — it is not configured as a linter for the docs site. The docs site is Astro/Starlight and doesn't use Biome for CSS linting. Non-applicable.

svelte5 add "layercake" to skill-suggester terms (Critical)

LayerCake is referenced in a supplemental file table within the skill, not a primary use case. The suggester already triggers on svelte, sveltekit, @ai-sdk/svelte, svelte-dnd-action — which covers real activation scenarios. Low value addition.

@AnExiledDev AnExiledDev merged commit d89c058 into main Feb 24, 2026
2 checks passed
@AnExiledDev AnExiledDev deleted the v1.14.0 branch February 24, 2026 07:22
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