Skip to content

Latest commit

 

History

History
179 lines (134 loc) · 8.85 KB

File metadata and controls

179 lines (134 loc) · 8.85 KB

Contributing

Thanks for considering a patch. This repo is a small Flask app plus a hash-routed SPA and a CLI export script. Keep changes focused and tested.

New contributors: start with docs/onboarding.md for a first-PR walkthrough, suggested reading order, full CI gate commands, and good-first-issue pointers.

Development setup

Prerequisites

  • Python 3.12 (matches CI)
  • Node 20+ (only if you change static/js/ or run frontend unit tests)

CI runs ruff check, ruff format --check, pip-audit, pytest, integration tests, and Vitest on Ubuntu, Windows, and macOS (ubuntu-latest, windows-latest, macos-latest; Python 3.12, Node 20). Type-check (mypy) and production install smoke run on Ubuntu only.

Bootstrap (Windows PowerShell)

git clone https://github.com/cppalliance/claude-code-chat-browser.git
cd claude-code-chat-browser
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements-dev.txt

Bootstrap (macOS / Linux)

git clone https://github.com/cppalliance/claude-code-chat-browser.git
cd claude-code-chat-browser
python -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt

Run the dev server

python app.py --port 5000
# Open http://127.0.0.1:5000

Useful flags:

  • --base-dir PATH — point at a different projects/ tree (for tests or fixtures)
  • --exclude-rules PATH — session exclusion rules file
  • --host 0.0.0.0 — listen on all interfaces (use only on trusted networks; never with --debug)
  • --debug — Flask/Werkzeug debug mode (loopback hosts only; enforced when starting via python app.py, not flask run or WSGI). Extending the guard to FLASK_DEBUG / flask run is a planned follow-up.

API and release policy

When changing JSON response shapes, update the API reference stability column and CHANGELOG before removing fields.

Running tests

Python

ruff check .                           # lint (E, F, W, I) — same gate as CI
ruff format --check .                  # formatting gate; run `ruff format .` to fix
pip-audit -r requirements.txt        # production dependency audit (CI gate)
pytest -q                              # full suite + coverage (see pyproject.toml)
pytest tests/test_api_integration.py -v
pytest tests/test_search.py -v
pytest tests/test_api_routes.py -v
pytest tests/test_error_codes.py -v
pytest tests/benchmarks/ --benchmark-only -o addopts= -v   # performance baselines (see benchmarks/README.md)

JavaScript (vitest)

Only needed when editing static/js/:

npm ci
npm test
npm run test:coverage   # optional

node_modules/ is gitignored — run npm ci after clone.

Code style and conventions

Area Convention
API errors Use error_response() from api/error_codes.py. Do not call jsonify({"error": ...}) without a code field. Add new members to ErrorCode and a row in tests/test_error_codes.py.
Exception leakage 5xx bodies are generic messages only. Log full tracebacks with current_app.logger.exception(...). Never put str(e) or class names in HTTP JSON (issue #25).
Path safety Use safe_join() from utils/session_path.py for any path built from URL segments.
Imports stdlib → third-party → local, blank line between groups.
Lint / format ruff check . and ruff format --check . (CI gates). Config in pyproject.toml; run ruff format . to apply formatting locally.
Line length 100 characters (line-length in pyproject.toml).

Tests required for common changes

Change Add or update
New HTTP route Happy + error path in tests/test_api_routes.py or tests/test_api_integration.py
New ErrorCode Parametrized row in tests/test_error_codes.py
Search / limit validation tests/test_search.py
New _parse_tool_result dispatch entry Fixture + assertion in tests/test_jsonl_parser.py
New Claude Code tool use name See Adding a new tool type below
CLI behavior tests/test_cli_e2e.py (subprocess) or tests/test_cli_args.py (parser only)
Frontend shared module static/js/shared/*.test.js (vitest)
Error response shape tests/test_error_propagation.py regression

Branching and pull requests

  • Default branch: master. Do not push directly to master.
  • Branch names: feat/<topic>, fix/<topic>, test/<topic>, chore/<topic>, docs/<topic>.
  • One logical change per PR when possible.
  • PR checklist:
    • ruff check . and ruff format --check . green locally
    • pytest -q green locally
    • npm test green if JS changed
    • CI jobs green (lint-and-audit, pytest, integration-tests, js-tests on Ubuntu + Windows + macOS; mypy, prod-install-smoke on Ubuntu)
    • PR description includes a Test plan section
    • API changes update docs/api-reference.md if behavior or errors change

Where things live

Task Location
Add HTTP route api/<area>.py, register blueprint in app.py
Add stable error code api/error_codes.py
Parse JSONL / tool results utils/jsonl_parser.py — see dispatch table notes
Project/session discovery utils/session_path.py
Session statistics utils/session_stats.py
Bulk / per-session export api/export_api.py, utils/md_exporter.py
Export state on disk utils/export_state_store.py
Exclusion rules utils/exclusion_rules.py
CLI export scripts/export.py
SPA shell + routing static/index.html, static/js/app.js
Shared frontend utilities static/js/shared/
API documentation docs/api-reference.md
Deprecation policy docs/deprecation-policy.md
Changelog CHANGELOG.md

Architecture

See docs/architecture.md for data flow, export state machine, and component diagram.

Adding a new tool type

Claude Code assistant tool_use blocks carry a name string (e.g. "Read", "Bash"). The browser coordinates that name across Python dispatch, Markdown export, and the SPA registry; drift is caught by tests/test_tool_dispatch_sync.py.

Before (manual checklist — 7 coordinated sites)

  1. utils/tool_dispatch.py_FILE_ACTIVITY_HANDLERS + _TOOL_RESULT_DISPATCH
  2. models/tool_results.pyToolNameLiteral, TypedDict, is_* guard, union member
  3. utils/md_exporter.py_render_tool_use / _render_tool_result branches
  4. static/js/render/registry.js — imports + TOOL_USE_RENDERERS + TOOL_RESULT_RENDERERS
  5. static/js/render/tool_use/*.js — renderer module
  6. static/js/render/tool_result/*.js — result renderer module (when applicable)
  7. static/tool_types.json — regenerate via scripts/gen_tool_types_manifest.py

After (registration record + generator)

  1. One edit: create or update a JSON record under tool_types/ (see tool_types/README.md).

  2. One command: python scripts/scaffold_tool_type.py --record tool_types/<name>.json
    Or from scratch: python scripts/scaffold_tool_type.py --name my_tool

  3. Complete stubs: field mapping in the dispatch builder and render HTML in JS modules. When result is registered, also finish overlap fixtures when priority > 0.

  4. Verify:

    pytest tests/test_scaffold_tool_type.py tests/test_tool_dispatch_sync.py tests/test_tool_dispatch_ordering.py tests/test_tool_dispatch_adversarial.py tests/test_jsonl_parser.py tests/test_real_session_fixtures.py -q
    npm test

The generator emits coordinated stubs across all seven sites when result is registered (dispatch table, TypedDict/guards, Markdown branches, JS use/result modules, registry.js, parser fixture, and static/tool_types.json). Use-only tools (--no-result) omit result dispatch, TypedDict/guard, parser fixture, and overlap-fixture artifacts. Hand-editing drops from seven sites to the record plus finishing TODO stubs (typically 2–3 files).

Dry-run preview: python scripts/scaffold_tool_type.py --name example_tool --dry-run

Getting help

Open an issue with a clear repro or propose a draft PR early for CI feedback.