The D3 placeholder replacement ran over the already-interpolated graph
JSON, so repo-derived content literally named __D3_SCRIPTS__ was expanded
into script markup inside the graphData script, truncating it and
promoting the remaining JSON to live HTML. Substitute the trusted
template placeholders scripts-first, data-last, and add a regression
test with a node named __D3_SCRIPTS__ and an HTML-shaped symbol name.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FmPUotoqsNWWt3b41FMjwv
The generated graph HTML loaded D3 only from the d3js.org CDN, so on
offline or filtered networks (the reporter's case) the script was blocked
and the page failed with 'd3 is not defined'. The CDN tag already carried
integrity + crossorigin, so the failure was the external fetch itself.
- Vendor the pinned d3 v7.9.0 build (byte-identical to the existing SRI
hash) as code_review_graph/assets/d3.v7.min.js; hatchling packages it
in both wheel and sdist.
- generate_html now writes the asset next to graph.html (verified against
the pinned sha384 before writing) and both templates reference the
same-origin file first, keeping the integrity attribute.
- A synchronous document.write fallback keeps the SRI + crossorigin CDN
tag for pages copied away from their d3 sidecar file.
- Regression tests: same-origin script tag with pinned SRI, SRI-pinned
CDN fallback, sidecar asset written into the served directory, and
packaged asset hash check.
Fixes#475
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FmPUotoqsNWWt3b41FMjwv
Auto mode switched away from the full D3 force layout only when node
count exceeded 3000; edge count was ignored, so a 2792-node/17488-edge
graph stayed in full mode and the force layout stalled the browser
(O(E) link force per tick plus one SVG element per edge).
- Add DEFAULT_MAX_FULL_EDGES = 3 * DEFAULT_MAX_FULL_NODES (9000),
derived from the ~3 edges/node budget the node cap already tolerated
- Auto mode now switches when rendered nodes > max_full_nodes OR
rendered edges > max_full_edges
- When switching without community data, fall back to file aggregation
instead of collapsing everything into one Uncategorized super-node
- Regression tests cover the exact reported 2792/17488 boundary
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FmPUotoqsNWWt3b41FMjwv
Keep both generated graph modes centered across delayed paint and viewport resize, with bounded requestAnimationFrame retries when SVG bounds are temporarily zero.
Co-authored-by: Mit Parikh <mitparikh1046@gmail.com>
d3.select("svg") returns the first <svg> in document order, which is a
16px legend icon — not the main graph canvas. This caused the entire
force graph to render inside the tiny legend swatch while the full-screen
canvas stayed empty.
Fix: target #graph-svg by id in both template copies. Add id="graph-svg"
to the aggregated-view template's <svg> element (it was missing).
Regression tests verify both full and community templates use the id
selector and contain no bare d3.select("svg").
Closes#523
Keep both sides: accessibility/ARIA/keyboard-nav from feat/accessibility-fixes
and community-legend CSS, community-legend HTML div, Phase 9 aggregation tests
from main. Node shapes use d3.symbol() path elements (accessibility PR wins
over main's circle approach) with aria-pressed on community toggle.
* fix: eval yaml guard + viz auto-collapse removal
- #212: eval runner.load_all_configs() now calls _require_yaml() before
reading YAML, surfacing "install code-review-graph[eval]" instead of
crashing with AttributeError on NoneType.safe_load when PyYAML isn't
installed.
- #132: visualization.py no longer unconditionally auto-collapses every
File node on startup; only kicks in at >2000 nodes. Previously, any
graph >~300 nodes would hide all CALLS/IMPORTS/INHERITS edges because
they connect Functions/Classes nested inside the collapsed Files.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(parser): Go receivers, Dart calls, inheritors_of fallback
- #190: Go method receivers — func (s *T) Foo() now attaches Foo to T
as a member (parent_name="T") with the usual CONTAINS edge, instead
of appearing as a top-level function. New _get_go_receiver_type()
helper walks the method_declaration's first parameter_list to
extract the receiver type name (handling both T and *T forms).
- #87 bug 1 (Dart CALLS edges): tree-sitter-dart doesn't wrap calls
in a call_expression; instead the pattern is identifier+selector
where the selector contains argument_part. New
_extract_dart_calls_from_children() walker handles both direct
(print('x')) and method-chained (obj.foo()) shapes and emits CALLS
edges with bare target names for the existing resolver.
- #87 bug 2 (Dart package: URIs): _do_resolve_module now handles
"package:<name>/<path>" by walking up to a pubspec.yaml whose name:
declaration matches <name>, then resolving to <root>/lib/<path>.
Results are cached per (dir, pkg_name) pair.
- #87 bug 3 (inheritors_of bare-vs-qualified): query.py falls back to
search_edges_by_target_name(node.name, kind="INHERITS"|"IMPLEMENTS")
when the primary qualified-name lookup returns nothing. Mirrors the
existing callers_of fallback; fixes not-just-Dart because bases are
stored as bare strings for every language.
Tests:
- test_multilang.py TestGoParsing.test_methods_attached_to_receiver
- test_parser.py TestParserMultilang.test_parse_dart_call_edges
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: nested node_modules + framework ignores (#91)
_should_ignore() treated fnmatch patterns literally, so "node_modules/**"
matched only top-level "node_modules/*" and missed nested paths like
"packages/app/node_modules/react/index.js" in monorepos. For every
"<dir>/**" pattern that is a single bare segment we now also test
whether <dir> appears anywhere in the path's parts.
Extended DEFAULT_IGNORE_PATTERNS with ignores for:
- PHP/Laravel: vendor/**, bootstrap/cache/**, public/build/**
- Ruby/Bundler: .bundle/**
- Java/Kotlin/Gradle: .gradle/**, *.jar
- Dart/Flutter: .dart_tool/**, .pub-cache/**
- Generic: coverage/**, .cache/**
Note: intentionally did NOT add packages/** (false positive in yarn/pnpm
workspace monorepos) or bin/**/obj/** (false positive for legitimate
source dirs). Users can extend via .code-review-graphignore.
Tests: test_should_ignore_nested_dependency_dirs,
test_should_ignore_framework_defaults.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: replace bare 'except Exception' with specific handlers + logging (#194)
Each site caught Exception broadly and silently returned an empty default,
masking real bugs. Narrowed each to the actual expected exception classes
and added logger.debug() so failures are traceable:
- cli.py _get_version — PackageNotFoundError only
- eval/benchmarks/search_quality.py — ImportError, sqlite3.OperationalError
- graph.py get_all_community_ids / get_communities_raw — sqlite3.OperationalError
(pre-v6 schemas lack community_id / communities table)
- migrations.py run_migrations — sqlite3.Error (re-raised after rollback+log)
- registry.py connection pool — sqlite3.Error
- tools/context.py — ImportError, OSError, ValueError, sqlite3.Error,
subprocess.SubprocessError (risk analysis); sqlite3.OperationalError
(missing communities/flows tables)
- tsconfig_resolver.py — OSError, ValueError, TypeError
- wiki.py — sqlite3.OperationalError
Tests continue to pass; no behavioral change at happy path.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: bump fastmcp to >=2.14.0, Windows SelectorEventLoop (#139, #195, #46, #136)
Three related problems, one dependency change + one line:
1. #139: fastmcp <2.14.0 has four published CVEs (CVE-2025-62800 XSS,
CVE-2025-62801 command injection, CVE-2025-66416 Confused Deputy). We
were pinned to "fastmcp>=0.1.0,<2" which resolved to fastmcp 1.0.
Bumped to "fastmcp>=2.14.0,<3"; the public API (`FastMCP(name, ...)`,
`@mcp.tool()`, `@mcp.prompt()`, `mcp.run(transport="stdio")`) is
unchanged so no source edits needed beyond this pin. Verified all
24 registered tools still resolve via mcp.get_tools() on 2.14.6.
2. #195: ImportError on FakeConnection/FakeRedisConnection. The chain
was fastmcp 1.0 -> docket -> fakeredis; a recent fakeredis release
renamed FakeConnection to FakeRedisConnection, breaking uvx installs
at import time. fastmcp 2.x doesn't depend on docket/fakeredis at
all, so bumping fixes this transitively.
3. #46 / #136: Windows build/embed hangs silently. On Python 3.8+ on
Windows, asyncio defaults to ProactorEventLoop, which interacts
poorly with ProcessPoolExecutor (used by full_build) over a stdio
MCP transport — it deadlocks and the user sees "Synthesizing..."
forever. main() now sets WindowsSelectorEventLoopPolicy before
mcp.run() on win32 only. This is the well-known fix for the pattern
and is a no-op on macOS/Linux. I cannot verify on Windows from
macOS but the fix is surgical and the policy change has no other
side effects.
uv.lock regenerated to drop docket/fakeredis and pick up fastmcp 2.14.6.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(vscode): better-sqlite3 12.x for Electron 39 / V8 14.2 (#218)
VS Code 1.115 ships Electron 39 / V8 14.2, which removed the
v8::Context::GetIsolate() C++ API used by better-sqlite3 11.x. The
extension could not activate at all — every command was undefined
because ./dist/extension.js failed to require('better-sqlite3').
Bumped:
- better-sqlite3: ^11.0.0 -> ^12.4.1 (12.x uses the new V8 API and
ships Electron 39 prebuilds). Currently installs 12.8.0.
- @types/better-sqlite3: ^7.6.8 -> ^7.6.13
- Extension version: 0.2.1 -> 0.2.2
src/backend/sqlite.ts: the @types/better-sqlite3 typings are still
"export =" style (CJS) but the type imports needed adjusting under
"module: Node16" strict mode:
- import type BetterSqlite3 from 'better-sqlite3' (via =require-style)
then "type DatabaseType = BetterSqlite3.Database"
- Dropped the non-existent .default access on the imported namespace
- Dropped the "Database.Database" namespace reference in _db() return
Verified locally:
- npm install succeeds, 12.8.0 prebuild loads
- node -e "require('better-sqlite3')(':memory:').exec(...)" works
- npx tsc --noEmit passes
- node esbuild.mjs produces dist/extension.js at the same size
Long-term, node:sqlite (built-in to Node 22) would eliminate this
rebuild-per-Electron-version problem entirely, but that requires API
refactoring and is out of scope here.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Main CI has been red for 13 consecutive pushes since #135. Root causes:
Lint job (ruff):
- skills.py: rename local vars _SCRIPT/_MARKER to lowercase (N806)
- communities.py: wrap long INSERT INTO SQL across two lines (E501)
- parser.py: strip trailing whitespace on Go field_identifier return (W291)
- visualization.py: rephrase comment so ruff stops parsing the embedded
"# noqa: E501" reference as a directive
Test (3.10) job:
- tests/test_skills.py: tomllib is Python 3.11+ only. Use conditional
import with tomli as the backport on 3.10.
- pyproject.toml: add "tomli>=2.0; python_version < '3.11'" to dev extras
- uv.lock: regenerated (also picks up pytest-cov + coverage entries that
were already in pyproject.toml dev extras but missing from the lock)
Verified locally on Python 3.11:
- ruff check code_review_graph/ — All checks passed
- mypy code_review_graph/ — Success (44 source files)
- bandit -r code_review_graph/ — 0 issues
- pytest --cov-fail-under=65 — 661 passed, 1 skipped, 2 xpassed, 72.77% cov
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add mode parameter to generate_html: "auto" (default), "full",
"community" (super-nodes by community), "file" (nodes by file).
Community mode supports double-click drill-down. CLI gets --mode flag.
Auto mode switches to community view above 3000 nodes.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Expands the existing keyboard-shortcut overlay to include a full
interaction guide (click a file, shift-click, drag, scroll, etc.) and a
dismiss hint, so new users can discover the graph's interactions at a
glance. Adds a corresponding test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Includes VS Code webview path rendering (SVGCircleElement -> SVGPathElement),
unified color palette in graph.ts, and symbolCross test assertion.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add schema migration framework for v2 database evolution
Introduces a versioned migration system (v1-v5) that runs automatically
on GraphStore init, enabling incremental schema changes for flows,
communities, FTS5 search, and signature tracking.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add transaction rollback to schema migrations
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: add missing indexes and clean up migrations
- Add CREATE INDEX statements in v3 migration (flows.criticality,
flows.entry_point_id, flow_memberships.node_id)
- Add CREATE INDEX statements in v4 migration (nodes.community_id,
communities.parent_id, communities.cohesion)
- Simplify redundant ternary in _table_exists to plain row[0] > 0
- Derive LATEST_VERSION from MIGRATIONS.keys() to stay in sync
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add execution flow detection, tracing, and criticality scoring
Implement flows.py with 7 functions: detect_entry_points (framework
decorators, name patterns, no-caller roots), trace_flows (BFS through
CALLS edges with cycle detection), compute_criticality (weighted scoring
on file spread, external calls, security sensitivity, test coverage gap,
depth), store_flows / get_flows / get_flow_by_id / get_affected_flows
for persistence and querying. Includes 19 tests covering all functions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: optimize entry point detection and tighten decorator patterns
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add flow MCP tools (list_flows, get_flow, get_affected_flows)
Wire the flows module into the MCP tool layer with 3 new tools:
- list_flows [EXPLORE]: list execution flows sorted by criticality
- get_flow [EXPLORE]: get detailed flow info with optional source snippets
- get_affected_flows [REVIEW]: find flows impacted by changed files
Registered all 3 as @mcp.tool() in main.py. Added TestFlowTools with
16 tests covering all tool functions, kind filtering, name search,
source inclusion, and affected flow detection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: improve flow tool path handling and kind filter limit
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add community detection with Leiden algorithm and file-based fallback
Implement communities.py with detect_communities(), store_communities(),
get_communities(), and get_architecture_overview(). Uses igraph Leiden
algorithm when available, falls back to file-based grouping otherwise.
Includes auto-naming, cohesion scoring, sub-community splitting for
large clusters (>50 nodes), and cross-community coupling warnings.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: sanitize community names and clean internal state from outputs
Apply _sanitize_name to all community names, descriptions, member
qualified_names, and cross-community edge source/target returned to
MCP clients. Strip internal member_qns set from detect_communities()
return values to prevent leaking internal state.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add community MCP tools (list, get, architecture overview)
Wire community detection into MCP with 3 new tools:
- list_communities_tool: list detected code communities sorted by size/cohesion
- get_community_tool: get details of a single community by ID or name match
- get_architecture_overview_tool: high-level architecture view with coupling warnings
Includes 15 tests covering all tool functions, status codes, and edge cases.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add hybrid search engine with FTS5 + RRF fusion
Implement code_review_graph/search.py with:
- rebuild_fts_index: drops/recreates standalone FTS5 table from nodes
- hybrid_search: FTS5 BM25 + optional vector embeddings merged via
Reciprocal Rank Fusion, with query-aware kind boosting (PascalCase
boosts Class/Type, snake_case boosts Function, dotted paths boost
qualified names) and context-file boosting
- rrf_merge: generic RRF implementation with configurable k parameter
- detect_query_kind_boost: heuristic query pattern detection
- Graceful fallback chain: hybrid -> FTS5-only -> keyword LIKE
- FTS5 injection prevention via double-quote wrapping
Update semantic_search_nodes in tools.py to use hybrid_search as its
primary search path with backward-compatible return format and new
optional context_files parameter.
20 tests covering index rebuild, FTS name/signature search, kind
boosting, RRF merge correctness, keyword fallback, empty queries,
field presence, kind filtering, context boosting, and injection safety.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add change impact analysis with risk-scored review guidance
Add changes.py module that maps git diffs to affected functions, flows,
communities, and test coverage gaps. Produces risk-scored (0-1),
priority-ordered review guidance. Register detect_changes_tool in MCP.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add graph-powered refactoring tools (rename, dead code, suggestions)
Add refactor.py module with rename_preview, find_dead_code,
suggest_refactorings, and apply_refactor operations. Register
consolidated refactor_tool and apply_refactor_tool as MCP tools
with path traversal prevention and 10-minute expiry enforcement.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add context-aware hints system for MCP tool responses
Introduce hints.py with SessionState tracking, intent inference from
tool-call history, and workflow-based next-step suggestions. Integrates
_hints into all new tool responses (tools 10-18 + semantic_search_nodes)
so Claude Code can suggest follow-up actions. Includes 19 tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add MCP prompt templates for guided workflows
Add 5 prompt functions (review_changes, architecture_map, debug_issue,
onboard_developer, pre_merge_check) that return structured message lists
for common code review workflows. Register all 5 via @mcp.prompt() in
main.py.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add Claude Code skills and hooks auto-install
Add skills.py with generate_skills (4 skill .md files), generate_hooks_config
(PostToolUse, SessionStart, PreCommit), install_hooks (.claude/settings.json),
and inject_claude_md (idempotent CLAUDE.md section). Add --skills, --hooks,
--all flags to the install/init CLI command.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add wiki generation from community structure (Task 12)
Generate markdown documentation pages for each detected code community,
with an index page linking them all. Includes overview, members table,
execution flows, and dependency sections per community page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: add multi-repo registry with connection pool (Task 13)
Add Registry class for managing multiple repos via ~/.code-review-graph/registry.json,
ConnectionPool with LRU eviction for SQLite connections, and cross-repo search.
Integrate wiki and registry tools into MCP server and CLI.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: interactive visualization upgrade and evaluation framework (Tasks 14-15)
Visualization: add flows/communities to export_graph_data, detail panel
on node click (callers/callees), community coloring toggle (D3 ordinal
scale), flow dropdown to highlight execution paths, search results
dropdown with zoom-to-node, and node kind filter checkboxes. Add --serve
flag to visualize command for local HTTP server on port 8765.
Eval framework: add scorer module with compute_token_efficiency,
compute_mrr, and compute_precision_recall. Add reporter module with
generate_markdown_report for benchmark results. Add eval CLI subcommand
(stub runner, working scorer/reporter).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat: wire post-build steps and add detect-changes CLI command (Task 16)
After successful build/update, automatically compute node signatures,
rebuild FTS index, trace execution flows, and detect communities. Add
detect-changes CLI subcommand for risk-scored change impact analysis.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: bump version to 2.0.0 and add optional dependency groups (Task 17)
Add communities, eval, wiki, and all optional dependency groups to
pyproject.toml. Bump version from 1.8.4 to 2.0.0 for the v2 release.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* test: add comprehensive v2 pipeline integration test (Task 18)
End-to-end test exercising flows, communities, FTS search,
analyze_changes, find_dead_code, rename_preview, generate_hints,
review_changes_prompt, generate_wiki, and the Registry API.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* chore: gitignore superpowers plans and specs directories
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve mypy type errors and bandit security warnings
- Fix no-redef in registry.py (renamed shadowed variable)
- Add dict[str, object] annotations for hint-augmented results in tools.py
- Replace bare except/pass with logging in registry.py and visualization.py
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add check_same_thread=False to EmbeddingStore SQLite connection
- Add _call_with_retry() with exponential backoff for Gemini API
- Escape </script> in visualization JSON (XSS defense)
- Split broad except into specific json.JSONDecodeError and (KeyError, TypeError)
- Add thread-safety comment on _default_repo_root in main.py
- Make git timeout configurable via CRG_GIT_TIMEOUT env var
- Expand test coverage: sanitize_name, find_large_functions, get_docs_section
- Clean up unused imports in test files
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Set is_test=True on File nodes for test files (*.test.ts, *.spec.ts, etc.)
- Recognize JS/TS test-runner names (describe, it, test) in test files
- Generate TESTED_BY edges when test functions call production functions
- Convert recursive allDescendants to iterative (fixes#27 stack overflow
on large codebases with 45k+ nodes)
Closes#21, Closes#27
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The escH function in the HTML template only escaped &, <, and >.
Node names containing quotes or backticks could inject scripts via
tooltip.innerHTML. Add escaping for ", ', and ` characters.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add integrity and crossorigin attributes to the D3.js script tag in
the HTML template to prevent supply-chain attacks if the CDN is
compromised.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
_build_name_index only indexed Python module-style paths, so
IMPORTS_FROM edges emitted as bare includes (e.g. "trading/Foo.hpp")
never matched File nodes stored with absolute paths. This left
C/C++ projects almost entirely disconnected in the visualization —
only 796 of 4300 edges were resolvable on a real project.
Fix: for every File node, also index all path suffixes
("Foo.hpp", "trading/Foo.hpp", "libs/trading/Foo.hpp", …) so that
any length of relative include path resolves to the correct node.
Adds a regression test with both a bare filename and a
relative-directory include path.
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Move generated files into .code-review-graph/ directory with auto-created
.gitignore. Add visualization density features: collapsed start, search bar,
edge type toggles, scale-aware force layout. Remove redundant references/,
agents/, and settings.json. Update all docs and CHANGELOG for v1.5.0.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>