Skip to content

Commit abab19f

Browse files
committed
Fix documentation and security issues from PR #71 review
- Fix CLI version in README (0.1.0 → 0.2.0) - Update 16 path references in AGENTS.md (.codeforge/ → defaults/codeforge/) - Replace unsafe eval pattern with getent passwd in 9 install scripts The eval echo "~$USERNAME" pattern could theoretically allow command injection if username validation were removed in future changes. Using getent passwd is safer and matches the pattern already used in codex-cli/install.sh.
1 parent 055611b commit abab19f

File tree

11 files changed

+26
-26
lines changed

11 files changed

+26
-26
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Monorepo for CodeForge — an AI-powered development environment for Claude Code
77
| Package | Description | Version |
88
|---------|-------------|---------|
99
| [`container/`](container/) | CodeForge DevContainer (`@coredirective/cf-container` on npm) | 2.2.0 |
10-
| [`cli/`](cli/) | CodeForge CLI (`codeforge-cli`) | 0.1.0 |
10+
| [`cli/`](cli/) | CodeForge CLI (`codeforge-cli`) | 0.2.0 |
1111
| [`docs/`](docs/) | Documentation site ([codeforge.core-directive.com](https://codeforge.core-directive.com)) ||
1212

1313
## Quick Start

container/.devcontainer/AGENTS.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ CodeForge devcontainer for AI-assisted development with Claude Code.
66

77
| File | Purpose |
88
|------|---------|
9-
| `.codeforge/config/settings.json` | Model, tokens, permissions, plugins, env vars |
10-
| `.codeforge/config/main-system-prompt.md` | System prompt defining assistant behavior |
11-
| `.codeforge/config/orchestrator-system-prompt.md` | Orchestrator mode prompt (delegation-first) |
12-
| `.codeforge/config/ccstatusline-settings.json` | Status bar widget layout (deployed to ~/.config/ccstatusline/) |
13-
| `.codeforge/config/disabled-hooks.json` | Disable individual plugin hooks by script name |
14-
| `.codeforge/config/claude-code-router.json` | LLM provider routing config (deployed to ~/.claude-code-router/) |
15-
| `.codeforge/file-manifest.json` | Controls which config files deploy and when |
9+
| `defaults/codeforge/config/settings.json` | Model, tokens, permissions, plugins, env vars |
10+
| `defaults/codeforge/config/main-system-prompt.md` | System prompt defining assistant behavior |
11+
| `defaults/codeforge/config/orchestrator-system-prompt.md` | Orchestrator mode prompt (delegation-first) |
12+
| `defaults/codeforge/config/ccstatusline-settings.json` | Status bar widget layout (deployed to ~/.config/ccstatusline/) |
13+
| `defaults/codeforge/config/disabled-hooks.json` | Disable individual plugin hooks by script name |
14+
| `defaults/codeforge/config/claude-code-router.json` | LLM provider routing config (deployed to ~/.claude-code-router/) |
15+
| `defaults/codeforge/file-manifest.json` | Controls which config files deploy and when |
1616
| `devcontainer.json` | Container definition: image, features, mounts |
1717
| `.env` | Boolean flags controlling setup steps |
1818

19-
Config files deploy via `.codeforge/file-manifest.json` on every container start. Most deploy to `~/.claude/`; ccstatusline config deploys to `~/.config/ccstatusline/`. Each entry supports `overwrite`: `"if-changed"` (default, sha256), `"always"`, or `"never"`. Supported variables: `${CLAUDE_CONFIG_DIR}`, `${WORKSPACE_ROOT}`, `${HOME}`.
19+
Config files deploy via `defaults/codeforge/file-manifest.json` on every container start. Most deploy to `~/.claude/`; ccstatusline config deploys to `~/.config/ccstatusline/`. Each entry supports `overwrite`: `"if-changed"` (default, sha256), `"always"`, or `"never"`. Supported variables: `${CLAUDE_CONFIG_DIR}`, `${WORKSPACE_ROOT}`, `${HOME}`.
2020

2121
## Commands
2222

@@ -62,11 +62,11 @@ Declared in `settings.json` under `enabledPlugins`, auto-activated on start:
6262

6363
## Rules System
6464

65-
Rules in `.codeforge/config/rules/` deploy to `.claude/rules/` on every container start. They load into ALL sessions automatically.
65+
Rules in `defaults/codeforge/config/rules/` deploy to `.claude/rules/` on every container start. They load into ALL sessions automatically.
6666

6767
**Current rules:** `auto-memory.md`, `explicit-start.md`, `plan-presentation.md`, `scope-discipline.md`, `session-search.md`, `spec-workflow.md`, `surface-decisions.md`, `workspace-scope.md`, `zero-tolerance-bugs.md`
6868

69-
**Adding rules:** Create `.md` in `.codeforge/config/rules/`, add a manifest entry in `.codeforge/file-manifest.json`.
69+
**Adding rules:** Create `.md` in `defaults/codeforge/config/rules/`, add a manifest entry in `defaults/codeforge/file-manifest.json`.
7070

7171
## Authentication & Persistence
7272

@@ -76,19 +76,19 @@ The `~/.claude/` directory is backed by a Docker named volume (`codeforge-claude
7676

7777
Codex CLI credentials (`~/.codex/`) are backed by a separate Docker named volume (`codeforge-codex-config-${devcontainerId}`). Set `OPENAI_API_KEY` in `.devcontainer/.secrets` (or as a Codespaces secret) for automatic API key injection, or run `codex` interactively for browser-based ChatGPT OAuth.
7878

79-
**Claude Code Router:** Set provider API keys (`ANTHROPIC_API_KEY`, `DEEPSEEK_API_KEY`, `GEMINI_API_KEY`, `OPENROUTER_API_KEY`) in `.devcontainer/.secrets`. Keys are exported as env vars on container start and read at runtime by the router's `$ENV_VAR` interpolation in `~/.claude-code-router/config.json`. Edit routing rules in `.codeforge/config/claude-code-router.json` and run `ccr-apply` to redeploy.
79+
**Claude Code Router:** Set provider API keys (`ANTHROPIC_API_KEY`, `DEEPSEEK_API_KEY`, `GEMINI_API_KEY`, `OPENROUTER_API_KEY`) in `.devcontainer/.secrets`. Keys are exported as env vars on container start and read at runtime by the router's `$ENV_VAR` interpolation in `~/.claude-code-router/config.json`. Edit routing rules in `defaults/codeforge/config/claude-code-router.json` and run `ccr-apply` to redeploy.
8080

8181
## Modifying Behavior
8282

83-
1. **Change model**: Edit `.codeforge/config/settings.json``"model"` field
84-
2. **Change system prompt**: Edit `.codeforge/config/main-system-prompt.md`
85-
3. **Add config file**: Place in `.codeforge/config/`, add entry to `.codeforge/file-manifest.json`
83+
1. **Change model**: Edit `defaults/codeforge/config/settings.json``"model"` field
84+
2. **Change system prompt**: Edit `defaults/codeforge/config/main-system-prompt.md`
85+
3. **Add config file**: Place in `defaults/codeforge/config/`, add entry to `defaults/codeforge/file-manifest.json`
8686
4. **Add features**: Add to `"features"` in `devcontainer.json`
8787
5. **Disable features**: Set `"version": "none"` in the feature's config
8888
6. **Disable setup steps**: Set flags to `false` in `.env`
89-
7. **Customize status bar**: Edit `.codeforge/config/ccstatusline-settings.json`
89+
7. **Customize status bar**: Edit `defaults/codeforge/config/ccstatusline-settings.json`
9090
8. **Lock Claude Code version**: Set `CLAUDE_VERSION_LOCK=2.1.80` in `.env` — the update script installs that exact version on container start instead of updating to latest. Unset to resume auto-updates.
91-
9. **Disable individual hooks**: Add script name (without `.py`) to `disabled` array in `.codeforge/config/disabled-hooks.json` — takes effect immediately, no restart needed
91+
9. **Disable individual hooks**: Add script name (without `.py`) to `disabled` array in `defaults/codeforge/config/disabled-hooks.json` — takes effect immediately, no restart needed
9292

9393
## Plugin Development Notes
9494

container/.devcontainer/features/ccburn/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ fi
6666
echo "[ccburn] Installing for user: ${USERNAME}"
6767

6868
# === GET USER HOME ===
69-
USER_HOME=$(eval echo "~${USERNAME}")
69+
USER_HOME=$(getent passwd "${USERNAME}" | cut -d: -f6)
7070
if [ ! -d "${USER_HOME}" ]; then
7171
echo "[ccburn] ERROR: Home directory not found for user ${USERNAME}"
7272
exit 1

container/.devcontainer/features/ccstatusline/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ fi
5959
echo "[ccstatusline] Installing for user: ${USERNAME}"
6060

6161
# Get user's home directory
62-
USER_HOME=$(eval echo ~${USERNAME})
62+
USER_HOME=$(getent passwd "${USERNAME}" | cut -d: -f6)
6363

6464
# Check if ccstatusline is available
6565
if sudo -u "${USERNAME}" bash -c 'npx -y ccstatusline@latest --version' &>/dev/null 2>&1; then

container/.devcontainer/features/ccusage/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ fi
7171
echo "[ccusage] Installing for user: ${USERNAME}"
7272

7373
# === GET USER HOME ===
74-
USER_HOME=$(eval echo "~${USERNAME}")
74+
USER_HOME=$(getent passwd "${USERNAME}" | cut -d: -f6)
7575
if [ ! -d "${USER_HOME}" ]; then
7676
echo "[ccusage] ERROR: Home directory not found for user ${USERNAME}"
7777
exit 1

container/.devcontainer/features/chromaterm/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
3131
USERNAME="${USERNAME:-root}"
3232
fi
3333

34-
USER_HOME="$(eval echo "~${USERNAME}")"
34+
USER_HOME="$(getent passwd "${USERNAME}" | cut -d: -f6)"
3535

3636
echo "[chromaterm] Target user: ${USERNAME}"
3737
echo "[chromaterm] Version: ${CT_VERSION}"

container/.devcontainer/features/claude-code-router/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ fi
6363
echo "[claude-code-router] Installing for user: ${USERNAME}"
6464

6565
# === GET USER HOME ===
66-
USER_HOME=$(eval echo "~${USERNAME}")
66+
USER_HOME=$(getent passwd "${USERNAME}" | cut -d: -f6)
6767
if [ ! -d "${USER_HOME}" ]; then
6868
echo "[claude-code-router] ERROR: Home directory not found for user ${USERNAME}"
6969
exit 1

container/.devcontainer/features/claude-monitor/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
3131
USERNAME="${USERNAME:-root}"
3232
fi
3333

34-
USER_HOME="$(eval echo "~${USERNAME}")"
34+
USER_HOME="$(getent passwd "${USERNAME}" | cut -d: -f6)"
3535

3636
echo "[claude-monitor] Target user: ${USERNAME}"
3737
echo "[claude-monitor] Home: ${USER_HOME}"

container/.devcontainer/features/dprint/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
3030
USERNAME="${USERNAME:-root}"
3131
fi
3232

33-
USER_HOME="$(eval echo "~${USERNAME}")"
33+
USER_HOME="$(getent passwd "${USERNAME}" | cut -d: -f6)"
3434

3535
echo "[dprint] Target user: ${USERNAME}"
3636
echo "[dprint] Version: ${DPRINT_VERSION}"

container/.devcontainer/features/oh-my-claude/install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" >/dev/null 2>&1; then
4141
USERNAME=root
4242
fi
4343

44-
USER_HOME=$(eval echo "~${USERNAME}")
44+
USER_HOME=$(getent passwd "${USERNAME}" | cut -d: -f6)
4545

4646
# Install npm package
4747
echo "[oh-my-claude] Installing @lgcyaxi/oh-my-claude@${OMC_VERSION} globally..."

0 commit comments

Comments
 (0)