{"owner":"keybase","repo":"client","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md",".github/copilot-instructions.md"],"skills":{"AGENTS.md":"# Repo Notes\n\n- This repo uses React Compiler. Assume React Compiler patterns are enabled when editing React code, and avoid adding `useMemo`/`useCallback` by default unless they are clearly needed for correctness or compatibility with existing code.\n- Functions returned from `React.useEffectEvent(...)` are special stable event functions, not normal callback dependencies. Do not include them in dependency arrays; instead, depend on the real reactive values around the effect/callback.\n- Do not read or write `ref.current` during render. Access refs only from effects, event handlers, or other post-render code; if render needs to know whether async data is current, store a request key/version in state or derive it from props/state.\n- Treat React mount/unmount effects as Strict-Mode-safe. Do not assume a component only mounts once; route-driven async startup and cleanup logic must be idempotent and must not leave refs or guards stuck false after a dev remount.\n- Do not add `mountedRef`/`isMountedRef` guards just to suppress local React state updates after unmount; those updates are already a no-op in modern React. Only use a guard when you need to reject stale async results or protect a real side effect, and prefer request/version guards when they express the intent more directly.\n- If a mount guard is truly needed, set the ref to `true` inside the effect body and set it to `false` in cleanup. Never rely on `useRef(true)` alone across the component lifetime, because Strict Mode remounts can leave the guard stuck `false` and silently drop async results.\n- When a component reads multiple adjacent values from the same store hook, prefer a consolidated selector with `C.useShallow(...)` instead of multiple separate subscriptions.\n- Keep types accurate. Do not use casts or misleading annotations to mask a real type mismatch just to get around an issue; fix the type or fix the implementation.\n- When importing `@/constants/types` as `T`, check whether the file uses `T.*` as values, not just types. If you add calls like `T.RPCGen.*`, `T.Chat.*`, `T.Teams.*`, or any other runtime `T.*` access, do not keep `import type * as T ...`; switch it to a value import.\n- Do not add new exported functions, types, or constants unless they are required outside the file. Prefer file-local helpers for one-off implementation details and tests.\n- Under `shared/`, non-test TypeScript source files should use the `.tsx` extension.\n- Do not edit lockfiles by hand. They are generated artifacts. If you cannot regenerate one locally, leave it unchanged.\n- Never disable lints to address lint failures. Fix the underlying issue instead.\n- Components must not mutate Zustand stores directly with `useXState.setState`, `getState()`-based writes, or similar ad hoc store mutation. If a component needs to affect store state, route it through a store dispatch action or move the state out of the store.\n- For server-owned state such as badges, Gregor-driven UI state, and other engine-fed state, prefer reflecting the latest server state instead of masking problems with optimistic local mutations. Do not add local state writes that make the UI look correct while drifting from what the server has actually told us.\n- When a Zustand store already uses `resetState: Z.defaultReset`, prefer calling `dispatch.resetState()` for full resets instead of manually reassigning each initial field in another dispatch action.\n- During refactors, do not delete existing guards, conditionals, or platform/test-specific behavior unless you have proven they are dead and the user asked for that behavior change. Port checks like `androidIsTestDevice` forward into the new code path instead of silently dropping them.\n- When addressing PR or review feedback, including bot or lint-style suggestions, do not apply it mechanically. Verify that the reported issue is real in this codebase and that the proposed fix is consistent with repo rules and improves correctness, behavior, or maintainability before making changes.\n- When a repo plan starts with a test or regression-coverage chunk, do that chunk before implementation chunks. Do not skip the first coverage phase; if local toolchain constraints prevent adding or running the planned tests, stop and tell the user before moving on.\n- When working from a repo plan or checklist such as `PLAN.md`, update the checklist in the same change and mark implemented items done before you finish.\n","CLAUDE.md":"## Rules\n- No `Co-Authored-By` in commits. Ever.\n- Never interact with the Electron app or iOS simulator (screenshots, driving UI, debug ports) without asking first. The user drives and takes screenshots.\n- Use `--no-ext-diff` with `git diff` (and `git show`/`git log -p`) so external diff tools don't hijack output.\n- \"Was working before\" = base branch, not previous commit. Base is normally `master`. Always run `gh pr view --json baseRefName` to confirm before any `git diff` or `git log` comparison.\n- Never use `npm`. Always `yarn`.\n- Never silently drop features/behavior — ask first, present options.\n- In tests/stories, use `testuser` / `testuser-mac` as placeholder usernames — never real usernames like `chrisnojima`.\n- No DOM elements (`<div>`, `<span>`, etc.) in plain `.tsx` files — use `Kb.*`. Guard desktop-only DOM with `Styles.isMobile`.\n- Temp files go in `/tmp/`.\n- Remove unused code when editing: styles, imports, vars, params, dead helpers.\n- Comments: no refactoring notes; only add when context isn't obvious from code.\n- Exact versions in `package.json` (no `^`/`~`).\n- Keep `react`, `react-dom`, `react-native`, `@react-native/*` in sync with Expo SDK.\n- When updating deps: edit `package.json` → `yarn` → `yarn ios:pod:install`.\n- After editing `rnmodules/react-native-kb/`: run `yarn sync:kb-modules` before building. `shared/node_modules/react-native-kb` is a copy, not a symlink, and Xcode compiles the copy — skipping this builds stale sources and reports errors against code you already fixed. `rnmodules/kb-common/` needs no sync (the Podfile references it by path).\n- When updating `electron`: run `shared/desktop/extract-electron-shasums.sh <version>`.\n- Never patch `react-native` itself (patch-package or node_modules edits): we use prebuilt RN core and don't compile its source, so native-side patches never take effect. Work around RN core bugs in app code.\n\n## Working Directory\nRepo root is `client/`. TS source lives in `shared/`. Always use absolute paths for file ops. For Bash: always `cd shared/` first.\n\n## Superpowers\n- Plans created by superpowers skills go into `plans/` at the repo root.\n- Never commit plan/spec/design docs. They're scratch for the current effort — leave them untracked and delete them when the work lands.\n\n## Validation\nAfter TS changes (from `shared/`): `yarn lint:all` (= `yarn lint` && `yarn lint:bailouts` && `yarn tsc`). Plain `yarn lint` is eslint only and does NOT catch react-compiler bailouts — no compiler rule is wired into `eslint.config.mjs`, so bailouts only surface via `lint:bailouts`. `lint:bailouts` also flags components the compiler cannot name (an `isMobile ? arrow : arrow` ternary is never compiled at all, so nothing in it is memoized — name both branches instead), and memo scopes keyed on the whole props object (a `props.x` read inside a callback, or a destructure below one, makes the compiler key on `props` itself, so the cache never hits — read every prop through one destructure at the top, above every callback). Repo baseline is 0 bailouts and 0 whole-props deps; keep it there. When debugging visually, skip until fix is confirmed. Never delete the ESLint cache.\n",".github/copilot-instructions.md":"# Copilot Instructions\n\n## React\n\n- We use modern React (19+). Contexts are rendered directly as providers: `<MyContext value={...}>`, not `<MyContext.Provider value={...}>`. Do not suggest adding `.Provider`.\n- We use the React Compiler. Components and hooks are memoized automatically:\n  - Do not suggest adding `useMemo`, `useCallback`, or `React.memo` for performance — the compiler handles it.\n  - Avoid patterns that make the compiler bail out, e.g. `try`/`catch` in a component or hook body (move it into a helper function instead).\n  - `'use no memo'` directives are intentional opt-outs; do not flag or remove them.\n"},"files":{"AGENTS.md":"# Repo Notes\n\n- This repo uses React Compiler. Assume React Compiler patterns are enabled when editing React code, and avoid adding `useMemo`/`useCallback` by default unless they are clearly needed for correctness or compatibility with existing code.\n- Functions returned from `React.useEffectEvent(...)` are special stable event functions, not normal callback dependencies. Do not include them in dependency arrays; instead, depend on the real reactive values around the effect/callback.\n- Do not read or write `ref.current` during render. Access refs only from effects, event handlers, or other post-render code; if render needs to know whether async data is current, store a request key/version in state or derive it from props/state.\n- Treat React mount/unmount effects as Strict-Mode-safe. Do not assume a component only mounts once; route-driven async startup and cleanup logic must be idempotent and must not leave refs or guards stuck false after a dev remount.\n- Do not add `mountedRef`/`isMountedRef` guards just to suppress local React state updates after unmount; those updates are already a no-op in modern React. Only use a guard when you need to reject stale async results or protect a real side effect, and prefer request/version guards when they express the intent more directly.\n- If a mount guard is truly needed, set the ref to `true` inside the effect body and set it to `false` in cleanup. Never rely on `useRef(true)` alone across the component lifetime, because Strict Mode remounts can leave the guard stuck `false` and silently drop async results.\n- When a component reads multiple adjacent values from the same store hook, prefer a consolidated selector with `C.useShallow(...)` instead of multiple separate subscriptions.\n- Keep types accurate. Do not use casts or misleading annotations to mask a real type mismatch just to get around an issue; fix the type or fix the implementation.\n- When importing `@/constants/types` as `T`, check whether the file uses `T.*` as values, not just types. If you add calls like `T.RPCGen.*`, `T.Chat.*`, `T.Teams.*`, or any other runtime `T.*` access, do not keep `import type * as T ...`; switch it to a value import.\n- Do not add new exported functions, types, or constants unless they are required outside the file. Prefer file-local helpers for one-off implementation details and tests.\n- Under `shared/`, non-test TypeScript source files should use the `.tsx` extension.\n- Do not edit lockfiles by hand. They are generated artifacts. If you cannot regenerate one locally, leave it unchanged.\n- Never disable lints to address lint failures. Fix the underlying issue instead.\n- Components must not mutate Zustand stores directly with `useXState.setState`, `getState()`-based writes, or similar ad hoc store mutation. If a component needs to affect store state, route it through a store dispatch action or move the state out of the store.\n- For server-owned state such as badges, Gregor-driven UI state, and other engine-fed state, prefer reflecting the latest server state instead of masking problems with optimistic local mutations. Do not add local state writes that make the UI look correct while drifting from what the server has actually told us.\n- When a Zustand store already uses `resetState: Z.defaultReset`, prefer calling `dispatch.resetState()` for full resets instead of manually reassigning each initial field in another dispatch action.\n- During refactors, do not delete existing guards, conditionals, or platform/test-specific behavior unless you have proven they are dead and the user asked for that behavior change. Port checks like `androidIsTestDevice` forward into the new code path instead of silently dropping them.\n- When addressing PR or review feedback, including bot or lint-style suggestions, do not apply it mechanically. Verify that the reported issue is real in this codebase and that the proposed fix is consistent with repo rules and improves correctness, behavior, or maintainability before making changes.\n- When a repo plan starts with a test or regression-coverage chunk, do that chunk before implementation chunks. Do not skip the first coverage phase; if local toolchain constraints prevent adding or running the planned tests, stop and tell the user before moving on.\n- When working from a repo plan or checklist such as `PLAN.md`, update the checklist in the same change and mark implemented items done before you finish.\n","CLAUDE.md":"## Rules\n- No `Co-Authored-By` in commits. Ever.\n- Never interact with the Electron app or iOS simulator (screenshots, driving UI, debug ports) without asking first. The user drives and takes screenshots.\n- Use `--no-ext-diff` with `git diff` (and `git show`/`git log -p`) so external diff tools don't hijack output.\n- \"Was working before\" = base branch, not previous commit. Base is normally `master`. Always run `gh pr view --json baseRefName` to confirm before any `git diff` or `git log` comparison.\n- Never use `npm`. Always `yarn`.\n- Never silently drop features/behavior — ask first, present options.\n- In tests/stories, use `testuser` / `testuser-mac` as placeholder usernames — never real usernames like `chrisnojima`.\n- No DOM elements (`<div>`, `<span>`, etc.) in plain `.tsx` files — use `Kb.*`. Guard desktop-only DOM with `Styles.isMobile`.\n- Temp files go in `/tmp/`.\n- Remove unused code when editing: styles, imports, vars, params, dead helpers.\n- Comments: no refactoring notes; only add when context isn't obvious from code.\n- Exact versions in `package.json` (no `^`/`~`).\n- Keep `react`, `react-dom`, `react-native`, `@react-native/*` in sync with Expo SDK.\n- When updating deps: edit `package.json` → `yarn` → `yarn ios:pod:install`.\n- After editing `rnmodules/react-native-kb/`: run `yarn sync:kb-modules` before building. `shared/node_modules/react-native-kb` is a copy, not a symlink, and Xcode compiles the copy — skipping this builds stale sources and reports errors against code you already fixed. `rnmodules/kb-common/` needs no sync (the Podfile references it by path).\n- When updating `electron`: run `shared/desktop/extract-electron-shasums.sh <version>`.\n- Never patch `react-native` itself (patch-package or node_modules edits): we use prebuilt RN core and don't compile its source, so native-side patches never take effect. Work around RN core bugs in app code.\n\n## Working Directory\nRepo root is `client/`. TS source lives in `shared/`. Always use absolute paths for file ops. For Bash: always `cd shared/` first.\n\n## Superpowers\n- Plans created by superpowers skills go into `plans/` at the repo root.\n- Never commit plan/spec/design docs. They're scratch for the current effort — leave them untracked and delete them when the work lands.\n\n## Validation\nAfter TS changes (from `shared/`): `yarn lint:all` (= `yarn lint` && `yarn lint:bailouts` && `yarn tsc`). Plain `yarn lint` is eslint only and does NOT catch react-compiler bailouts — no compiler rule is wired into `eslint.config.mjs`, so bailouts only surface via `lint:bailouts`. `lint:bailouts` also flags components the compiler cannot name (an `isMobile ? arrow : arrow` ternary is never compiled at all, so nothing in it is memoized — name both branches instead), and memo scopes keyed on the whole props object (a `props.x` read inside a callback, or a destructure below one, makes the compiler key on `props` itself, so the cache never hits — read every prop through one destructure at the top, above every callback). Repo baseline is 0 bailouts and 0 whole-props deps; keep it there. When debugging visually, skip until fix is confirmed. Never delete the ESLint cache.\n",".github/copilot-instructions.md":"# Copilot Instructions\n\n## React\n\n- We use modern React (19+). Contexts are rendered directly as providers: `<MyContext value={...}>`, not `<MyContext.Provider value={...}>`. Do not suggest adding `.Provider`.\n- We use the React Compiler. Components and hooks are memoized automatically:\n  - Do not suggest adding `useMemo`, `useCallback`, or `React.memo` for performance — the compiler handles it.\n  - Avoid patterns that make the compiler bail out, e.g. `try`/`catch` in a component or hook body (move it into a helper function instead).\n  - `'use no memo'` directives are intentional opt-outs; do not flag or remove them.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Repo Notes\n\n- This repo uses React Compiler. Assume React Compiler patterns are enabled when editing React code, and avoid adding `useMemo`/`useCallback` by default unless they are clearly needed for correctness or compatibility with existing code.\n- Functions returned from `React.useEffectEvent(...)` are special stable event functions, not normal callback dependencies. Do not include them in dependency arrays; instead, depend on the real reactive values around the effect/callback.\n- Do not read or write `ref.current` during render. Access refs only from effects, event handlers, or other post-render code; if render needs to know whether async data is current, store a request key/version in state or derive it from props/state.\n- Treat React mount/unmount effects as Strict-Mode-safe. Do not assume a component only mounts once; route-driven async startup and cleanup logic must be idempotent and must not leave refs or guards stuck false after a dev remount.\n- Do not add `mountedRef`/`isMountedRef` guards just to suppress local React state updates after unmount; those updates are already a no-op in modern React. Only use a guard when you need to reject stale async results or protect a real side effect, and prefer request/version guards when they express the intent more directly.\n- If a mount guard is truly needed, set the ref to `true` inside the effect body and set it to `false` in cleanup. Never rely on `useRef(true)` alone across the component lifetime, because Strict Mode remounts can leave the guard stuck `false` and silently drop async results.\n- When a component reads multiple adjacent values from the same store hook, prefer a consolidated selector with `C.useShallow(...)` instead of multiple separate subscriptions.\n- Keep types accurate. Do not use casts or misleading annotations to mask a real type mismatch just to get around an issue; fix the type or fix the implementation.\n- When importing `@/constants/types` as `T`, check whether the file uses `T.*` as values, not just types. If you add calls like `T.RPCGen.*`, `T.Chat.*`, `T.Teams.*`, or any other runtime `T.*` access, do not keep `import type * as T ...`; switch it to a value import.\n- Do not add new exported functions, types, or constants unless they are required outside the file. Prefer file-local helpers for one-off implementation details and tests.\n- Under `shared/`, non-test TypeScript source files should use the `.tsx` extension.\n- Do not edit lockfiles by hand. They are generated artifacts. If you cannot regenerate one locally, leave it unchanged.\n- Never disable lints to address lint failures. Fix the underlying issue instead.\n- Components must not mutate Zustand stores directly with `useXState.setState`, `getState()`-based writes, or similar ad hoc store mutation. If a component needs to affect store state, route it through a store dispatch action or move the state out of the store.\n- For server-owned state such as badges, Gregor-driven UI state, and other engine-fed state, prefer reflecting the latest server state instead of masking problems with optimistic local mutations. Do not add local state writes that make the UI look correct while drifting from what the server has actually told us.\n- When a Zustand store already uses `resetState: Z.defaultReset`, prefer calling `dispatch.resetState()` for full resets instead of manually reassigning each initial field in another dispatch action.\n- During refactors, do not delete existing guards, conditionals, or platform/test-specific behavior unless you have proven they are dead and the user asked for that behavior change. Port checks like `androidIsTestDevice` forward into the new code path instead of silently dropping them.\n- When addressing PR or review feedback, including bot or lint-style suggestions, do not apply it mechanically. Verify that the reported issue is real in this codebase and that the proposed fix is consistent with repo rules and improves correctness, behavior, or maintainability before making changes.\n- When a repo plan starts with a test or regression-coverage chunk, do that chunk before implementation chunks. Do not skip the first coverage phase; if local toolchain constraints prevent adding or running the planned tests, stop and tell the user before moving on.\n- When working from a repo plan or checklist such as `PLAN.md`, update the checklist in the same change and mark implemented items done before you finish.\n","category":"root","tokens":1108},{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"## Rules\n- No `Co-Authored-By` in commits. Ever.\n- Never interact with the Electron app or iOS simulator (screenshots, driving UI, debug ports) without asking first. The user drives and takes screenshots.\n- Use `--no-ext-diff` with `git diff` (and `git show`/`git log -p`) so external diff tools don't hijack output.\n- \"Was working before\" = base branch, not previous commit. Base is normally `master`. Always run `gh pr view --json baseRefName` to confirm before any `git diff` or `git log` comparison.\n- Never use `npm`. Always `yarn`.\n- Never silently drop features/behavior — ask first, present options.\n- In tests/stories, use `testuser` / `testuser-mac` as placeholder usernames — never real usernames like `chrisnojima`.\n- No DOM elements (`<div>`, `<span>`, etc.) in plain `.tsx` files — use `Kb.*`. Guard desktop-only DOM with `Styles.isMobile`.\n- Temp files go in `/tmp/`.\n- Remove unused code when editing: styles, imports, vars, params, dead helpers.\n- Comments: no refactoring notes; only add when context isn't obvious from code.\n- Exact versions in `package.json` (no `^`/`~`).\n- Keep `react`, `react-dom`, `react-native`, `@react-native/*` in sync with Expo SDK.\n- When updating deps: edit `package.json` → `yarn` → `yarn ios:pod:install`.\n- After editing `rnmodules/react-native-kb/`: run `yarn sync:kb-modules` before building. `shared/node_modules/react-native-kb` is a copy, not a symlink, and Xcode compiles the copy — skipping this builds stale sources and reports errors against code you already fixed. `rnmodules/kb-common/` needs no sync (the Podfile references it by path).\n- When updating `electron`: run `shared/desktop/extract-electron-shasums.sh <version>`.\n- Never patch `react-native` itself (patch-package or node_modules edits): we use prebuilt RN core and don't compile its source, so native-side patches never take effect. Work around RN core bugs in app code.\n\n## Working Directory\nRepo root is `client/`. TS source lives in `shared/`. Always use absolute paths for file ops. For Bash: always `cd shared/` first.\n\n## Superpowers\n- Plans created by superpowers skills go into `plans/` at the repo root.\n- Never commit plan/spec/design docs. They're scratch for the current effort — leave them untracked and delete them when the work lands.\n\n## Validation\nAfter TS changes (from `shared/`): `yarn lint:all` (= `yarn lint` && `yarn lint:bailouts` && `yarn tsc`). Plain `yarn lint` is eslint only and does NOT catch react-compiler bailouts — no compiler rule is wired into `eslint.config.mjs`, so bailouts only surface via `lint:bailouts`. `lint:bailouts` also flags components the compiler cannot name (an `isMobile ? arrow : arrow` ternary is never compiled at all, so nothing in it is memoized — name both branches instead), and memo scopes keyed on the whole props object (a `props.x` read inside a callback, or a destructure below one, makes the compiler key on `props` itself, so the cache never hits — read every prop through one destructure at the top, above every callback). Repo baseline is 0 bailouts and 0 whole-props deps; keep it there. When debugging visually, skip until fix is confirmed. Never delete the ESLint cache.\n","category":"root","tokens":793},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","title":"copilot-instructions.md","content":"# Copilot Instructions\n\n## React\n\n- We use modern React (19+). Contexts are rendered directly as providers: `<MyContext value={...}>`, not `<MyContext.Provider value={...}>`. Do not suggest adding `.Provider`.\n- We use the React Compiler. Components and hooks are memoized automatically:\n  - Do not suggest adding `useMemo`, `useCallback`, or `React.memo` for performance — the compiler handles it.\n  - Avoid patterns that make the compiler bail out, e.g. `try`/`catch` in a component or hook body (move it into a helper function instead).\n  - `'use no memo'` directives are intentional opt-outs; do not flag or remove them.\n","category":".github","tokens":157}]}