Imported from izumi0uu/better-github-stars-manager (
AGENTS.md). Install upstream withnpx skills add izumi0uu/better-github-stars-manager. Copyright stays with the author.
GitHub Stars Manager Agent Guide
Keep this file short and practical. Add rules here only when they are core to the repo or fix a repeated mistake.
Scope
- This repo is a Chrome extension that augments the GitHub Stars page with local search, filters, sorting, tags, notes, and sync helpers.
- Prefer repo-specific facts over generic browser-extension assumptions.
- If an API behavior is unclear or recently changed, check official docs before editing code.
Branch Policy
masteris the sole long-lived development and release branch.- Feature branches, including
feat/firefox, are temporary integration branches and must merge back intomaster; do not treat them as future development lines.
Key Paths
src/storage/db.ts: IndexedDB schema and version bumps.src/types/index.ts: shared domain types and config shape.src/auth/auth-store.ts:chrome.storage.localconfig normalization.src/api/github-star-source.ts: GitHub REST/GraphQL sync logic.src/upgrades/backfill-state.tsandsrc/upgrades/tasks.ts: one-shot feature/data backfills.src/background/index.ts: backfill orchestration and sync entrypoints.tests/unit,tests/integration,tests/regressions,tests/runtime: test layers.
Contributor Workflow
- Before implementation or debugging, consult
CONTRIBUTING.en.md(orCONTRIBUTING.md) for the current build and verification commands. - Cubby Agent work must also consult
docs/en/cubby-agent.md(ordocs/zh/cubby-agent.md) and use the documented diagnostics entry points. Development diagnostics builds are never release evidence.
Source Of Truth
- IndexedDB is the source of truth for bulk repo data and annotations:
stars,tags,tagMeta. chrome.storage.localis only for lightweight config and UI state: token metadata, locale, theme, onboarding, sync progress, backfill state, and user preferences.- GitHub is the source of truth for repository metadata such as
archived,fork,pushed_at,created_at, andstarred_at. - Do not infer remote repo state in the UI when the sync layer can persist the canonical field.
Data Rules
- UI-only behavior changes do not need a storage upgrade.
- Unless
package.jsonversion has already changed in the current worktree, treat new feature work as unreleased. Do not add compatibility code for hypothetical previously shipped users unless the user explicitly says the behavior has already been released. - Local dev builds and feature-branch experiments are not releases. If an unreleased migration, backfill, or schema change is revised before shipping, edit the existing unreleased upgrade/backfill in place instead of inventing a new version/id just to support local development data.
- A new lightweight preference in
Configshould be added with a safe default and normalized on read. This usually does not need a DB bump. - A new persisted field on
Star,Tag, orTagMetarequires:- updating
src/types/index.ts - bumping Dexie schema in
src/storage/db.tsif the stored shape changes - keeping legacy-row compatibility, usually by treating old
undefinedvalues as missing
- updating
- New remote-derived metadata for existing rows should usually use a feature/data backfill, not an app-version migration.
- Backfills are keyed by capability, not extension version. Once a one-shot backfill is done, it should stay done unless the task definition itself changes.
- Do not run a full sync on every extension update. Full sync is for data completeness gaps that incremental sync or lazy hydration cannot close reliably.
Upgrade Decision Rules
- Use a Dexie version bump when stored IndexedDB shape or indexes change.
- Use config normalization when only
chrome.storage.localshape changes. - Add a backfill task when old local rows are missing data required by a new feature.
- Prefer lazy remote hydration when missing data can be filled gradually without blocking correctness.
- Prefer a full-sync backfill only when the feature needs library-wide consistency and there is no safe incremental path.
Sync And GitHub API Rules
- Keep incremental sync and rescan aligned with authenticated REST
GET /user/starred; that endpoint matches the current cursor and tombstone model. - Keep full sync, incremental sync, and rescan aligned with authenticated REST
GET /user/starredwhenever the required metadata already exists there. archivedmust come from GitHub metadata (repo.archivedor GraphQLisArchived) and be stored locally; never guess it from UI state.- Repository creation time should come from GitHub repo metadata (
created_at/createdAt), not from releases, tags, or first-star heuristics. - Preserve tombstone semantics. By default the product operates on currently starred repos, not historical unstarred rows.
GitHub Docs To Trust
- REST starring endpoints:
https://docs.github.com/v3/activity/starring - REST repositories endpoints:
https://docs.github.com/rest/repos/repos
Privacy And External Context
- Never put personal information in tracked files, including real usernames, names, email addresses, local home-directory paths, account data, tokens, or screenshots and fixtures derived from a personal account. The only exception is a screenshot that the repository maintainer supplied and explicitly approved for public release; even then, it must not expose tokens, email addresses, local paths, private repository data, or other non-public account data. Use synthetic values such as
octocat,user@example.com, and repository-relative paths everywhere else. - Never copy issue, pull-request, Jira, support-ticket, chat, or other external-work-item content into product code, tests, fixtures, comments, logs, screenshots, generated artifacts, or documentation. The maintainer-approved public screenshot exception above may include public GitHub repository, issue, or pull-request text already visible in the product UI; it does not cover Jira, support, chat, private repositories, private work items, or copied external text elsewhere in the repository. Translate every other external requirement into generic product behavior and terminology; keep external identifiers, URLs, customer data, reporter details, and verbatim text out of the repository.
- Before committing, scan every changed tracked artifact, including binary assets and metadata, for personal information and external-work-item residue.
Testing And Done Criteria
- Always run
pnpm typecheckafter code changes. - Run the smallest relevant test layer first:
pnpm test:logicfor pure logic and filter/sort behaviorpnpm test:integrationfor query/store integrationpnpm test:regressionsfor sync/storage compatibility changespnpm test:runtimefor extension runtime smoke coverage
- Add a regression test when changing sync semantics, storage compatibility, migration/backfill logic, or GitHub data mapping.
- Name new tests, suites, and replay env prefixes by product surface or behavior, not priority or phase labels. Use names like
query-fuzz,tag-store-fuzz, orBACKGROUND_RUNNER_FUZZ. - For docs-only changes, code tests are optional.
- Do not add automated tests that read Markdown files to assert prose, headings, links, or section layout. Test the owning runtime behavior or machine-readable contract instead; review published documentation directly.
- Do not add automated tests solely to assert exact i18n wording or descriptive UI/documentation copy. When copy changes, update or remove stale text assertions; test the owning behavior, accessibility semantics, or machine-readable contract instead.
- New tests MUST fail when the behavior under test is removed. Prefer injected dependency and real handler/component behavior tests over assertions that read source files and match implementation strings or regular expressions. Static source checks are reserved for packaging, security, generated-artifact, or CSS-structure constraints that cannot be exercised behaviorally; keep them narrow and state the boundary they protect.
- Do not duplicate the same descriptive copy contract across i18n, component, and Options tests. Keep exact copy assertions only when wording is itself a security, privacy, authorization, error-sanitization, accessibility-name, or externally documented protocol contract; otherwise assert state, role, selector, callback, error code, URL, or structured payload.
- Rejection assertions MUST check a stable error type, code, or message when one exists. Avoid bare
toThrow(),assert.throws(), and truthiness-only assertions when a more specific observable contract is available.
Documentation
- Keep
docs/for user-facing guides, privacy policies, Chrome Web Store material, and other published product documentation. - Internal workflows, implementation history, and superseded plans are research context, not current public contracts. Keep them out of
docs/and do not cite them as implementation authority.
Comment Rules
- Write comments when they materially improve maintainability.
- Good comments briefly explain what a function or module does, what problem it solves, or the key constraint/invariant behind it.
- Comments should focus on intent, purpose, boundaries, and
why; avoid line-by-line narration ofwhatthe next lines already say. - Prefer one short block comment above the tricky code. Do not add multi-paragraph, sectioned, or doc-style comments inside product code.
- If a comment starts carrying design history, tradeoff analysis, or workflow notes, move that material to tests or docs and leave at most a short pointer.
- During refactors, update or delete stale comments aggressively. A partly true comment is worse than no comment.
Maintenance Of This File
- Keep this file concise. Link to code paths or dedicated docs instead of turning this into a handbook.
- Update this file when the same repo-specific mistake or review comment appears more than once.