# 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, branch pills, and repo skeletons.
- `src/components/code-view.tsx`: code and diff presentation components, highlighting helper functions, `CodeView`, `DiffView`, and `PullDiffView`.
- `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/code-view.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`.

## Local UI Style

Upstream Tangled templates are the baseline, but Untangled should also preserve
the local design language already present in the Solid app. Before copying an
upstream class literally, compare nearby local pages and shared components.

- Favor a quiet, dense tool UI: compact spacing, small radii, restrained
  borders, and flat page sections. Avoid marketing-style cards, oversized
  type, decorative gradients, and unnecessary nested panels.
- When extending an existing multi-section page, copy its spacing rhythm before
  inventing a new one. Match the surrounding stack gaps, heading margins,
  description spacing, and form row density so sibling sections feel authored
  together rather than assembled from separate patterns.
- Top-level route titles are usually plain lowercase labels. Use uppercase
  tracking only for compact metadata labels, table/list section labels, or
  places where the local surrounding UI already uses that treatment.
- Action labels, nav labels, badges, pagination, and small utility links are
  generally lowercase. Keep this consistent unless the surrounding local
  component clearly uses title case.
- Prefer established primitives (`btn`, `btn-create`, `btn-flat`,
  `buttonStyles`, `StateBadge`, `ToggleButton`) over custom button and badge
  stacks. Preserve their icon sizes, min-heights, padding, hover behavior, and
  inner icon/text grouping.
- Icon buttons and icon+text actions should use Lucide icons already used in
  the app. Keep icons visible, aligned, and sized consistently with adjacent
  controls.
- Badges shown next to controls should match the controls' visual density and
  height. Avoid badge styles that look like separate one-off pills unless a
  shared badge component already does that.
- For repeated control rows such as checkboxes, toggles, or small preferences,
  reuse the same DOM structure and utility classes as nearby controls instead
  of building a visually similar variant. Small markup differences often create
  visible spacing drift even when the text and colors match.
- Prefer lightweight interaction patterns for local preferences: save
  immediately when the change is unambiguous, keep temporary drafts only where
  validation requires it, and avoid extra cards or explicit save actions unless
  the setting genuinely needs batching or confirmation.
- Dialogs and destructive/creation popovers should feel like app chrome, not a
  page section: center modal dialogs in the viewport, use a real backdrop when
  blocking interaction, and prefer spacing over extra separator lines when the
  header/body relationship is already clear.
- When Tailwind utilities are missing from `public/static/tw.css`, add a small
  explicit `.untangled-*` rule in `src/index.css` rather than relying on an
  unavailable arbitrary class.

## 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/code-view.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` and `src/components/code-view.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 -->
