From 84714b97c69ed6b62d2ee0df9122e6490889e1e8 Mon Sep 17 00:00:00 2001 From: ".Dev" <696222+AnExiledDev@users.noreply.github.com> Date: Thu, 16 Apr 2026 15:51:28 -0500 Subject: [PATCH 1/3] Release v2.2.0 (Container) + v0.2.0 (CLI) (#75) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Claude Code Router + Codex CLI features, extract dashboard, restructure 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 * Remove dashboard feature from devcontainer 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 * Remove deprecated container/.codeforge directory 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. * Add behavioral rules for Claude Code sessions 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 * Update hook gate path to ~/.claude/disabled-hooks.json All plugin scripts now check ~/.claude/disabled-hooks.json instead of .codeforge/config/disabled-hooks.json for the hook disable list. * Update defaults configuration - 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 * Update agent definitions: remove worktree isolation, upgrade models - 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 * Update documentation and refactor CLAUDE.md structure - 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 * Pin agent models to opus-4-5 Update all 9 opus-based agents to use explicit model version opus-4-5. * Bump version to 2.2.0 with comprehensive changelog 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. * Add effort frontmatter to all agents and skills 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) * Add session tokens command for thinking token analysis - 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 devcontainer feature (disabled) 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. * Ignore .research/ directory * 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. * Fix container tests for new config location 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. --------- Co-authored-by: Claude --- container/test.js | 87 +++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/container/test.js b/container/test.js index f7ff688..45bf679 100644 --- a/container/test.js +++ b/container/test.js @@ -28,8 +28,8 @@ function runTests() { "README.md", ".devcontainer/devcontainer.json", ".devcontainer/scripts/setup.sh", - ".codeforge/config/settings.json", - ".codeforge/file-manifest.json", + ".devcontainer/defaults/codeforge/config/settings.json", + ".devcontainer/defaults/codeforge/file-manifest.json", ]; let allFilesExist = true; @@ -99,9 +99,14 @@ function runTests() { // Test 7: generateChecksums produces expected structure let checksumStructureValid = true; - const codeforgeDir = path.join(__dirname, ".codeforge"); - if (fs.existsSync(codeforgeDir)) { - const checksums = generateChecksums(codeforgeDir); + const defaultsDir = path.join( + __dirname, + ".devcontainer", + "defaults", + "codeforge", + ); + if (fs.existsSync(defaultsDir)) { + const checksums = generateChecksums(defaultsDir); if (typeof checksums === "object" && checksums !== null) { const keys = Object.keys(checksums); if (keys.length > 0) { @@ -125,55 +130,41 @@ function runTests() { checksumStructureValid = false; } } else { - console.log("❌ Test 7: .codeforge directory not found, skipping"); + console.log( + "❌ Test 7: .devcontainer/defaults/codeforge/ not found, skipping", + ); checksumStructureValid = false; } - // Test 8: Bundled defaults in .devcontainer/defaults/codeforge/ match .codeforge/ - let bundledDefaultsInSync = true; - const bundledDir = path.join( - __dirname, - ".devcontainer", - "defaults", - "codeforge", - ); - if (fs.existsSync(bundledDir) && fs.existsSync(codeforgeDir)) { - const sourceChecksums = generateChecksums(codeforgeDir); - const bundledChecksums = generateChecksums(bundledDir); - const sourceKeys = Object.keys(sourceChecksums).sort(); - const bundledKeys = Object.keys(bundledChecksums).sort(); + // Test 8: Defaults directory has expected config structure + let defaultsStructureValid = true; + const expectedSubdirs = ["config"]; + const expectedFiles = ["file-manifest.json", "config/settings.json"]; - if (JSON.stringify(sourceKeys) !== JSON.stringify(bundledKeys)) { - console.log( - "❌ Test 8: Bundled defaults file list differs from .codeforge/", - ); - const missing = sourceKeys.filter((k) => !bundledKeys.includes(k)); - const extra = bundledKeys.filter((k) => !sourceKeys.includes(k)); - if (missing.length) - console.log(` Missing from bundled: ${missing.join(", ")}`); - if (extra.length) - console.log(` Extra in bundled: ${extra.join(", ")}`); - bundledDefaultsInSync = false; - } else { - const drifted = sourceKeys.filter( - (k) => sourceChecksums[k] !== bundledChecksums[k], - ); - if (drifted.length > 0) { - console.log( - "❌ Test 8: Bundled defaults content differs from .codeforge/", - ); - console.log(` Drifted files: ${drifted.join(", ")}`); - bundledDefaultsInSync = false; - } else { - console.log("✓ Test 8: Bundled defaults match .codeforge/"); + if (fs.existsSync(defaultsDir)) { + for (const subdir of expectedSubdirs) { + const subdirPath = path.join(defaultsDir, subdir); + if ( + !fs.existsSync(subdirPath) || + !fs.statSync(subdirPath).isDirectory() + ) { + console.log(`❌ Test 8: Missing expected subdirectory: ${subdir}`); + defaultsStructureValid = false; } } - } else if (!fs.existsSync(bundledDir)) { - console.log("❌ Test 8: .devcontainer/defaults/codeforge/ not found"); - bundledDefaultsInSync = false; + for (const file of expectedFiles) { + const filePath = path.join(defaultsDir, file); + if (!fs.existsSync(filePath)) { + console.log(`❌ Test 8: Missing expected file: ${file}`); + defaultsStructureValid = false; + } + } + if (defaultsStructureValid) { + console.log("✓ Test 8: Defaults directory has expected structure"); + } } else { - console.log("❌ Test 8: .codeforge/ not found, cannot compare"); - bundledDefaultsInSync = false; + console.log("❌ Test 8: .devcontainer/defaults/codeforge/ not found"); + defaultsStructureValid = false; } // Summary @@ -184,7 +175,7 @@ function runTests() { setupExecutable && checksumFunctionsExist && checksumStructureValid && - bundledDefaultsInSync + defaultsStructureValid ) { console.log("🎉 All tests passed! Package is ready for distribution."); process.exit(0); From fd4c66ca6e3e099a4ad3734aabea530255ea484c Mon Sep 17 00:00:00 2001 From: ".Dev" <696222+AnExiledDev@users.noreply.github.com> Date: Thu, 16 Apr 2026 20:59:24 -0500 Subject: [PATCH 2/3] =?UTF-8?q?Release=20v2.2.1=20=E2=80=94=20alias=20UX?= =?UTF-8?q?=20+=20session=20tokens=20path=20fix=20(#76)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add Claude Code Router + Codex CLI features, extract dashboard, restructure 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 * Remove dashboard feature from devcontainer 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 * Remove deprecated container/.codeforge directory 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. * Add behavioral rules for Claude Code sessions 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 * Update hook gate path to ~/.claude/disabled-hooks.json All plugin scripts now check ~/.claude/disabled-hooks.json instead of .codeforge/config/disabled-hooks.json for the hook disable list. * Update defaults configuration - 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 * Update agent definitions: remove worktree isolation, upgrade models - 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 * Update documentation and refactor CLAUDE.md structure - 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 * Pin agent models to opus-4-5 Update all 9 opus-based agents to use explicit model version opus-4-5. * Bump version to 2.2.0 with comprehensive changelog 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. * Add effort frontmatter to all agents and skills 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) * Add session tokens command for thinking token analysis - 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 devcontainer feature (disabled) 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. * Ignore .research/ directory * 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. * Fix container tests for new config location 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. * Fix disallowed tools alias splitting * Pass --thinking-display summarized in claude aliases 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. * Fix session tokens --project filter for absolute paths 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. * Bump container to 2.2.1 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 * Implement session tokens --since / --until filters 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. * Set default effort level to high * Remove stale test-dashboard CI job 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. * Fix pathToProjectSlug on Windows 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. * Pin zod to v3 to unbreak docs build @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. * Default to opus-4-5, add cc7/ccw7/cc-orc7 for opus-4-7 (#77) 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. * Scope pathToProjectSlug leading-dash assertion to POSIX 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. * Fix release.yml changelog extraction header pattern 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). --------- Co-authored-by: Claude --- .github/workflows/ci.yml | 14 +--- .github/workflows/release.yml | 2 +- cli/CHANGELOG.md | 7 ++ cli/package.json | 2 +- cli/src/commands/session/tokens.ts | 76 +++++++++++++++++- cli/tests/tokens.test.ts | 79 +++++++++++++++++++ container/.devcontainer/AGENTS.md | 7 +- container/.devcontainer/CHANGELOG.md | 14 ++++ .../defaults/codeforge/config/settings.json | 10 +-- .../.devcontainer/scripts/setup-aliases.sh | 49 +++++++++--- container/package.json | 2 +- docs/package-lock.json | 47 ++++++----- docs/package.json | 5 +- docs/src/content/docs/reference/changelog.md | 12 +++ 14 files changed, 261 insertions(+), 65 deletions(-) create mode 100644 cli/tests/tokens.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 15d052e..d682e8d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,10 +3,10 @@ name: CI on: push: branches: [main, staging] - paths: ['container/**', 'cli/**', 'dashboard/**'] + paths: ['container/**', 'cli/**'] pull_request: branches: [main, staging] - paths: ['container/**', 'cli/**', 'dashboard/**'] + paths: ['container/**', 'cli/**'] jobs: test: @@ -52,13 +52,3 @@ jobs: working-directory: cli - run: bun test working-directory: cli - - test-dashboard: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - uses: oven-sh/setup-bun@v2 - - run: bun install - working-directory: dashboard - - run: bun test - working-directory: dashboard diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d6e07cb..a199138 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -50,7 +50,7 @@ jobs: id: changelog run: | VERSION="${{ needs.validate.outputs.version }}" - NOTES=$(sed -n "/^## \[v${VERSION}\]/,/^## \[v/{ /^## \[v${VERSION}\]/d; /^## \[v/d; p; }" container/.devcontainer/CHANGELOG.md) + NOTES=$(sed -n "/^## v${VERSION} /,/^## v/{ /^## v${VERSION} /d; /^## v/d; p; }" container/.devcontainer/CHANGELOG.md) if [ -z "$NOTES" ]; then NOTES="Release v${VERSION}" fi diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 5aa4617..4603236 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,5 +1,12 @@ # CodeForge CLI Changelog +## v0.2.1 — 2026-04-16 + +### Fixes + +- **`session tokens --project` now works with absolute paths** — the filter was comparing an on-disk slug (e.g. `-workspaces-projects-CodeForge`) to the raw `--project` path (e.g. `/workspaces/projects/CodeForge`), which never matched. Absolute paths and paths starting with `./` / `../` are now encoded to Claude's slug form (replacing `/` and `.` with `-`) before matching. Plain substrings without separators still pass through unchanged, so `--project CodeForge` keeps working. +- **`session tokens --since` / `--until` now actually filter results** — both options were parsed but never applied. Filtering is session-level and uses file mtime (last-activity time) so sessions outside the window are skipped without being parsed. + ## v0.2.0 — 2026-04-16 ### New Command diff --git a/cli/package.json b/cli/package.json index 122180f..c13d4b0 100644 --- a/cli/package.json +++ b/cli/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "0.2.0", + "version": "0.2.1", "description": "CLI for CodeForge development workflows", "keywords": [ "codeforge", diff --git a/cli/src/commands/session/tokens.ts b/cli/src/commands/session/tokens.ts index 1b2dde3..2a6b1f6 100644 --- a/cli/src/commands/session/tokens.ts +++ b/cli/src/commands/session/tokens.ts @@ -1,6 +1,7 @@ import chalk from "chalk"; import type { Command } from "commander"; -import { basename } from "path"; +import { stat } from "fs/promises"; +import { basename, isAbsolute, resolve } from "path"; import { readLines } from "../../search/engine.js"; import { discoverSessionFiles } from "../../utils/glob.js"; import { parseRelativeTime, parseTime } from "../../utils/time.js"; @@ -80,6 +81,54 @@ function extractProjectFromPath(filePath: string): string | undefined { return undefined; } +/** + * Normalize a user-provided --project value for matching against Claude's + * on-disk project slugs. + * + * Claude encodes project cwds by replacing `/` and `.` with `-`, e.g. + * /workspaces/projects/CodeForge -> -workspaces-projects-CodeForge + * /workspaces/.devcontainer -> -workspaces--devcontainer + * + * Behavior: + * - Absolute paths are converted to slug form. + * - Relative paths beginning with `./` or `../` are resolved against cwd first. + * - Plain substrings without separators pass through unchanged so users can + * filter with `--project CodeForge` against the slug (backwards-compatible). + */ +export function pathToProjectSlug(input: string): string { + const looksLikePath = + isAbsolute(input) || input.startsWith("./") || input.startsWith("../"); + if (looksLikePath) { + const abs = isAbsolute(input) ? input : resolve(input); + // Normalize Windows separators so the slug logic (which encodes `/` and + // `.` as `-`) produces identical output on all platforms. Without this, + // `resolve("./foo")` on Windows returns `D:\...\foo` and the backslashes + // leak through unchanged. + const normalized = abs.replace(/\\/g, "/"); + return normalized.replace(/\/+$/, "").replace(/[./]/g, "-"); + } + return input; +} + +/** + * Pure check for whether a file's last-modified time falls within an optional + * [since, until] window. Exported for direct unit testing without fixtures. + * + * Semantics: + * - `since`: mtime must be >= since (inclusive) + * - `until`: mtime must be <= until (inclusive) + * - If both bounds are omitted, always returns true. + */ +export function isFileWithinTimeRange( + mtime: Date, + since?: Date, + until?: Date, +): boolean { + if (since && mtime < since) return false; + if (until && mtime > until) return false; + return true; +} + function isSubagentPath(filePath: string): boolean { return filePath.includes("/subagents/"); } @@ -304,11 +353,30 @@ async function analyzeTokens(options: { const mainSessions: SessionTokenStats[] = []; const subagentSessions: SessionTokenStats[] = []; + const projectNeedle = options.project + ? pathToProjectSlug(options.project) + : undefined; + + const hasTimeFilter = !!(options.since || options.until); + for (const filePath of files) { - // Filter by project - if (options.project) { + // Filter by project (slug-to-slug match; absolute paths are encoded). + if (projectNeedle) { const project = extractProjectFromPath(filePath); - if (!project?.includes(options.project)) continue; + if (!project?.includes(projectNeedle)) continue; + } + + // Filter by file mtime (session activity time) before the expensive + // per-file parse. Sessions outside the window are skipped without reads. + if (hasTimeFilter) { + try { + const st = await stat(filePath); + if (!isFileWithinTimeRange(st.mtime, options.since, options.until)) { + continue; + } + } catch { + continue; + } } const stats = await analyzeSessionTokens(filePath); diff --git a/cli/tests/tokens.test.ts b/cli/tests/tokens.test.ts new file mode 100644 index 0000000..d5091be --- /dev/null +++ b/cli/tests/tokens.test.ts @@ -0,0 +1,79 @@ +import { describe, expect, test } from "bun:test"; +import { + isFileWithinTimeRange, + pathToProjectSlug, +} from "../src/commands/session/tokens.js"; + +describe("pathToProjectSlug", () => { + test("encodes absolute paths to claude's slug form", () => { + expect(pathToProjectSlug("/workspaces/projects/CodeForge")).toBe( + "-workspaces-projects-CodeForge", + ); + }); + + test("encodes dotfiles with double dashes like claude does", () => { + // /workspaces/.devcontainer -> /workspaces/-devcontainer (slash -> dash, + // then the leading dot on the next segment becomes another dash) + expect(pathToProjectSlug("/workspaces/.devcontainer")).toBe( + "-workspaces--devcontainer", + ); + }); + + test("strips trailing slashes before encoding", () => { + expect(pathToProjectSlug("/workspaces/projects/CodeForge/")).toBe( + "-workspaces-projects-CodeForge", + ); + expect(pathToProjectSlug("/workspaces/projects/CodeForge///")).toBe( + "-workspaces-projects-CodeForge", + ); + }); + + test("passes plain substrings through unchanged for backwards compat", () => { + // No separator -> user wants substring match against a slug + expect(pathToProjectSlug("CodeForge")).toBe("CodeForge"); + expect(pathToProjectSlug("projects-CodeForge")).toBe("projects-CodeForge"); + }); + + test("resolves relative ./ and ../ paths before encoding", () => { + const abs = pathToProjectSlug("./foo"); + // Resolved path always ends with /foo; after encoding trailing segment is -foo + expect(abs.endsWith("-foo")).toBe(true); + // On POSIX, resolved absolute paths start with `/` which encodes to `-`. + // On Windows they start with a drive letter (e.g. `D:`) so the leading + // `-` assertion is POSIX-only. + if (process.platform !== "win32") { + expect(abs.startsWith("-")).toBe(true); + } + + const abs2 = pathToProjectSlug("../bar"); + expect(abs2.endsWith("-bar")).toBe(true); + }); +}); + +describe("isFileWithinTimeRange", () => { + const jan1 = new Date("2026-01-01T00:00:00Z"); + const feb1 = new Date("2026-02-01T00:00:00Z"); + const mar1 = new Date("2026-03-01T00:00:00Z"); + + test("returns true when no bounds are given", () => { + expect(isFileWithinTimeRange(feb1)).toBe(true); + }); + + test("since: includes mtimes at or after the bound", () => { + expect(isFileWithinTimeRange(feb1, jan1)).toBe(true); + expect(isFileWithinTimeRange(feb1, feb1)).toBe(true); // inclusive + expect(isFileWithinTimeRange(feb1, mar1)).toBe(false); + }); + + test("until: includes mtimes at or before the bound", () => { + expect(isFileWithinTimeRange(feb1, undefined, mar1)).toBe(true); + expect(isFileWithinTimeRange(feb1, undefined, feb1)).toBe(true); // inclusive + expect(isFileWithinTimeRange(feb1, undefined, jan1)).toBe(false); + }); + + test("since + until: inclusive range", () => { + expect(isFileWithinTimeRange(feb1, jan1, mar1)).toBe(true); + expect(isFileWithinTimeRange(jan1, feb1, mar1)).toBe(false); + expect(isFileWithinTimeRange(mar1, jan1, feb1)).toBe(false); + }); +}); diff --git a/container/.devcontainer/AGENTS.md b/container/.devcontainer/AGENTS.md index 8b65f56..83465af 100644 --- a/container/.devcontainer/AGENTS.md +++ b/container/.devcontainer/AGENTS.md @@ -22,11 +22,12 @@ Config files deploy via `defaults/codeforge/file-manifest.json` on every contain | Command | Purpose | |---------|---------| -| `cc` / `claude` | Run Claude Code with auto-configuration | +| `cc` / `claude` | Run Claude Code with auto-configuration (opus-4-5, 200k context) | | `codeforge config apply` | Deploy config files to `~/.claude/` (same as container start) | | `ccraw` | Vanilla Claude Code (bypasses config) | -| `ccw` | Claude Code with writing system prompt | -| `cc-orc` | Claude Code in orchestrator mode (delegation-first) | +| `ccw` | Claude Code with writing system prompt (opus-4-5, 200k context) | +| `cc-orc` | Claude Code in orchestrator mode, delegation-first (opus-4-5, 200k context) | +| `cc7` / `ccw7` / `cc-orc7` | Claude Code on opus-4-7 with 400k context (main / writing / orchestrator modes) | | `codex` | OpenAI Codex CLI terminal coding agent | | `ccms` | Session history search _(disabled — requires Rust toolchain; uncomment in devcontainer.json to enable)_ | | `codeforge proxy` | Launch Claude Code through mitmproxy — inspect API traffic in browser (port 8081) | diff --git a/container/.devcontainer/CHANGELOG.md b/container/.devcontainer/CHANGELOG.md index 2a5cae9..ed33e6f 100644 --- a/container/.devcontainer/CHANGELOG.md +++ b/container/.devcontainer/CHANGELOG.md @@ -1,5 +1,19 @@ # CodeForge Devcontainer Changelog +## v2.2.1 — 2026-04-16 + +### Configuration + +- **Default model changed to `claude-opus-4-5`** — `ANTHROPIC_MODEL` and `ANTHROPIC_DEFAULT_OPUS_MODEL` in default settings flipped from `claude-opus-4-7` to `claude-opus-4-5`. Subagents also run on 4.5 by default. +- **Per-alias context windows** — `CLAUDE_CODE_MAX_CONTEXT_TOKENS` and `CLAUDE_CODE_AUTO_COMPACT_WINDOW` removed from global `settings.json env` (they pinned 250k globally, which would exceed 4.5's 200k ceiling). Context is now set inline per alias: `cc` / `claude` / `ccw` / `cc-orc` = 200k; `cc7` / `ccw7` / `cc-orc7` = 400k. +- **New 4.7 alias variants** — `cc7`, `ccw7`, `cc-orc7` run Claude Code on `claude-opus-4-7` with a 400k context window (main / writing / orchestrator system prompts respectively). Use these for sessions that need 4.7's larger window; use `cc` / `ccw` / `cc-orc` (now on 4.5) for standard work. +- **Thinking display set to summarized** — `cc`, `claude`, `ccw`, and `cc-orc` aliases now pass `--thinking-display summarized`, keeping the terminal tidy while still surfacing thinking. `ccraw` is unaffected (stays vanilla). +- **View mode set to focus** — `viewMode` changed from `verbose` to `focus` in default settings for a cleaner terminal UI. + +### Fixes + +- **Disallowed tools alias splitting** — oh-my-claude disallowed tools are now stored as a bash array and expanded per-argument in the Claude aliases, so `--disallowedTools` and each tool name are passed as separate argv entries in both bash and zsh. + ## v2.2.0 — 2026-04-16 ### Claude Code Router diff --git a/container/.devcontainer/defaults/codeforge/config/settings.json b/container/.devcontainer/defaults/codeforge/config/settings.json index edf1ef1..694b1d0 100644 --- a/container/.devcontainer/defaults/codeforge/config/settings.json +++ b/container/.devcontainer/defaults/codeforge/config/settings.json @@ -3,8 +3,8 @@ "autoCompact": true, "alwaysThinkingEnabled": true, "env": { - "ANTHROPIC_MODEL": "claude-opus-4-7", - "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4-7", + "ANTHROPIC_MODEL": "claude-opus-4-5", + "ANTHROPIC_DEFAULT_OPUS_MODEL": "claude-opus-4-5", "ANTHROPIC_DEFAULT_SONNET_MODEL": "claude-sonnet-4-6", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "claude-haiku-4-5-20251001", "BASH_DEFAULT_TIMEOUT_MS": "120000", @@ -13,13 +13,11 @@ "MAX_MCP_OUTPUT_TOKENS": "10000", "MAX_THINKING_TOKENS": "31999", "CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING": "1", - "CLAUDE_CODE_EFFORT_LEVEL": "max", + "CLAUDE_CODE_EFFORT_LEVEL": "high", "MCP_TIMEOUT": "120000", "MCP_TOOL_TIMEOUT": "30000", "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "80", "FORCE_AUTOUPDATE_PLUGINS": "1", - "CLAUDE_CODE_AUTO_COMPACT_WINDOW": "250000", - "CLAUDE_CODE_MAX_CONTEXT_TOKENS": "250000", "CLAUDE_CODE_SCROLL_SPEED": "3", "ENABLE_TOOL_SEARCH": "auto:5", @@ -51,7 +49,7 @@ }, "autoMemoryDirectory": "./.claude/memory", "plansDirectory": "./.claude/plans", - "viewMode": "verbose", + "viewMode": "focus", "spinnerVerbs": { "mode": "replace", "verbs": [ diff --git a/container/.devcontainer/scripts/setup-aliases.sh b/container/.devcontainer/scripts/setup-aliases.sh index 55d501e..9ce2518 100755 --- a/container/.devcontainer/scripts/setup-aliases.sh +++ b/container/.devcontainer/scripts/setup-aliases.sh @@ -61,6 +61,9 @@ for rc in ~/.bashrc ~/.zshrc; do sed -i "/^alias claude='/d" "$rc" sed -i "/^alias ccraw='/d" "$rc" sed -i "/^alias ccw='/d" "$rc" + sed -i "/^alias cc7='/d" "$rc" + sed -i "/^alias ccw7='/d" "$rc" + sed -i "/^alias cc-orc7='/d" "$rc" sed -i '/^alias check-setup=/d' "$rc" # cc-tools function from old format if grep -q "^cc-tools()" "$rc" 2>/dev/null; then @@ -93,14 +96,35 @@ else fi # oh-my-claude tools to disable (memory, preferences, coworker - keep only proxy tools) -# Note: no quotes around tool names - they don't contain spaces and quotes would be passed literally -_OMC_DISALLOWED_TOOLS='--disallowedTools mcp__oh-my-claude__remember mcp__oh-my-claude__recall mcp__oh-my-claude__get_memory mcp__oh-my-claude__forget mcp__oh-my-claude__list_memories mcp__oh-my-claude__memory_status mcp__oh-my-claude__compact_memories mcp__oh-my-claude__clear_memories mcp__oh-my-claude__summarize_memories mcp__oh-my-claude__add_preference mcp__oh-my-claude__list_preferences mcp__oh-my-claude__get_preference mcp__oh-my-claude__update_preference mcp__oh-my-claude__delete_preference mcp__oh-my-claude__match_preferences mcp__oh-my-claude__preference_stats mcp__oh-my-claude__coworker_task' - -alias cc='CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --system-prompt-file "\$CLAUDE_CONFIG_DIR/main-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions \$_OMC_DISALLOWED_TOOLS' -alias claude='CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --system-prompt-file "\$CLAUDE_CONFIG_DIR/main-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions \$_OMC_DISALLOWED_TOOLS' +_OMC_DISALLOWED_TOOLS=( + --disallowedTools + mcp__oh-my-claude__remember + mcp__oh-my-claude__recall + mcp__oh-my-claude__get_memory + mcp__oh-my-claude__forget + mcp__oh-my-claude__list_memories + mcp__oh-my-claude__memory_status + mcp__oh-my-claude__compact_memories + mcp__oh-my-claude__clear_memories + mcp__oh-my-claude__summarize_memories + mcp__oh-my-claude__add_preference + mcp__oh-my-claude__list_preferences + mcp__oh-my-claude__get_preference + mcp__oh-my-claude__update_preference + mcp__oh-my-claude__delete_preference + mcp__oh-my-claude__match_preferences + mcp__oh-my-claude__preference_stats + mcp__oh-my-claude__coworker_task +) + +alias cc='CLAUDE_CODE_MAX_CONTEXT_TOKENS=200000 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --system-prompt-file "\$CLAUDE_CONFIG_DIR/main-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions --thinking-display summarized "\${_OMC_DISALLOWED_TOOLS[@]}"' +alias claude='CLAUDE_CODE_MAX_CONTEXT_TOKENS=200000 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --system-prompt-file "\$CLAUDE_CONFIG_DIR/main-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions --thinking-display summarized "\${_OMC_DISALLOWED_TOOLS[@]}"' alias ccraw='command "\$_CLAUDE_BIN"' -alias ccw='CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --system-prompt-file "\$CLAUDE_CONFIG_DIR/writing-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions \$_OMC_DISALLOWED_TOOLS' -alias cc-orc='CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --system-prompt-file "\$CLAUDE_CONFIG_DIR/orchestrator-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions \$_OMC_DISALLOWED_TOOLS' +alias ccw='CLAUDE_CODE_MAX_CONTEXT_TOKENS=200000 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --system-prompt-file "\$CLAUDE_CONFIG_DIR/writing-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions --thinking-display summarized "\${_OMC_DISALLOWED_TOOLS[@]}"' +alias cc-orc='CLAUDE_CODE_MAX_CONTEXT_TOKENS=200000 CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --system-prompt-file "\$CLAUDE_CONFIG_DIR/orchestrator-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions --thinking-display summarized "\${_OMC_DISALLOWED_TOOLS[@]}"' +alias cc7='CLAUDE_CODE_MAX_CONTEXT_TOKENS=400000 CLAUDE_CODE_AUTO_COMPACT_WINDOW=400000 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --model claude-opus-4-7 --system-prompt-file "\$CLAUDE_CONFIG_DIR/main-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions --thinking-display summarized "\${_OMC_DISALLOWED_TOOLS[@]}"' +alias ccw7='CLAUDE_CODE_MAX_CONTEXT_TOKENS=400000 CLAUDE_CODE_AUTO_COMPACT_WINDOW=400000 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --model claude-opus-4-7 --system-prompt-file "\$CLAUDE_CONFIG_DIR/writing-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions --thinking-display summarized "\${_OMC_DISALLOWED_TOOLS[@]}"' +alias cc-orc7='CLAUDE_CODE_MAX_CONTEXT_TOKENS=400000 CLAUDE_CODE_AUTO_COMPACT_WINDOW=400000 CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 "\$_CLAUDE_WRAP" "\$_CLAUDE_BIN" --model claude-opus-4-7 --system-prompt-file "\$CLAUDE_CONFIG_DIR/orchestrator-system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions --thinking-display summarized "\${_OMC_DISALLOWED_TOOLS[@]}"' alias ccr-apply='codeforge config apply && (ccr restart 2>/dev/null || ccr start) && echo "CCR config applied and restarted"' alias omc-apply='codeforge config apply && (omc proxy restart 2>/dev/null || omc proxy start) && echo "OMC config applied and proxy restarted"' @@ -131,11 +155,14 @@ BLOCK_EOF done echo "[setup-aliases] Aliases configured:" -echo " cc -> claude with \$CLAUDE_CONFIG_DIR/main-system-prompt.md" -echo " claude -> claude with \$CLAUDE_CONFIG_DIR/main-system-prompt.md" +echo " cc -> claude (opus-4-5, 200k ctx) with \$CLAUDE_CONFIG_DIR/main-system-prompt.md" +echo " claude -> claude (opus-4-5, 200k ctx) with \$CLAUDE_CONFIG_DIR/main-system-prompt.md" echo " ccraw -> vanilla claude without any config" -echo " ccw -> claude with \$CLAUDE_CONFIG_DIR/writing-system-prompt.md" -echo " cc-orc -> claude with \$CLAUDE_CONFIG_DIR/orchestrator-system-prompt.md (delegation mode)" +echo " ccw -> claude (opus-4-5, 200k ctx) with \$CLAUDE_CONFIG_DIR/writing-system-prompt.md" +echo " cc-orc -> claude (opus-4-5, 200k ctx) with \$CLAUDE_CONFIG_DIR/orchestrator-system-prompt.md (delegation mode)" +echo " cc7 -> claude (opus-4-7, 400k ctx) with \$CLAUDE_CONFIG_DIR/main-system-prompt.md" +echo " ccw7 -> claude (opus-4-7, 400k ctx) with \$CLAUDE_CONFIG_DIR/writing-system-prompt.md" +echo " cc-orc7 -> claude (opus-4-7, 400k ctx) with \$CLAUDE_CONFIG_DIR/orchestrator-system-prompt.md (delegation mode)" echo " ccr-apply -> redeploy claude-code-router config + restart daemon" echo " cc-tools -> list all available CodeForge tools" echo " check-setup -> verify CodeForge setup health" diff --git a/container/package.json b/container/package.json index 5dfd24c..66c551b 100644 --- a/container/package.json +++ b/container/package.json @@ -3,7 +3,7 @@ "publishConfig": { "access": "public" }, - "version": "2.2.0", + "version": "2.2.1", "description": "Complete development container that sets up Claude Code with modular devcontainer features, modern dev tools, and persistent configurations. Drop it into any project and get a production-ready AI development environment in minutes.", "main": "setup.js", "bin": { diff --git a/docs/package-lock.json b/docs/package-lock.json index e347b5d..82ca6e8 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -8,7 +8,7 @@ "name": "codeforge-docs", "version": "0.1.0", "dependencies": { - "@astrojs/sitemap": "^3.7.0", + "@astrojs/sitemap": "3.7.0", "@astrojs/starlight": "^0.37.6", "@astrojs/starlight-tailwind": "^4.0.2", "@fontsource-variable/plus-jakarta-sans": "^5.2.8", @@ -122,14 +122,14 @@ } }, "node_modules/@astrojs/sitemap": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.2.tgz", - "integrity": "sha512-PqkzkcZTb5ICiyIR8VoKbIAP/laNRXi5tw616N1Ckk+40oNB8Can1AzVV56lrbC5GKSZFCyJYUVYqVivMisvpA==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.0.tgz", + "integrity": "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==", "license": "MIT", "dependencies": { - "sitemap": "^9.0.0", + "sitemap": "^8.0.2", "stream-replace-string": "^2.0.0", - "zod": "^4.3.6" + "zod": "^3.25.76" } }, "node_modules/@astrojs/starlight": { @@ -3866,15 +3866,6 @@ "@esbuild/win32-x64": "0.25.12" } }, - "node_modules/astro/node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/astro/node_modules/zod-to-ts": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", @@ -8767,24 +8758,30 @@ "license": "MIT" }, "node_modules/sitemap": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.1.tgz", - "integrity": "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==", + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.3.tgz", + "integrity": "sha512-9Ew1tR2WYw8RGE2XLy7GjkusvYXy8Rg6y8TYuBuQMfIEdGcWoJpY2Wr5DzsEiL/TKCw56+YKTCCUHglorEYK+A==", "license": "MIT", "dependencies": { - "@types/node": "^24.9.2", + "@types/node": "^17.0.5", "@types/sax": "^1.2.1", "arg": "^5.0.0", "sax": "^1.4.1" }, "bin": { - "sitemap": "dist/esm/cli.js" + "sitemap": "dist/cli.js" }, "engines": { - "node": ">=20.19.5", - "npm": ">=10.8.2" + "node": ">=14.0.0", + "npm": ">=6.0.0" } }, + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" + }, "node_modules/smol-toml": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz", @@ -9965,9 +9962,9 @@ } }, "node_modules/zod": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/docs/package.json b/docs/package.json index 2c5ab5a..da68fad 100644 --- a/docs/package.json +++ b/docs/package.json @@ -11,7 +11,7 @@ "astro": "astro" }, "dependencies": { - "@astrojs/sitemap": "^3.7.0", + "@astrojs/sitemap": "3.7.0", "@astrojs/starlight": "^0.37.6", "@astrojs/starlight-tailwind": "^4.0.2", "@fontsource-variable/plus-jakarta-sans": "^5.2.8", @@ -28,5 +28,8 @@ "starlight-tags": "^0.4.0", "starlight-versions": "^0.7.0", "tailwindcss": "^4.2.1" + }, + "overrides": { + "zod": "3.25.76" } } diff --git a/docs/src/content/docs/reference/changelog.md b/docs/src/content/docs/reference/changelog.md index cf1ec2b..f577d9f 100755 --- a/docs/src/content/docs/reference/changelog.md +++ b/docs/src/content/docs/reference/changelog.md @@ -47,6 +47,17 @@ For minor and patch updates, you can usually just rebuild the container. Check t ## Version History +## v2.2.1 — 2026-04-16 + +### Configuration + +- **Thinking display set to summarized** — `cc`, `claude`, `ccw`, and `cc-orc` aliases now pass `--thinking-display summarized`, keeping the terminal tidy while still surfacing thinking. `ccraw` is unaffected (stays vanilla). +- **View mode set to focus** — `viewMode` changed from `verbose` to `focus` in default settings for a cleaner terminal UI. + +### Fixes + +- **Disallowed tools alias splitting** — oh-my-claude disallowed tools are now stored as a bash array and expanded per-argument in the Claude aliases, so `--disallowedTools` and each tool name are passed as separate argv entries in both bash and zsh. + ## v2.2.0 — 2026-04-16 ### Claude Code Router @@ -84,6 +95,7 @@ For minor and patch updates, you can usually just rebuild the container. Check t - **Model upgrade** — all 9 opus-based agents now pinned to explicit `opus-4-5` model version (architect, documenter, implementer, investigator, migrator, refactorer, security-auditor, spec-writer, test-writer) - **Worktree isolation removed** — write-capable agents (documenter, implementer, migrator, refactorer, test-writer) now run in the main worktree instead of isolated git worktrees - **Model tier upgrade** — investigator and security-auditor upgraded from sonnet to opus for improved analysis quality +- **Effort levels configured** — all 19 agents and 23 skills now have `effort:` frontmatter for Opus 4.7 adaptive thinking ### Configuration From 9344ad78f442f12fa51175375dbf1533303fd55c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 20:32:05 +0000 Subject: [PATCH 3/3] Bump typescript from 5.9.3 to 6.0.3 in /cli Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.9.3 to 6.0.3. - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.9.3...v6.0.3) --- updated-dependencies: - dependency-name: typescript dependency-version: 6.0.3 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/package.json b/cli/package.json index c13d4b0..4904ae3 100644 --- a/cli/package.json +++ b/cli/package.json @@ -35,7 +35,7 @@ "devDependencies": { "@types/bun": "^1.3.10", "@types/node": "^22.0.0", - "typescript": "^5.7.0" + "typescript": "^6.0.3" }, "engines": { "node": ">=18.0.0"