# Agent Notes

## Build

Use this as the main verification command:

```bash
rtk npm run build
```

This is a Solid/Vite TypeScript frontend. The build runs `tsc -b && vite build`.
Do not start the Vite dev server from agent sessions; use the build command for
verification.

## Architecture Map

Do not start by reading every file. Start from the area you are changing.

- `src/App.tsx`: provider wiring only. Keep this small. It should compose app-wide providers and render `AppRoutes`.
- `src/routes.tsx`: the declarative route table. Repo routes are nested under `/:owner/:repo` and use `RepoLayout`.
- `src/layout.tsx`: global shell and topbar. Preserve the `.untangled-shell` wrapper so app pages keep the intended width and padding. There is intentionally no footer.
- `src/pages/home.tsx`: home page and repository jump/recent/own-repo UI.
- `src/pages/oauth-callback.tsx`: OAuth callback completion page.
- `src/pages/not-found.tsx`: not-found page.
- `src/pages/search.tsx`: global search page.
- `src/pages/repo.tsx`: barrel exports for repo routes only.
- `src/pages/repo/shared.tsx`: repo layout/context, shared repo frame/header/tabs, repo query keys, and `useRepoQuery`.
- `src/pages/repo/code.tsx`: repo overview/tree page and blob/file viewer.
- `src/pages/repo/code-helpers.ts`: pure code-route helpers such as ref/path resolution, language normalization, delayed loading, and navigation click checks.
- `src/pages/repo/issues.tsx`: issue list, new issue, and issue detail.
- `src/pages/repo/issues-helpers.ts`: issue-specific pure helpers such as comment thread building.
- `src/pages/repo/pulls.tsx`: pull list, new pull, pull detail, and patch/diff rendering calls.
- `src/pages/repo/pulls-helpers.ts`: pull-specific pure helpers such as state filter parsing.
- `src/components/common.tsx`: generic UI primitives such as `Avatar`, `LoadingState`, `StateBadge`, and form/button/card style helpers.
- `src/components/repo.tsx`: repo presentation components such as tabs, file rows, README/comment cards, `CodeView`, `DiffView`, branch pills, and repo skeletons.
- `src/lib/api.ts`: compatibility facade that re-exports domain APIs. Do not add implementation here.
- `src/lib/api/constants.ts`: public service URLs and OAuth scope exports.
- `src/lib/api/appview.ts`: appview JSON transport, fallback, and appview response types.
- `src/lib/api/backlinks.ts`: Constellation backlink traversal and backlink pagination helpers.
- `src/lib/api/client.ts`: shared ATProto RPC client creation and service URL normalization.
- `src/lib/api/hydration.ts`: record hydration from appview/PDS records into resolved authors.
- `src/lib/api/identity.ts`: auth RPC, identity resolver, actor resolution, avatar resolution.
- `src/lib/api/repos.ts`: repo records, repo metadata, tree/blob/branch/tag/log/language APIs, compare APIs, and related response types.
- `src/lib/api/issues.ts`: issue list/detail/create/comment/state APIs and issue types.
- `src/lib/api/pulls.ts`: pull list/detail/create/comment/status/patch APIs and pull types.
- `src/lib/api/stars.ts`: repo star summary/count/create/delete APIs and star types.
- `src/lib/api/records.ts`: shared record utilities such as AT URI parsing and blob CID extraction.
- `src/lib/auth.tsx`: auth provider and OAuth session state.
- `src/lib/live-events.tsx`: live websocket event provider/hook.
- `src/lib/repo-utils.ts`: repo URL/path helpers, file type checks, formatting, recent repo storage, language colors, tree sorting, and shared pure repo helpers.
- `src/index.css`: global CSS plus explicit utility classes used to replace missing Tailwind arbitrary classes.

## Repo Route Pattern

Repo pages live under `RepoLayout` in `src/pages/repo/shared.tsx`.

