Release v2.2.1 — alias UX + session tokens path fix#76
Conversation
…ucture docs Container: - Add claude-code-router feature for LLM provider routing (DeepSeek, Gemini, OpenRouter) - Add codex-cli feature for OpenAI Codex terminal agent - Add defaults/ directory with factory config templates - Update ccusage feature with Codex support - Update auth scripts for new provider API keys Dashboard: - Extract dashboard/ to separate CodeDirective repository - Add dashboard/ to .gitignore (deprecated in monorepo) Documentation: - Restructure docs: getting-started → start-here, features/customization → use/customize - Move plugins/ under extend/ section - Add new reference pages: agents, skills, cli-tools, environment-variables - Consolidate architecture and troubleshooting in reference/ Housekeeping: - Gitignore temp directories and screenshots
Dashboard extracted to separate CodeDirective repository. Remove: - codeforge-dashboard devcontainer feature - Dashboard port forwarding and config from devcontainer.json - Dashboard documentation page and sidebar references - Dashboard mentions from README, CLAUDE.md, and related docs
Configuration migrated to container/.devcontainer/defaults/codeforge/. The .codeforge directory at package root was a development artifact that should not ship with the npm package.
New rules in defaults/codeforge/config/rules/: - auto-memory.md: memory constraints and staleness cleanup - zero-tolerance-bugs.md: bugs always in scope, must be fixed - scope-discipline.md: only user defines scope - explicit-start.md: never start without clear instruction - plan-presentation.md: compressed overview before full plan - surface-decisions.md: surface assumptions before acting
All plugin scripts now check ~/.claude/disabled-hooks.json instead of .codeforge/config/disabled-hooks.json for the hook disable list.
- settings.json: update to opus-4-7, reduce thinking tokens (31999), disable adaptive thinking, add effort_level max, adjust compaction thresholds, disable agent teams, add background tasks and no-flicker - main-system-prompt.md: streamline prompt content - file-manifest.json: update file list for new rules - claude-code-router.json: add default router configuration
- Remove isolation: worktree from write-capable agents (documenter, implementer, migrator, refactorer, test-writer) — run in main worktree - Upgrade investigator and security-auditor from sonnet to opus
- Move devcontainer guide from CLAUDE.md to AGENTS.md - CLAUDE.md now uses @AGENTS.md include directive - docs: update changelog, cli-tools reference, troubleshooting - docs: remove dashboard references, fix sidebar formatting - deps: update docs package-lock.json
Update all 9 opus-based agents to use explicit model version opus-4-5.
Update changelog with all changes since v2.1.1: - Claude Code Router and Codex CLI features - Dashboard feature removed from devcontainer - 6 new behavioral rules - Agent model pinning to opus-4-5 - Worktree isolation removed from write-capable agents - Configuration updates (opus-4-7, reduced thinking tokens, max effort) - Hook gate path changed to ~/.claude/ - Config directory restructure - Documentation overhaul Version updated in package.json and README.md.
Configure Opus 4.7 adaptive thinking via effort: field in frontmatter: - 19 agents: max (2), xhigh (10), high (4), medium (5) - 23 skills: xhigh (3), high (10), medium (9), low (1) Effort levels calibrated by task complexity: - max: architect, spec-writer (deep reasoning required) - xhigh: implementer, migrator, refactorer, etc. (code writing) - high: debug-logs, dependency-analyst, etc. (analysis tasks) - medium: explorer, bash-exec, etc. (simple operations) - low: worktree (basic git commands)
- New `codeforge session tokens` command analyzes thinking token usage - Shows exact billed output tokens and visible content breakdown - Thinking Density table: % turns with thinking, avg chars, session intensity - Per-session breakdown: turns with thinking, density, avg chars per turn - Filter by --project, --model, --since, --until - Output formats: text (colorized) and JSON Bump CLI version to 0.2.0
Add oh-my-claude multi-provider proxy feature for Chinese LLM routing (Kimi, DeepSeek, Qwen, Zhipu, MiniMax). Feature is disabled pending refinement — omc install modifies settings.json despite --skip-* flags. Feature structure: - devcontainer-feature.json with version, autostart, providerAgentsOnly options - install.sh with backup/restore approach to protect settings.json - poststart-hook.sh for auto-starting proxy - README.md documenting usage and configuration Supporting changes: - .secrets.example: Add Chinese LLM provider API keys - disabled-hooks.json: Add omc memory/preference hooks - setup-aliases.sh: Add --disallowedTools for omc MCP tools, omc-apply alias - devcontainer.json: Add Chinese provider secrets (feature commented out) Note: claude-code-router also commented out pending router consolidation.
- 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.
Update test.js to reference .devcontainer/defaults/codeforge/ instead of the removed .codeforge/ directory. Test 8 now validates the defaults directory structure rather than comparing against a source that no longer exists.
# Conflicts: # container/test.js
📝 WalkthroughWalkthroughUpdates across devcontainer defaults, alias setup, CLI session-token filtering, tests, CI, docs, and package versions: Claude model defaults and viewMode changed; alias disallowed-tools converted to an array with summarized thinking display and new 400k-context aliases; CLI adds slug/time filters for session tokens with tests; container defaults layout and tests adjusted; CI/workflow and dependency pins updated. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Add `--thinking-display summarized` to cc, claude, ccw, and cc-orc so thinking output stays tidy in the terminal. ccraw stays vanilla. Also flip default viewMode from verbose to focus for a cleaner UI.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
container/.devcontainer/CHANGELOG.md (1)
44-45: LGTM — changelog entries accurately describe the behavior changes.Note: the disallowed-tools alias splitting fix itself (the subject of this PR) isn't called out here — it's a bug fix that only restores the originally intended behavior of the existing
--disallowedToolsalias wiring, so an additional bullet under a### Bug Fixes(or similar) subsection may be worth adding per the repo's "every change MUST have a changelog entry" rule. Not a blocker since the alias area is already covered by the--thinking-displaybullet.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@container/.devcontainer/CHANGELOG.md` around lines 44 - 45, Add a bug-fix bullet to the changelog stating that the alias splitting bug for the disallowed-tools wiring was fixed: mention the restored behavior of the --disallowedTools argument (and that the alias parsing now correctly preserves multi-value/disallowed tool lists) and reference the affected alias wiring (e.g., the disallowed-tools alias handling used by aliases such as `cc`, `claude`, etc.) under a new or existing "### Bug Fixes" subsection so the change follows the repo's requirement that every change has a changelog entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@container/.devcontainer/CHANGELOG.md`:
- Around line 44-45: Add a bug-fix bullet to the changelog stating that the
alias splitting bug for the disallowed-tools wiring was fixed: mention the
restored behavior of the --disallowedTools argument (and that the alias parsing
now correctly preserves multi-value/disallowed tool lists) and reference the
affected alias wiring (e.g., the disallowed-tools alias handling used by aliases
such as `cc`, `claude`, etc.) under a new or existing "### Bug Fixes" subsection
so the change follows the repo's requirement that every change has a changelog
entry.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ef909f9d-05ee-44e7-a0d0-629b2fae39b5
📒 Files selected for processing (4)
container/.devcontainer/CHANGELOG.mdcontainer/.devcontainer/defaults/codeforge/config/settings.jsoncontainer/.devcontainer/scripts/setup-aliases.shcontainer/test.js
The filter compared Claude's on-disk project slug (e.g. "-workspaces-projects-CodeForge") to the raw --project path (e.g. "/workspaces/projects/CodeForge"), which never matched — so passing an absolute path per the session-search convention returned zero sessions. Encode absolute and ./..-relative inputs to slug form (replace / and . with -) before comparing. Plain substrings without separators still pass through unchanged, so --project CodeForge keeps working. Bump CLI to 0.2.1 and add tokens.test.ts covering the transform.
Ships the UX changes from this staging cycle: - --thinking-display summarized in cc/claude/ccw/cc-orc aliases - viewMode focus default - Disallowed tools alias splitting fix
Both options were parsed but never applied in analyzeTokens, so they were silent no-ops. Apply them session-level using file mtime (last activity), skipping out-of-window files before the expensive per-file parse. Extract isFileWithinTimeRange as a pure, exported helper so the bound checks are unit-testable without fixture files. Inclusive on both ends. Folded into v0.2.1 CHANGELOG alongside the --project fix.
The dashboard/ package was extracted in bd688a5 but its CI job remained, causing every CI run to fail with "No such file or directory" when the job tried to cd into the nonexistent dashboard/. Drop the job and its path filter.
resolve() on Windows returns backslash-separated paths (D:\a\foo), and the slug regex only replaced forward slashes, leaving backslashes unchanged in the output. Normalize \ to / before slugging so test-cli (windows-latest) passes.
@astrojs/sitemap@3.7.2 declared zod@^4.3.6 as a direct dep, and zod-to-json-schema@3.25.2 (an astro transitive) accepts v3 or v4, so npm hoisted zod@4 at the root. Vite's SSR bundler then resolved "zod" to v4 during the docs build, which crashes Starlight's HeadConfigSchema (written for zod v3's z.record() single-arg form) with "Cannot read properties of undefined (reading '_zod')" while rendering the 404 route. - Pin @astrojs/sitemap to 3.7.0 (last zod-v3-compatible release); later versions use v4-only syntax internally so we can't just override zod for them. - Add an "overrides" block to force zod@3.25.76 across the tree so zod-to-json-schema stops hoisting v4. - Sync regenerated docs changelog (incidental, produced by the sync-changelog.mjs step in npm run build). Note: dependabot PR #57 would bump sitemap to 3.7.1 and re-break this. Close or ignore that PR.
Flip ANTHROPIC_MODEL and ANTHROPIC_DEFAULT_OPUS_MODEL in default settings.json from claude-opus-4-7 to claude-opus-4-5. Remove the global CLAUDE_CODE_MAX_CONTEXT_TOKENS and CLAUDE_CODE_AUTO_COMPACT_WINDOW env vars (they pinned 250k globally, which would exceed 4.5's 200k API ceiling). Move context-window control inline per alias: - cc / claude / ccw / cc-orc: 200k (opus-4-5) - cc7 / ccw7 / cc-orc7: 400k (opus-4-7) — new variants Thinking-related env vars (MAX_THINKING_TOKENS, adaptive-thinking flag, effort level) remain global. ccraw is unchanged. Also adds legacy-cleanup sed entries for cc7/ccw7/cc-orc7 so future renames stay idempotent, updates the Commands table in AGENTS.md, and documents the change in CHANGELOG.md.
There was a problem hiding this comment.
🧹 Nitpick comments (2)
docs/package.json (1)
14-14: Consider documenting the rationale for pinned versions.The
package-lock.jsonconfirms both version pins are locked in place:
@astrojs/sitemappinned to exactly3.7.0zodpinned viaoverridesto3.25.76(resolving the docs build issue)The npm package manager and
overridesmechanism are correctly in use. To help future maintainers understand when these pins can be relaxed, consider adding a brief comment or ADR explaining why these specific versions are necessary. This is particularly useful for thezodoverride, which addresses a transitive dependency issue across multiple packages in the lockfile.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/package.json` at line 14, Add a short note documenting why exact pins are used: update the package.json near the "@astrojs/sitemap" entry and the "overrides" entry that pins "zod" (or create a short ADR/markdown in the repo docs) to state the rationale (e.g., exact "@astrojs/sitemap" v3.7.0 pin and "zod" override to 3.25.76 to resolve a transitive docs build issue), when they can be relaxed, and link to the related package-lock evidence or issue/PR; include the package keys "@astrojs/sitemap" and "overrides.zod" in the note so future maintainers can find the reason quickly.cli/src/commands/session/tokens.ts (1)
362-380: Optional: avoid double-stat per session file.
discoverSessionFilesincli/src/utils/glob.tsalready runsstatSyncon every entry to sort by mtime (see lines 44-59 in that file). This adds a secondawait stat(filePath)per file whenever--since/--untilis active. For large session directories that's an extra syscall per file on the hot path.Consider having
discoverSessionFilesreturn{ path, mtime }(or expose an alternate entry point) and passing the already-known mtime intoisFileWithinTimeRangehere. Purely a perf nit — current behavior is correct.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@cli/src/commands/session/tokens.ts` around lines 362 - 380, discoverSessionFiles currently stat()s entries but this loop in tokens.ts calls stat(filePath) again when hasTimeFilter is set causing a double syscall; change discoverSessionFiles (cli/src/utils/glob.ts) to return entries with both path and mtime (e.g., { path, mtime }) or add an alternate API, then update the loop in cli/src/commands/session/tokens.ts to iterate those entries and call isFileWithinTimeRange with the supplied mtime instead of calling await stat(filePath); also update related types/signatures (and keep a compatibility shim if other callers expect plain strings).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@cli/src/commands/session/tokens.ts`:
- Around line 362-380: discoverSessionFiles currently stat()s entries but this
loop in tokens.ts calls stat(filePath) again when hasTimeFilter is set causing a
double syscall; change discoverSessionFiles (cli/src/utils/glob.ts) to return
entries with both path and mtime (e.g., { path, mtime }) or add an alternate
API, then update the loop in cli/src/commands/session/tokens.ts to iterate those
entries and call isFileWithinTimeRange with the supplied mtime instead of
calling await stat(filePath); also update related types/signatures (and keep a
compatibility shim if other callers expect plain strings).
In `@docs/package.json`:
- Line 14: Add a short note documenting why exact pins are used: update the
package.json near the "@astrojs/sitemap" entry and the "overrides" entry that
pins "zod" (or create a short ADR/markdown in the repo docs) to state the
rationale (e.g., exact "@astrojs/sitemap" v3.7.0 pin and "zod" override to
3.25.76 to resolve a transitive docs build issue), when they can be relaxed, and
link to the related package-lock evidence or issue/PR; include the package keys
"@astrojs/sitemap" and "overrides.zod" in the note so future maintainers can
find the reason quickly.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c3eb0878-c29e-4498-a2c7-42ac9a948172
⛔ Files ignored due to path filters (1)
docs/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (12)
.github/workflows/ci.ymlcli/CHANGELOG.mdcli/package.jsoncli/src/commands/session/tokens.tscli/tests/tokens.test.tscontainer/.devcontainer/AGENTS.mdcontainer/.devcontainer/CHANGELOG.mdcontainer/.devcontainer/defaults/codeforge/config/settings.jsoncontainer/.devcontainer/scripts/setup-aliases.shcontainer/package.jsondocs/package.jsondocs/src/content/docs/reference/changelog.md
✅ Files skipped from review due to trivial changes (5)
- container/package.json
- cli/package.json
- container/.devcontainer/AGENTS.md
- docs/src/content/docs/reference/changelog.md
- container/.devcontainer/CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (2)
- container/.devcontainer/defaults/codeforge/config/settings.json
- container/.devcontainer/scripts/setup-aliases.sh
On Windows, resolve('./foo') returns a drive-letter path like
D:\...\foo. The normalizer rewrites backslashes to forward slashes
and the encoder replaces [./] with '-', producing e.g.
D--a-CodeForge-foo. Starts with a letter, not a dash.
Guard the POSIX-only startsWith('-') assertion on process.platform
so Windows CI passes while keeping the POSIX contract tested.
The sed pattern was matching '## [v${VERSION}]' (bracketed) but the
container CHANGELOG uses unbracketed '## v${VERSION} — date' headers.
The match always failed and release notes silently fell back to the
'Release v${VERSION}' placeholder.
Switch to the same unbracketed pattern release-cli.yml uses (with a
trailing space sentinel to avoid prefix collisions like v2.2.1 vs
v2.2.10).
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/release.yml (1)
53-53: Optional: pattern is brittle to heading format drift and unescaped regex metacharacters.Two minor robustness concerns worth noting:
- The required trailing space ties extraction to the current
## v2.2.1 — dateformat. If a future entry is written as## v2.2.1(no date suffix) or uses a different separator, extraction silently falls back to theRelease v${VERSION}placeholder — matching the issue this commit was meant to fix.${VERSION}is interpolated directly into the sed regex, so dots are treated as.(any char). For semver this is negligible, but a prerelease like2.2.1-rc.1would also make-/.regex-sensitive.Anchoring on start-of-heading only and escaping the version would be more forgiving:
♻️ Proposed tweak
- NOTES=$(sed -n "/^## v${VERSION} /,/^## v/{ /^## v${VERSION} /d; /^## v/d; p; }" container/.devcontainer/CHANGELOG.md) + VERSION_RE=$(printf '%s' "$VERSION" | sed 's/[.[\*^$/]/\\&/g') + NOTES=$(sed -n "/^## v${VERSION_RE}\([ ]\|$\)/,/^## v/{ /^## v${VERSION_RE}\([ ]\|$\)/d; /^## v/d; p; }" container/.devcontainer/CHANGELOG.md)Not blocking — the current form works for the v2.2.1 release.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/release.yml at line 53, The sed extraction is brittle: it requires a trailing space after the heading and interpolates VERSION unescaped; change the NOTES assignment to anchor the heading and use an escaped-version variable (e.g. ESCAPED_VERSION derived from VERSION by backslash-escaping regex metacharacters) and match a word-boundary instead of a literal space; in other words, replace the pattern using "^## v${VERSION} " with something like "^## v${ESCAPED_VERSION}\b" (and leave the rest of the sed range block intact) so headings like "## v2.2.1" or "## v2.2.1-rc.1" are handled safely while avoiding accidental regex wildcards.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.github/workflows/release.yml:
- Line 53: The sed extraction is brittle: it requires a trailing space after the
heading and interpolates VERSION unescaped; change the NOTES assignment to
anchor the heading and use an escaped-version variable (e.g. ESCAPED_VERSION
derived from VERSION by backslash-escaping regex metacharacters) and match a
word-boundary instead of a literal space; in other words, replace the pattern
using "^## v${VERSION} " with something like "^## v${ESCAPED_VERSION}\b" (and
leave the rest of the sed range block intact) so headings like "## v2.2.1" or
"## v2.2.1-rc.1" are handled safely while avoiding accidental regex wildcards.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6bbea028-788e-4c76-9849-ecb295133048
📒 Files selected for processing (2)
.github/workflows/release.ymlcli/tests/tokens.test.ts
Summary
Shipping v2.2.1 with alias UX improvements and CLI fixes.
Container (v2.2.1):
CLI (v0.2.1):
Test plan
Summary by CodeRabbit
New Features
Bug Fixes
Chores