Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Code owners — auto-requested as reviewers on matching paths.
# Last match wins; see https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
#
# Review owners (development + code review): @clean6378-max-it (Chen), @timon0305 (Zilin)
#
# Final approval, merge sequencing, and no-self-merge rules are enforced by branch
# protection / automation, not by listing additional owners here.

# Default owners for the repository.
* @clean6378-max-it @timon0305
Comment thread
clean6378-max-it marked this conversation as resolved.

# Docs and contributor process
/docs/ @clean6378-max-it @timon0305
Comment thread
clean6378-max-it marked this conversation as resolved.
Outdated
/CONTRIBUTING.md @clean6378-max-it @timon0305
/README.md @clean6378-max-it @timon0305

# CI and workflow changes
/.github/ @clean6378-max-it @timon0305
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

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`](docs/onboarding.md) for a first-PR walkthrough, suggested reading order, full CI gate commands, and good-first-issue pointers.

## Development setup

### Prerequisites
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ claude-code-chat-browser/

## Development

See **[`CONTRIBUTING.md`](CONTRIBUTING.md)** for full setup, conventions, and where to change each layer.
See **[`CONTRIBUTING.md`](CONTRIBUTING.md)** for full setup, conventions, and where to change each layer. New contributors should follow **[`docs/onboarding.md`](docs/onboarding.md)** for a first-PR walkthrough and reading order.
Comment thread
clean6378-max-it marked this conversation as resolved.

**Maintainer coverage:** commit activity is currently concentrated on a small set of identities (bus-factor risk). Mitigations: [`.github/CODEOWNERS`](.github/CODEOWNERS) routes code review to @clean6378-max-it and @timon0305; final merge approval (@wpak-ai) is enforced via branch protection, plus [`docs/onboarding.md`](docs/onboarding.md) for contributor ramp-up.
Comment thread
clean6378-max-it marked this conversation as resolved.
Outdated

Quick start:

Expand Down
1 change: 1 addition & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ No bundler step — modern browsers load modules directly. Frontend unit tests u

## Related documentation

- [Contributor onboarding](onboarding.md)
- [API reference](api-reference.md)
- [Contributing](../CONTRIBUTING.md)
- [README](../README.md)
131 changes: 131 additions & 0 deletions docs/onboarding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Contributor onboarding

Welcome. This doc is the **fast path** for your first PR. It links the existing guides rather than repeating them — read it once, then bookmark the references below.

## Before you start

| Doc | What it covers |
|-----|----------------|
| [CONTRIBUTING.md](../CONTRIBUTING.md) | Dev setup, code style, PR checklist, where to change each layer |
| [docs/architecture.md](architecture.md) | Data flow, export state machine, dispatch table, frontend layout |
| [docs/api-reference.md](api-reference.md) | HTTP routes, error codes, field stability |

## Suggested reading order

Work through these in order before touching unfamiliar code:

1. **[docs/architecture.md](architecture.md)** — component diagram, layers, and how JSONL becomes API + UI.
2. **[utils/jsonl_parser.py](../utils/jsonl_parser.py)** — session parsing entry point; tool results flow through `tool_dispatch`.
3. **[utils/tool_dispatch.py](../utils/tool_dispatch.py)** — priority-based `_TOOL_RESULT_DISPATCH` table; read the module docstring and [dispatch table notes](architecture.md#dispatch-table).
4. **Frontend SPA** — [`static/js/app.js`](../static/js/app.js) (routing), [`static/js/sessions.js`](../static/js/sessions.js) (message panel), [`static/js/render/registry.js`](../static/js/render/registry.js) (tool renderers).

For API or export changes, also skim [`api/error_codes.py`](../api/error_codes.py) and [`utils/md_exporter.py`](../utils/md_exporter.py).

## First PR walkthrough

### 1. Fork and clone

```powershell
Comment thread
clean6378-max-it marked this conversation as resolved.
Outdated
# GitHub UI: fork cppalliance/claude-code-chat-browser to your account, then:
git clone https://github.com/<your-user>/claude-code-chat-browser.git
cd claude-code-chat-browser
git remote add upstream https://github.com/cppalliance/claude-code-chat-browser.git
```

On macOS/Linux, use the same `git clone` / `git remote add` commands in your shell.

### 2. Create a branch

Branch names follow `feat/<topic>`, `fix/<topic>`, `docs/<topic>`, etc. (see [CONTRIBUTING.md](../CONTRIBUTING.md#branching-and-pull-requests)).

```bash
git fetch upstream
git checkout -b docs/my-first-change upstream/master
```

### 3. Development setup

Follow **[CONTRIBUTING.md — Development setup](../CONTRIBUTING.md#development-setup)** for your OS (Python 3.12 venv, `pip install -r requirements-dev.txt`, optional Node 20+ for JS).

Smoke-test the dev server:

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

### 4. Make a focused change

- One logical change per PR when possible.
- Match existing conventions (ruff, import order, `error_response()` for API errors) — see [Code style](../CONTRIBUTING.md#code-style-and-conventions).
- Add or update tests for behavior changes — see [Tests required](../CONTRIBUTING.md#tests-required-for-common-changes).

### 5. Run the full local gate

Run these locally before opening a PR. In CI, **ruff** (`check` + `format --check`) runs on Ubuntu, Windows, and macOS. **mypy** runs only in the Ubuntu job; run it locally before Python-heavy changes. **pip-audit**, **pytest**, integration tests, and **Vitest** also run on all three platforms in CI.

```bash
# Lint + format (CI: Ubuntu + Windows + macOS)
ruff check .
ruff format --check .