- `RepoLayout` creates the shared repo query once for the `/:owner/:repo` route subtree.
- Child routes must call `useRepoQuery()` instead of creating their own repo query.
- `RepoFrame` owns the shared repo chrome, tab links, star control, recent-repo storage, and live event subscription.
- New repo-route behavior should usually go in a focused `src/pages/repo/*.tsx` file or a small helper beside it, not in `src/App.tsx` or `src/routes.tsx`.
- Keep route files from growing indefinitely. Move pure helpers into `*-helpers.ts` files and reusable display pieces into `src/components/repo.tsx`.

## API Module Pattern

Use domain imports for new code:

```ts
import { getRepoTree } from '../../lib/api/repos';
import { createIssue } from '../../lib/api/issues';
```

The facade `src/lib/api.ts` remains for compatibility with existing imports, but new implementation should go into the relevant domain module. Shared internals should stay in a narrowly scoped helper such as `src/lib/api/appview.ts`, `src/lib/api/backlinks.ts`, `src/lib/api/client.ts`, `src/lib/api/hydration.ts`, `src/lib/api/records.ts`, or `src/lib/api/stateful.ts`.

Guidelines:

- Do not add new implementation to `src/lib/api.ts`.
- Prefer keeping public types next to the domain module that exposes the API.
- Keep ATProto/PDS resolution rules centralized; repo UI record hydration should resolve the actor/PDS first and call the record endpoint against that PDS.
- Do not use `public.api.bsky.app` for repo `listRecords` or record hydration.

## Styling Source Of Truth

This frontend is intended to match the upstream Tangled app templates in:

```text
../tangled-upstream/appview/pages
```

Useful upstream files:

- `templates/layouts/base.html`
- `templates/layouts/repobase.html`
- `templates/repo/index.html`
- `templates/repo/blob.html`
- `templates/repo/issues/issues.html`
- `templates/repo/issues/fragments/issueListing.html`
- `templates/repo/pulls/pulls.html`
- `templates/repo/pulls/fragments/*`
- `static/tw.css`

When matching visuals, compare against those templates before inventing new
layout/styling.

## Upstream Comparison Workflow

For Tangled parity work, use upstream as the contract and compare details before
changing local components:

- Start from the matching upstream template in `../tangled-upstream/appview/pages/templates/...`, then check nearby Go/router files when behavior or icon names are data-driven.
- For repo chrome, `templates/layouts/repobase.html` is the main reference. Confirm header grouping, action buttons, tab icons, label spacing, font sizes, and vertical padding against that file before patching `src/pages/repo/shared.tsx`.
- For code/blob views, compare `templates/repo/index.html` and `templates/repo/blob.html` before changing `src/pages/repo/code.tsx`, `src/components/repo.tsx`, or file-view CSS.
- Treat screenshots as prompts to inspect upstream source, not as the only source of truth.
- Small differences such as `gap-*`, `py-*`, icon choice, and short-rev styling matter.
- Remove or hide upstream controls that are not implemented locally instead of shipping fake UI.
- External upstream-only affordances can link to `https://tangled.org`, such as repo stars and `/:owner/:repo/feed.atom`.

## Tailwind/CSS Pitfall

The checked-in `public/static/tw.css` does not include all arbitrary Tailwind
classes. Avoid relying on classes such as:

- `grid-cols-[...]`
- `[overflow-wrap:anywhere]`
- `dark:[&_code]:...`
- arbitrary safe-area or min-height utilities

If a class is not present in `public/static/tw.css`, add an explicit
`.untangled-*` rule in `src/index.css` instead.

## Repo UI Notes

- Preserve the `.untangled-shell` wrapper in `RootShell`; widening pages changes the app layout.
- Do not add a footer unless explicitly requested.
- File/tree ordering should be folders first, then files alphabetically. This is implemented in `sortedTreeEntries` in `src/lib/repo-utils.ts`.
- File/blob rendering uses `CodeView` in `src/components/repo.tsx`.
- PR diffs use `DiffView`, which parses unified patches into collapsible per-file panels and reuses `CodeView`.
- Repo overview and blob pages should resolve `HEAD` to the default branch for user-facing links when possible.
- Keep unimplemented upstream features visually inert rather than adding fake behavior.
- Repo commit lists should show author avatars like upstream. Upstream maps verified commit author emails to DIDs server-side; the local app can render `Avatar` when the commit author email is already a DID, otherwise use `PlaceholderAvatar`.
- The upstream placeholder avatar is a rounded gray background with a centered `user-round` icon. Use `PlaceholderAvatar` from `src/components/common.tsx` instead of a plain empty circle.
- Do not show a verified-looking commit badge unless signature validity is actually checked. Use the neutral commit badge/icon for commit hashes.
- Repo stars must count backlinks for both `sh.tangled.feed.star:subject.did` and legacy/alternate `sh.tangled.feed.star:subjectDid`, then dedupe hydrated refs.
- Star and unstar should be optimistic. Unstar deletes the current user's `sh.tangled.feed.star` record and should update local state without refetching.
- While star summary is loading, make the star control unclickable and show the upstream-style `loader-circle` spinner (`LoaderCircle` with `animate-spin` locally).
- Markdown rendering should not enable hard line breaks globally for README-style content; `marked` should use `breaks: false`.

## Editing Guidance

- Keep `src/App.tsx` small.
- Keep route declarations in `src/routes.tsx`.
- Keep global shell/topbar work in `src/layout.tsx`.
- Keep top-level non-repo pages in `src/pages`.
- Keep repo-route behavior in `src/pages/repo/*.tsx`.
- Keep repo-route pure helpers in nearby `src/pages/repo/*-helpers.ts` files.
- Keep generic display components in `src/components/common.tsx`.
- Keep repo-specific display components in `src/components/repo.tsx`.
- Keep shared pure repo helpers in `src/lib/repo-utils.ts`.
- Do not add large page logic back into `src/App.tsx`.
- Do not remove existing behavior while restructuring.
- Run `rtk npm run build` after meaningful changes.

## Current Size Guide

Approximate current file roles:

- `src/App.tsx`: tiny provider shell.
- `src/layout.tsx`: global topbar/shell.
- `src/routes.tsx`: route table.
- `src/pages/repo/code.tsx`: largest repo route; split further if code/blob logic grows.
- `src/pages/repo/pulls.tsx`: pull routes and patch/diff UI.
- `src/pages/repo/issues.tsx`: issue routes.
- `src/lib/api/*`: domain modules own their public implementations; shared plumbing is split across focused helper modules.


<!-- headroom:rtk-instructions -->
# RTK (Rust Token Killer) - Token-Optimized Commands

When running shell commands, **always prefix with `rtk`**. This reduces context
usage by 60-90% with zero behavior change. If rtk has no filter for a command,
it passes through unchanged — so it is always safe to use.

## Key Commands
```bash
# Git (59-80% savings)
rtk git status          rtk git diff            rtk git log

# Files & Search (60-75% savings)
rtk ls <path>           rtk read <file>         rtk grep <pattern>
rtk find <pattern>      rtk diff <file>

# Test (90-99% savings) — shows failures only
rtk pytest tests/       rtk cargo test          rtk test <cmd>

# Build & Lint (80-90% savings) — shows errors only
rtk tsc                 rtk lint                rtk cargo build
rtk prettier --check    rtk mypy                rtk ruff check

# Analysis (70-90% savings)
rtk err <cmd>           rtk log <file>          rtk json <file>
rtk summary <cmd>       rtk deps                rtk env

# GitHub (26-87% savings)
rtk gh pr view <n>      rtk gh run list         rtk gh issue list

# Infrastructure (85% savings)
rtk docker ps           rtk kubectl get         rtk docker logs <c>

# Package managers (70-90% savings)
rtk pip list            rtk pnpm install        rtk npm run <script>
```

## Rules
- In command chains, prefix each segment: `rtk git add . && rtk git commit -m "msg"`
- For debugging, use raw command without rtk prefix
- `rtk proxy <cmd>` runs command without filtering but tracks usage
<!-- /headroom:rtk-instructions -->