# Type check (CI: Ubuntu only)
mypy -p api -p utils -p models -p scripts
Comment thread
clean6378-max-it marked this conversation as resolved.
Outdated

# Security audit (production deps)
pip-audit -r requirements.txt

# Python tests (full suite)
pytest -q

# Integration subset (also run in CI)
pytest tests/test_api_integration.py -v

# Frontend — only if you changed static/js/
npm ci
npm test
Comment thread
clean6378-max-it marked this conversation as resolved.
Outdated
```

Fix formatting with `ruff format .` when `ruff format --check` fails.

### 6. Push and open a PR

```bash
git push -u origin docs/my-first-change
```

Open a pull request against **`master`** on `cppalliance/claude-code-chat-browser`. Include:

- A short summary of **why** the change is needed.
- A **Test plan** checklist (what you ran locally).
- Links to any related issue (`Fixes #NNN` when applicable).

### 7. Review

[`.github/CODEOWNERS`](../.github/CODEOWNERS) auto-requests reviewers on new PRs. **Do not self-merge.**

1. **Code review** from @clean6378-max-it (Chen) or @timon0305 (Zilin). They own development and technical review on this repo.
2. **Final approval and merge** from @wpak-ai (Will Pak) after code review is done.

Address review feedback in follow-up commits on the same branch.

## Good first issues

Browse open issues filtered by label:

- [**good first issue**](https://github.com/cppalliance/claude-code-chat-browser/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) — scoped for newcomers
- [**help wanted**](https://github.com/cppalliance/claude-code-chat-browser/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) — maintainers welcome extra hands
- [**documentation**](https://github.com/cppalliance/claude-code-chat-browser/issues?q=is%3Aissue+is%3Aopen+label%3Adocumentation) — docs-only patches

Not sure which issue to pick? Comment on an issue or open a draft PR early for CI feedback — see [Getting help](../CONTRIBUTING.md#getting-help).

## Maintainer coverage (bus factor)

Recent commit history is concentrated on a small set of identities. If those maintainers are unavailable, review and release can stall.

**Mitigations in this repo:**

- **[`.github/CODEOWNERS`](../.github/CODEOWNERS)** — @clean6378-max-it and @timon0305 for code review routing. Final merge approval (@wpak-ai) is enforced via branch protection.
- **This onboarding path** — lowers the ramp for additional contributors to run gates and ship safely.

If you are joining as a reviewer, read the [suggested reading order](#suggested-reading-order) and run the [full local gate](#5-run-the-full-local-gate) once on `master` before approving your first PR.
14 changes: 9 additions & 5 deletions tests/benchmarks/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,14 @@ def tracemalloc_peak() -> TracemallocPeak:
def write_jsonl(path: Path, line_count: int, *, first_timestamp: str | None = None) -> Path:
"""Write a JSONL session file with *line_count* rows derived from the template fixture."""
template = json.loads(TEMPLATE_LINE)
if first_timestamp is not None:
Comment thread
clean6378-max-it marked this conversation as resolved.
Outdated
base_dt = datetime.fromisoformat(first_timestamp.replace("Z", "+00:00"))
else:
base_dt = _EXPORT_SESSION_BASE.replace(hour=10)
with path.open("w", encoding="utf-8") as f:
for i in range(line_count):
entry = deepcopy(template)
if i == 0 and first_timestamp is not None:
entry["timestamp"] = first_timestamp
else:
entry["timestamp"] = f"2026-06-12T10:{i % 60:02d}:00Z"
entry["timestamp"] = (base_dt + timedelta(minutes=i)).strftime("%Y-%m-%dT%H:%M:%SZ")
if i % 3 == 1:
msg = entry.setdefault("message", {})
if isinstance(msg, dict) and "content" in msg:
Expand All @@ -79,8 +80,11 @@ def seed_search_corpus(
"""Create a multi-session project tree under *base_dir* for search benchmarks."""
project = base_dir / "bench-project"
project.mkdir(parents=True, exist_ok=True)
# Keep every message inside the default 30-day search window (see DEFAULT_SEARCH_WINDOW_DAYS).
anchor = datetime.now(UTC) - timedelta(days=1)
Comment thread
clean6378-max-it marked this conversation as resolved.
Outdated
for i in range(session_count):
write_jsonl(project / f"session_{i:04d}.jsonl", lines_per_session)
first_ts = (anchor + timedelta(minutes=i * 30)).strftime("%Y-%m-%dT%H:%M:%SZ")
write_jsonl(project / f"session_{i:04d}.jsonl", lines_per_session, first_timestamp=first_ts)
return base_dir


Expand Down
Loading