37 Commits

Author SHA1 Message Date
Цвылев Александр Вадимович 22f7fd25ff perf(metadata): bound bulk re-enrich concurrency
A large batch selection fired hundreds of simultaneous requests (each also
enqueuing a worker job). Run them in batches of BULK_CONCURRENCY.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 10:53:49 +03:00
Цвылев Александр Вадимович 5b31e77b1e perf(radio): bound queue backlog and exclude list
An infinite radio appends forever: cap the queue at QUEUE_CAP, trimming only
already-played entries (keep KEEP_BEHIND for prev-nav), and send only the most
recent EXCLUDE_WINDOW ids as "don't repeat" so the request and server NOT IN
don't grow unbounded.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 10:53:48 +03:00
Цвылев Александр Вадимович 7f116f0657 fix(player): clean up audio listeners + keep position on URL change
- register named listeners with cleanup so a remount (StrictMode) can't leave
  duplicates double-dispatching
- when the same track's URL changes (quality switch or token refresh), resume
  at the current position instead of restarting from 0

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 10:53:48 +03:00
Цвылев Александр Вадимович ac6b76bf98 feat(radio): wire radio + similarity into the queue (A11/B6, §6.5)
"Start radio" in the track menu seeds the queue from a track; RadioController
(headless, in AppShell) tops it up via /radio/next as it drains. QueuePanel's
radio scaffolding is now live: the exploration slider drives familiar<->new and
each entry shows its reason ("why this is playing"). Adds the radio endpoints
(start/next/similar), radio context + actions on the queue slice, and the pick->
entry mapper. Degrades to metadata picks while ML is offline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 02:40:13 +03:00
Цвылев Александр Вадимович e45ef785cf feat(player): stream at the chosen quality + per-track optimize (§6.6)
The Playback quality setting now drives streaming: getStreamUrl appends
?quality= and useAudioPlayer feeds the server-synced streamQuality, so the
backend transcodes on demand (miss → original). Adds an optimizeTrack mutation
and an Optimize action in the metadata editor to warm a track's rendition.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 21:22:59 +03:00
Цвылев Александр Вадимович 9d88d70be0 feat(player): Now Playing overlay + synced lyrics panel (A1/A11, §6.7)
Full-screen overlay expanded from the persistent player: big artwork or a
Lyrics tab. Synced (LRC) lyrics highlight the active line by playback position,
auto-scroll, and seek on tap; plain text is the fallback; missing lyrics offers
a re-fetch. Adds lyrics endpoint + LRC parser + isNowPlayingOpen player state.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 21:04:39 +03:00
Цвылев Александр Вадимович 6efbf4b68b feat(metadata): wire batch editor over metadata-status buckets (A7)
/metadata/batch?status=pending|failed edits a whole bucket: bulk re-enrich
(AcoustID/MusicBrainz) and stamp common fields onto the selection, with a
select-list and per-track checkboxes. Storage Maintenance failed/missing tabs
link straight into it, closing the A6→A7 flow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 20:50:04 +03:00
Цвылев Александр Вадимович 87fac7a5a1 feat(admin): wire instance health panel + settings instance (A9/A10)
AdminInstance shows backing-service health (db/redis/ml), read-only source
status (env-configured), and a library reindex with graceful handling when no
indexable source exists. InstanceSettings shows the active instance and offers
switch/sign-out to /connect. Adds getServices/getSources/reindex endpoints.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 20:43:27 +03:00
Цвылев Александр Вадимович 3eba3701d0 feat(storage): wire Storage Maintenance screen (A6)
Duplicates / failed / missing-metadata tabs (paginated, reusing TrackRow) plus
admin orphan-file cleanup. Adds getDuplicates/getBrokenFiles/getMissingMetadata/
runCleanup endpoints and a DuplicateGroup type; drops the dead scanStorage/
deleteTrackFile stubs that had no backend route.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 20:42:05 +03:00
Цвылев Александр Вадимович 28d9e59e34 feat(admin): wire Admin Users management (A9)
User list with create dialog, role toggle, (de)activate, and reset-password;
self-lockout guard. Adds getUser/resetPassword endpoints, an isActive field on
the User type, and en/ru strings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 20:40:36 +03:00
Цвылев Александр Вадимович 57044dabba feat(settings): wire Playback + Scrobbling panels to the backend
Adds src/api/endpoints/settings.ts (getSettings/updateSettings,
getScrobbling/updateScrobbling) plus AppSettings/ScrobblingConfig types
and a Settings cache tag. Replaces the "coming soon" scaffolds:

- Playback: stream-quality preference (SegmentedControl), server-synced.
- Scrobbling: enable + provider (Last.fm/ListenBrainz) + username +
  write-only session key, with a linked/not-linked badge and save states.

Built with modern-sk (Window/SegmentedControl/TextField/Button/Callout/
Badge) + the shared Loading/Error states; en + ru strings added. Server
state flows through RTK Query hooks only (no fetch in components).

Also drops a pre-existing unused TextField import in LibraryPage that was
failing `tsc --noEmit`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-28 15:16:19 +03:00
Senko-san 205b51ec73 stuff
Docker Build & Publish / build (push) Successful in 35s
Docker Build & Publish / push (push) Failing after 2s
Docker Build & Publish / Prune old image versions (push) Has been skipped
2026-07-23 12:02:13 +03:00
Senko-san 608b85a630 chore: bump modern-sk ver.
Docker Build & Publish / build (push) Successful in 35s
Docker Build & Publish / push (push) Failing after 2s
Docker Build & Publish / Prune old image versions (push) Has been skipped
2026-07-11 16:29:40 +03:00
Senko-san 28920d08bd chore: graphify!
Docker Build & Publish / build (push) Successful in 39s
Docker Build & Publish / push (push) Failing after 5s
Docker Build & Publish / Prune old image versions (push) Has been skipped
2026-07-11 16:21:07 +03:00
Senko-san 89cf66f28a fix(api): refetch from server when online (stale-while-revalidate)
Docker Build & Publish / build (push) Successful in 35s
Docker Build & Publish / push (push) Failing after 2s
Docker Build & Publish / Prune old image versions (push) Has been skipped
The Tier-2 rehydrated cache seeded fulfilled entries at startup, so RTKQ served stale data and never hit the network (manual metadata edits, etc. only appeared after clearing the cache). Enable refetchOnMountOrArgChange + refetchOnReconnect + refetchOnFocus and wire setupListeners, so the cached snapshot still shows instantly but the server silently revalidates it whenever reachable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 14:13:59 +03:00
Senko-san f5a6b919aa fix(library): poll track list while enrichment is pending
The library tracks query wasn't refetching, so a track stayed on "Identifying metadata…" until an unrelated Track-tag invalidation. Poll every 4s while any listed track is metadata_status=pending, then stop (and never while offline).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 14:09:47 +03:00
Senko-san 231887c3b7 feat(discover): wire A4 search + A5 downloads to backend
Adds DownloadJob/ExternalSearchResult/SourceInfo contract types + mappers, the downloads + search RTKQ endpoints, and the SearchDownloadPage (search external sources, per-result download states) and DownloadsManagerPage (active/history, progress, retry/cancel, poll-while-active). en/ru i18n. Snapshot also bundles in-progress queue/metadata-editor/storage UI work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 14:04:43 +03:00
Senko-san cdcacc56d1 fix(queue): marquee long track names + dedupe now-playing bars
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Queue sidebar no longer scrolls horizontally on long titles/artists:
text now ping-pong scrolls (news-ticker style) only when it overflows,
via a new Marquee component; .qd-scroll also clips overflow-x.

The current track previously showed the playing-bars indicator both in
place of the drag grip and over the cover. Keep only the cover overlay
and restore the drag grip on the current row.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 02:28:27 +03:00
Senko-san b966ad8be5 fix(library): show album cover art in the Albums grid
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
The album cards always fell back to the 💿 placeholder: the mapper dropped
the backend's `has_cover` and no album cover URL was ever built. Carry
`hasCover` through `RawAlbum`/`Album` and add `getAlbumCoverUrl` (GET
/albums/{id}/cover, token in the query like the track/stream URLs). The
Library Albums grid and the artist-detail discography now render real
covers, same source the album-detail page already used.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 02:15:50 +03:00
Senko-san 6595417246 feat(storage): show device-local storage alongside the server
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
The Storage dashboard only showed the remote server library. Split it into
two sections so both storages live there:

- "On this device": the Tier-3 service-worker audio cache (downloaded
  audio — usage gauge vs max, cached-track count) plus the offline library
  metadata (tracks/albums/artists browsable without the server, from the
  selectLocal* selectors). Always rendered, even with no backend.
- "On the server": the existing remote dashboard, now offline-aware — a
  quiet "server unreachable" notice instead of a blocking error when off.

- hook: useAudioCacheStats (reads getAudioCacheStats from the SW)
- i18n: storage.{device,server,audioCache,...} (en + ru)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 02:05:22 +03:00
Senko-san 94361899a8 feat(library): offline fallback for album & artist detail pages
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Extend the offline-library behaviour to the detail screens: with the
backend unreachable, both pages resolve their entity + tracks/albums from
the locally-cached library (reusing the `selectLocal*` selectors, filtered
by id) instead of showing a retry-only error.

- album detail: album + tracks from cache; offline banner; "not available
  offline" state when the album isn't cached; inner track states no longer
  error over locally-available tracks
- artist detail: artist + discography + tracks from cache; same treatment
- i18n: `common.offlineBanner`, `album.offline.*`, `artist.offline.*`
  (en + ru)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 01:49:39 +03:00
Senko-san 8a0e6782ad feat(library): render from locally-cached data when offline
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
The Library showed a blocking error with the backend unreachable. Now it
composes a read-only library from everything already in the RTK Query
cache (Tier-2 rehydrated last-seen data + anything fetched this session),
so it keeps rendering offline instead of erroring.

- selectors: `selectLocalTracks/Albums/Artists` — memoized, union + dedupe
  across getTracks/getAlbums/getArtists, the per-album/artist list
  endpoints, and single-entity fetches; skips pending/rejected entries
- LibraryPage: when offline, fall back to the composed lists (live data
  still wins online), filter client-side for search, show an offline
  banner, and never show the retry-only ErrorState
- i18n: `library.offline.*` (en + ru)
- test: selector composition / dedup / status filtering (3 cases)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 01:44:45 +03:00
Senko-san 4aa071eeeb feat(upload): persistent "Recently uploaded" list (§A8)
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
The transient client-side upload queue vanished on refresh, so a just-
uploaded track seemed to disappear. Add a server-backed "Recently
uploaded" section (source=upload, newest first) that survives refresh and
auto-refreshes after each upload (the upload mutation already invalidates
the `Track` tag this query provides).

- api: `source` filter on `LibraryFilters` → `GET /tracks?source=`
- i18n: `upload.recent.*` (en + ru); loading/error/empty states

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 01:36:07 +03:00
Senko-san 45a624b642 feat(artist): functional Artist detail screen (§A3)
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Replace the scaffold Placeholder with a real artist page wired to the
existing `/artists/{id}` (+ `/albums`, `/tracks`) endpoints: header with
procedural avatar / counts / "Play all" (queues with source=artist),
discography grid (cards → album detail), and the full track list. All
three list states per async section.

Also make the Library artists-tab rows clickable → `/artists/:id`,
closing the previous navigation dead-end.

i18n: new `artist.*` block (en + ru).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 01:30:06 +03:00
Senko-san 808c52484c feat(storage): functional Storage dashboard (§A6)
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Replace the "coming soon" stub with a real dashboard wired to
`GET /storage`. modern-sk visuals: a layered disk-capacity gauge (library
share vs other-used vs free), stat tiles (tracks/artists/albums/playtime/
footprint/avg size), per-format size bars, metadata-health badges, source
breakdown, a popularity-weighted top-genres cloud, and playful fun facts.

- types: full `StorageStats` shape + `toStorageStats` snake→camel mapper
- endpoint: re-point `getStorageStats` to `GET /storage` with transform
- lib: `formatLongDuration` for big playtime spans
- i18n: `storage.*` keys (en + ru)
- three list states (loading / error / empty) per the UI invariant

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 01:20:01 +03:00
Senko-san 44c8d1870f feat(queue): move shuffle/loop controls into queue drawer, scoped to queue
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
2026-06-13 18:17:21 +03:00
Senko-san a8e060d1a8 fix(player): show actual track format instead of hardcoded FLAC/320kbps
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
2026-06-13 18:06:35 +03:00
Senko-san 8ae447e08d feat(track): icon-based status badges, detect locally-cached tracks
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Replace the labelled availability/metadata badges in track rows with
small icon+tooltip indicators (cloud/hard-drives/warning/etc, derived
from TrackAvailability and MetadataStatus).

Add a `connection` slice fed by a single status poller (Sidebar) so
other components can cheaply check backend reachability. TrackRow uses
this plus the offline audio cache to show "Local" instead of a stale
"On server" when the backend is down but the track is already cached.
2026-06-13 18:00:48 +03:00
Senko-san df8c67b368 feat(album): single cover on album detail, track-number rows
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Album detail header falls back to a track's cover when the album
record itself has none, and each track row hides its per-track art in
favour of a large album-position number, since the header already
shows the album's cover once.
2026-06-13 17:51:55 +03:00
Senko-san f5767ff55e feat(track): show now-playing bars overlay on cover art
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Overlay the accent-coloured "hopping bars" PlayingIndicator on a
track's cover art wherever TrackRow appears when it's the active
player track, and reuse the same component/overlay for the current
entry's cover in the queue panel.
2026-06-13 17:49:06 +03:00
Senko-san 3984c7a499 feat(track): play-on-hover cover art, replacing double-click
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Add a play overlay button shown on cover art hover that inserts the
track into the queue right after the current track and jumps to it,
so it takes priority over what's already queued. Replaces the
double-click-to-play interaction with a new playNow queue action.
2026-06-13 17:44:35 +03:00
Senko-san b37fabd936 feat(queue): make queue tracks draggable via dnd-kit
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Wire up @dnd-kit sortable context in QueuePanel so tracks can be
reordered by dragging the grip handle, dispatching moveInQueue on drop.
2026-06-13 17:40:58 +03:00
Senko-san 9c70b8a11f feat(queue): add per-track overflow menu in queue panel
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Replace the bare "remove" cross on each queue row with a ghost
three-dot menu offering Play now, Move next (reposition right after
the current track), Track info, and Remove — consolidating the
previously separate info button into the same menu.
2026-06-13 17:37:17 +03:00
Senko-san 5c8f89675d feat(queue): unified persistent queue list with playing indicator
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Show all queue entries (played and upcoming) in one list instead of
splitting into a "Now playing" card + "Next up" tail, so previously
played tracks don't disappear and reappear when navigating back/forward.
The current track is outlined and shows a reusable "hopping bars"
PlayingIndicator (modern-sk style equalizer animation) for future reuse
across track lists.
2026-06-13 17:18:38 +03:00
Senko-san df2531171e fix(queue): resolve real track covers in queue panel
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Queue rows passed albumArtUrl straight to ArtTile, but for tracks that
field is usually empty — the real cover is served per-track from
/tracks/{id}/cover. Apply the same resolution PersistentPlayer uses
(getCoverUrl ?? getTrackCoverUrl) for both the now-playing tile and the
up-next rows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 17:06:21 +03:00
Senko-san d1b2b40ffd feat(metadata): implement single-track metadata editor page (§A7)
Docker Build & Publish / Prune old image versions (push) Has been cancelled
Docker Build & Publish / build (push) Has been cancelled
Docker Build & Publish / push (push) Has been cancelled
Replace the placeholder with a controlled form for title/artist/album/
year/genre/track number, an AcoustID "find matches" action showing
ranked candidates with confidence, a diff/apply picker, a re-enrich
button, and save via PUT /metadata. Adds matches/apply API endpoints,
mappers, types, and en/ru i18n strings. Batch editor remains a
placeholder (deferred).
2026-06-13 14:36:17 +03:00
Senko-san 8a70f478c3 feat: track info drawer (Get Info-style)
Add a right-side track info drawer that sits to the right of the queue
panel when both are open. Shows a large cover, title/artist/album links,
a Play/Queue/Edit actions row, and Status/General/File/Identifiers
sections (empty rows omitted). Opens from the track context menu, the
player now-playing tile, and the queue now-playing card.

- ui slice: trackInfoId + open/closeTrackInfo
- TrackInfoDrawer rendered after QueuePanel in AppShell; overlays content
  on narrow viewports
- map source/createdAt/enrichedAt from the wire (were unmapped)
- formatDateTime helper, info icon, i18n (en/ru)
- drop orphaned toggleNowPlaying/isNowPlayingOpen from player slice

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 14:02:38 +03:00
166 changed files with 32353 additions and 456 deletions
+24
View File
@@ -0,0 +1,24 @@
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/Users/senko/.local/bin/graphify hook-guard search"
}
]
},
{
"matcher": "Read|Glob",
"hooks": [
{
"type": "command",
"command": "/Users/senko/.local/bin/graphify hook-guard read"
}
]
}
]
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ on:
env: env:
# Number of tagged (non-latest) versions to keep per image name. # Number of tagged (non-latest) versions to keep per image name.
KEEP_VERSIONS: "5" KEEP_VERSIONS: '5'
jobs: jobs:
build: build:
+10
View File
@@ -64,3 +64,13 @@ Screens follow a spec (`music-selfhost-screens.md`, parts A1–A11). Implemented
## Gotcha ## Gotcha
`tests/index.test.tsx` is the stale rsbuild scaffold test importing a now-deleted `src/App` — it will fail until rewritten. The entry point is `src/index.tsx` (there is no `App.tsx`). `tests/index.test.tsx` is the stale rsbuild scaffold test importing a now-deleted `src/App` — it will fail until rewritten. The entry point is `src/index.tsx` (there is no `App.tsx`).
## graphify
This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.
Rules:
- For codebase questions, first run `graphify query "<question>"` when graphify-out/graph.json exists. Use `graphify path "<A>" "<B>"` for relationships and `graphify explain "<concept>"` for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output.
- If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.
- Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.
- After modifying code, run `graphify update .` to keep the graph current (AST-only, no API cost).
+1
View File
@@ -0,0 +1 @@
{"0": "Track/Player UI Components", "1": "Store Persistence & Local Library", "2": "App Routes & Feature Pages", "3": "Runtime Package Dependencies", "4": "Package Dev Dependencies", "5": "Downloads & Storage Stats", "6": "Instance Connection & Config", "7": "Layout Nav & Permissions", "8": "Library/Playlist API & Mappers", "9": "Project Docs & CI", "10": "React Best Practices Skill Docs", "11": "TypeScript Config", "12": "App Entry & Misc APIs", "13": "Service Worker Cache Core", "14": "Auth & Admin API Types", "15": "External Search API", "16": "Upload Page", "17": "Metadata Editor Page", "18": "Downloads API & Types", "19": "React Compiler & Memoization Rules", "20": "Effects & Derived State Rules", "21": "Test TypeScript Config", "22": "Auth Store Slice", "23": "JS Caching Performance Rules", "24": "Server Caching Rules", "25": "Track Types & Context Menu", "26": "Loop Optimization Rules", "27": "Env Type Declarations", "28": "Lazy Loading Rules", "29": "Event Listener Rules", "30": "SVG Optimization Rules", "31": "Script Loading Rules", "32": "Iteration Optimization Rules", "33": "Lookup Optimization Rules", "34": "Hydration Rules", "35": "Resource Preloading Rules", "36": "RSC Serialization Rules", "37": "Parallel Data Fetching Rules", "38": "Docker Runtime Config Script", "39": "Rsbuild Config", "40": "Conditional Rendering Rule", "41": "Defer Reads Rule", "42": "Non-blocking Server Work Rule", "43": "PostCSS Config", "44": "Public Static Config", "45": "Lint Config", "46": "Test Runner Config", "47": "Admin RTKQ Hooks", "48": "Auth RTKQ Hooks", "49": "Downloads RTKQ Hooks", "50": "Library RTKQ Hooks", "51": "Playlists RTKQ Hooks", "52": "Search RTKQ Hooks", "53": "Storage RTKQ Hooks", "54": "Stale Scaffold Test", "55": "Test Setup"}
+1
View File
@@ -0,0 +1 @@
/Users/senko/.local/share/uv/tools/graphifyy/bin/python
+1
View File
@@ -0,0 +1 @@
/Users/senko/Work/mcma-compose/mcma-webui
+258
View File
@@ -0,0 +1,258 @@
# Graph Report - . (2026-07-11)
## Corpus Check
- 182 files · ~63,741 words
- Verdict: corpus is large enough that graph structure adds value.
## Summary
- 671 nodes · 1391 edges · 56 communities (39 shown, 17 thin omitted)
- Extraction: 97% EXTRACTED · 3% INFERRED · 0% AMBIGUOUS · INFERRED: 44 edges (avg confidence: 0.74)
- Token cost: 240,902 input · 0 output
## Community Hubs (Navigation)
- Track/Player UI Components
- Store Persistence & Local Library
- App Routes & Feature Pages
- Runtime Package Dependencies
- Package Dev Dependencies
- Downloads & Storage Stats
- Instance Connection & Config
- Layout Nav & Permissions
- Library/Playlist API & Mappers
- Project Docs & CI
- React Best Practices Skill Docs
- TypeScript Config
- App Entry & Misc APIs
- Service Worker Cache Core
- Auth & Admin API Types
- External Search API
- Upload Page
- Metadata Editor Page
- Downloads API & Types
- React Compiler & Memoization Rules
- Effects & Derived State Rules
- Test TypeScript Config
- Auth Store Slice
- JS Caching Performance Rules
- Server Caching Rules
- Track Types & Context Menu
- Loop Optimization Rules
- Env Type Declarations
- Lazy Loading Rules
- Event Listener Rules
- SVG Optimization Rules
- Script Loading Rules
- Iteration Optimization Rules
- Lookup Optimization Rules
- Hydration Rules
- Resource Preloading Rules
- RSC Serialization Rules
- Parallel Data Fetching Rules
- Docker Runtime Config Script
- Conditional Rendering Rule
- Defer Reads Rule
- Non-blocking Server Work Rule
- Admin RTKQ Hooks
- Auth RTKQ Hooks
- Downloads RTKQ Hooks
- Library RTKQ Hooks
- Playlists RTKQ Hooks
- Search RTKQ Hooks
- Storage RTKQ Hooks
## God Nodes (most connected - your core abstractions)
1. `useAppSelector()` - 31 edges
2. `useAppDispatch()` - 28 edges
3. `formatDuration()` - 17 edges
4. `compilerOptions` - 17 edges
5. `getCoverUrl()` - 16 edges
6. `Vercel React Best Practices Skill` - 15 edges
7. `TrackRow()` - 13 edges
8. `upsertInstance()` - 13 edges
9. `getApiBaseUrl()` - 13 edges
10. `Vercel React Best Practices - AGENTS.md (Compiled Document)` - 13 edges
## Surprising Connections (you probably didn't know these)
- `favicon.png (cartoon mascot icon)` --conceptually_related_to--> `MCMA Web UI (control center role)` [AMBIGUOUS]
public/favicon.png → CLAUDE.md
- `CLAUDE.md (MCMA webui project guidance)` --conceptually_related_to--> `README.md (rsbuild scaffold readme)` [INFERRED]
CLAUDE.md → README.md
- `Rsbuild Best Practices Skill` --semantically_similar_to--> `Avoid Barrel File Imports` [INFERRED] [semantically similar]
.agents/skills/rsbuild-best-practices/SKILL.md → .agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md
- `Calculate Derived State During Rendering` --semantically_similar_to--> `Subscribe to Derived State` [INFERRED] [semantically similar]
.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md → .agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md
- `Calculate Derived State During Rendering` --semantically_similar_to--> `Put Interaction Logic in Event Handlers` [INFERRED] [semantically similar]
.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md → .agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md
## Import Cycles
- 3-file cycle: `src/api/baseQuery.ts -> src/store/index.ts -> src/api/index.ts -> src/api/baseQuery.ts`
## Hyperedges (group relationships)
- **Eliminating Waterfalls Rule Group (Section 1, CRITICAL impact)** — agents_skills_vercel_react_best_practices_rules_async_cheap_condition_before_await_rule, agents_skills_vercel_react_best_practices_rules_async_defer_await_rule, agents_skills_vercel_react_best_practices_rules_async_dependencies_rule, agents_skills_vercel_react_best_practices_rules_async_parallel_rule, agents_skills_vercel_react_best_practices_rules_async_api_routes_rule, agents_skills_vercel_react_best_practices_rules_async_suspense_boundaries_rule [EXTRACTED 1.00]
- **Bundle Size Optimization Rule Group (Section 2, CRITICAL impact)** — agents_skills_vercel_react_best_practices_rules_bundle_analyzable_paths_rule, agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_rule, agents_skills_vercel_react_best_practices_rules_bundle_conditional_rule, agents_skills_vercel_react_best_practices_rules_bundle_defer_third_party_rule [EXTRACTED 1.00]
- **useEffectEvent Stable-Callback Pattern Group** — agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_rule, agents_skills_vercel_react_best_practices_rules_advanced_event_handler_refs_rule, agents_skills_vercel_react_best_practices_rules_advanced_use_latest_rule, agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_useeffectevent [INFERRED 0.80]
- **In-memory caching of expensive computations/IO** — agents_skills_vercel_react_best_practices_rules_js_cache_function_results, agents_skills_vercel_react_best_practices_rules_js_cache_property_access, agents_skills_vercel_react_best_practices_rules_js_cache_storage [INFERRED 0.85]
- **Single-pass array iteration optimizations** — agents_skills_vercel_react_best_practices_rules_js_flatmap_filter, agents_skills_vercel_react_best_practices_rules_js_combine_iterations, agents_skills_vercel_react_best_practices_rules_js_index_maps, agents_skills_vercel_react_best_practices_rules_js_set_map_lookups [INFERRED 0.75]
- **Event listener management and dedup patterns** — agents_skills_vercel_react_best_practices_rules_client_event_listeners, agents_skills_vercel_react_best_practices_rules_client_passive_event_listeners, agents_skills_vercel_react_best_practices_rules_client_swr_dedup [INFERRED 0.80]
- **Minimizing useEffect Usage Pattern** — agents_skills_vercel_react_best_practices_rules_rerender_derived_state_no_effect, agents_skills_vercel_react_best_practices_rules_rerender_move_effect_to_event, agents_skills_vercel_react_best_practices_rules_rerender_dependencies [INFERRED 0.80]
- **React Compiler Reduces Need for Manual Memoization** — react_compiler, agents_skills_vercel_react_best_practices_rules_rendering_hoist_jsx, agents_skills_vercel_react_best_practices_rules_rerender_memo, agents_skills_vercel_react_best_practices_rules_rerender_functional_setstate [INFERRED 0.85]
- **RSC data-fetching and serialization patterns** — agents_skills_vercel_react_best_practices_rules_server_dedup_props, agents_skills_vercel_react_best_practices_rules_server_serialization, agents_skills_vercel_react_best_practices_rules_server_parallel_fetching, agents_skills_vercel_react_best_practices_rules_server_parallel_nested_fetching [INFERRED 0.80]
- **Server-side caching and request-state-safety patterns** — agents_skills_vercel_react_best_practices_rules_server_cache_react, agents_skills_vercel_react_best_practices_rules_server_cache_lru, agents_skills_vercel_react_best_practices_rules_server_hoist_static_io, agents_skills_vercel_react_best_practices_rules_server_no_shared_module_state [INFERRED 0.80]
- **React re-render optimization patterns** — agents_skills_vercel_react_best_practices_rules_rerender_no_inline_components, agents_skills_vercel_react_best_practices_rules_rerender_simple_expression_in_memo, agents_skills_vercel_react_best_practices_rules_rerender_split_combined_hooks, agents_skills_vercel_react_best_practices_rules_rerender_use_ref_transient_values [INFERRED 0.75]
## Communities (56 total, 17 thin omitted)
### Community 0 - "Track/Player UI Components"
Cohesion: 0.08
Nodes (57): getAlbumCoverUrl(), getCoverUrl(), getStreamUrl(), getTrackCoverUrl(), ArtTile(), hashHue(), Props, TILE_PALETTE (+49 more)
### Community 1 - "Store Persistence & Local Library"
Cohesion: 0.07
Nodes (36): baseQueryWithReauth(), rawBaseQuery(), rehydrateApi, RehydrateApiPayload, instanceStorage, AppDispatch, RootState, loadPlayerState() (+28 more)
### Community 2 - "App Routes & Feature Pages"
Cohesion: 0.06
Nodes (32): Placeholder(), Props, Props, SubNav(), SubNavItem, AppShell(), AdminPage(), AdminInstance() (+24 more)
### Community 3 - "Runtime Package Dependencies"
Cohesion: 0.05
Nodes (39): @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities, i18next, @olly/modern-sk, dependencies, @dnd-kit/core, @dnd-kit/sortable (+31 more)
### Community 4 - "Package Dev Dependencies"
Cohesion: 0.06
Nodes (35): babel-plugin-react-compiler, happy-dom, devDependencies, babel-plugin-react-compiler, happy-dom, prettier, @rsbuild/core, @rsbuild/plugin-babel (+27 more)
### Community 5 - "Downloads & Storage Stats"
Cohesion: 0.11
Nodes (25): DownloadStatus, TrackInfoBody(), ACTIVE, DownloadsManagerPage(), isActive(), JobRow(), STATUS_BADGE, DiskGauge() (+17 more)
### Community 6 - "Instance Connection & Config"
Cohesion: 0.13
Nodes (28): ConnectionStatus(), STATUS_KEY, STATUS_VARIANTS, clearInstanceAuth(), clearScope(), defaultName(), getActiveInstance(), getActiveInstanceId() (+20 more)
### Community 7 - "Layout Nav & Permissions"
Cohesion: 0.10
Nodes (25): MetadataStatus, TrackAvailability, Icon(), IconName, Props, TODO: remove this component, use phosphor's icons project-wide, CONN_KEY, MAIN_NAV (+17 more)
### Community 8 - "Library/Playlist API & Mappers"
Cohesion: 0.14
Nodes (24): libraryApi, paging(), SORT_BY, trackParams(), playlistsApi, DOWNLOAD_STATUSES, METADATA_STATUSES, RawAlbum (+16 more)
### Community 9 - "Project Docs & CI"
Cohesion: 0.11
Nodes (26): AGENTS.md (agent instructions for rsbuild JS project), Don't Define Components Inside Components, Avoid useMemo for Simple Primitive Expressions, Split Combined Hook Computations, Use Transitions for Non-Urgent Updates, Use useDeferredValue for Expensive Derived Renders, Use useRef for Transient Values, CLAUDE.md (MCMA webui project guidance) (+18 more)
### Community 10 - "React Best Practices Skill Docs"
Cohesion: 0.16
Nodes (23): Rsbuild Best Practices Skill, Vercel React Best Practices - AGENTS.md (Compiled Document), Vercel React Best Practices README, Rule Sections Metadata, Rule File Template, Do Not Put Effect Events in Dependency Arrays, useEffectEvent (React Hook), Store Event Handlers in Refs (+15 more)
### Community 11 - "TypeScript Config"
Cohesion: 0.09
Nodes (21): DOM, ES2020, src, compilerOptions, allowImportingTsExtensions, jsx, lib, moduleDetection (+13 more)
### Community 12 - "App Entry & Misc APIs"
Cohesion: 0.10
Nodes (15): likesApi, LikeState, LikeValue, RawLikeState, storageApi, uploadApi, api, RawStorageStats (+7 more)
### Community 13 - "Service Worker Cache Core"
Cohesion: 0.23
Nodes (16): buildRangeResponse(), cacheKeyFor(), parseRangeHeader(), selectEvictions(), trackIdFromUrl(), handleAudio(), handleImage(), indexChain (+8 more)
### Community 14 - "Auth & Admin API Types"
Cohesion: 0.14
Nodes (15): adminApi, authApi, RawTokenResponse, RawUser, toUser(), ApiError, AuthTokens, LibraryFilters (+7 more)
### Community 15 - "External Search API"
Cohesion: 0.24
Nodes (10): mapSearch(), RawSearchResponse, searchApi, SearchResponse, RawSearchResult, RawSourceInfo, toSearchResult(), toSourceInfo() (+2 more)
### Community 16 - "Upload Page"
Cohesion: 0.22
Nodes (7): buildUploadFormData(), { useUploadTrackMutation }, extractError(), ItemStatus, QueueItem, RECENT_UPLOADS, UploadPage()
### Community 17 - "Metadata Editor Page"
Cohesion: 0.20
Nodes (7): DiffRowDef, EMPTY_FORM, fieldStyle(), FormState, labelStyle, Props, SingleTrackEditor()
### Community 18 - "Downloads API & Types"
Cohesion: 0.24
Nodes (9): downloadsApi, ListParams, RawCreateResponse, RawDownloadJob, toDownloadJob(), toDownloadStatus(), DownloadJob, DownloadRequestResult (+1 more)
### Community 19 - "React Compiler & Memoization Rules"
Cohesion: 0.25
Nodes (9): Use Activity Component for Show/Hide, CSS content-visibility for Long Lists, Hoist Static JSX Elements, Use Functional setState Updates, Use Lazy State Initialization, Extract to Memoized Components, Extract Default Non-primitive Parameter Value from Memoized Component to Constant, React Activity Component API (+1 more)
### Community 20 - "Effects & Derived State Rules"
Cohesion: 0.22
Nodes (9): Use useTransition Over Manual Loading States, Narrow Effect Dependencies, Subscribe to Derived State, Calculate Derived State During Rendering, Put Interaction Logic in Event Handlers, Should this code move to an event handler? (React docs), React useTransition API, useTransition Reference (React docs) (+1 more)
### Community 21 - "Test TypeScript Config"
Cohesion: 0.25
Nodes (7): ./, @testing-library/jest-dom, ../tsconfig.json, compilerOptions, types, extends, include
### Community 22 - "Auth Store Slice"
Cohesion: 0.29
Nodes (5): User, authSlice, AuthState, initialState, persisted
### Community 23 - "JS Caching Performance Rules"
Cohesion: 0.33
Nodes (6): Version and Minimize localStorage Data, Avoid Layout Thrashing, Cache Repeated Function Calls, Cache Property Access in Loops, Cache Storage API Calls, Hoist RegExp Creation
### Community 24 - "Server Caching Rules"
Cohesion: 0.40
Nodes (4): Authenticate Server Actions Like API Routes, Cross-Request LRU Caching, Hoist Static I/O to Module Level, Avoid Shared Module State for Request Data
### Community 25 - "Track Types & Context Menu"
Cohesion: 0.50
Nodes (4): PlaylistTrack, Track, Props, Props
### Community 26 - "Loop Optimization Rules"
Cohesion: 0.50
Nodes (4): Early Return from Functions, Early Length Check for Array Comparisons, Use Loop for Min/Max Instead of Sort, Use toSorted() Instead of sort() for Immutability
### Community 27 - "Env Type Declarations"
Cohesion: 0.50
Nodes (3): ImportMeta, ImportMetaEnv, Window
### Community 28 - "Lazy Loading Rules"
Cohesion: 0.67
Nodes (3): Dynamic Imports for Heavy Components, Preload Based on User Intent, Defer Non-Critical Work with requestIdleCallback
### Community 29 - "Event Listener Rules"
Cohesion: 0.67
Nodes (3): Deduplicate Global Event Listeners, Use Passive Event Listeners for Scrolling Performance, Use SWR for Automatic Deduplication
### Community 30 - "SVG Optimization Rules"
Cohesion: 0.67
Nodes (3): Animate SVG Wrapper Instead of SVG Element, Optimize SVG Precision, SVGO (SVG Optimizer)
### Community 31 - "Script Loading Rules"
Cohesion: 0.67
Nodes (3): Use defer or async on Script Tags, MDN Script element defer/async reference, next/script Component
## Ambiguous Edges - Review These
- `MCMA Web UI (control center role)` → `favicon.png (cartoon mascot icon)` [AMBIGUOUS]
public/favicon.png · relation: conceptually_related_to
## Knowledge Gaps
- **194 isolated node(s):** `30-runtime-config.sh script`, `name`, `version`, `private`, `type` (+189 more)
These have ≤1 connection - possible missing edges or undocumented components.
- **17 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
## Suggested Questions
_Questions this graph is uniquely positioned to answer:_
- **What is the exact relationship between `MCMA Web UI (control center role)` and `favicon.png (cartoon mascot icon)`?**
_Edge tagged AMBIGUOUS (relation: conceptually_related_to) - confidence is low._
- **Why does `useAppDispatch()` connect `Track/Player UI Components` to `Track Types & Context Menu`, `Instance Connection & Config`, `Layout Nav & Permissions`?**
_High betweenness centrality (0.010) - this node is a cross-community bridge._
- **Why does `useAppSelector()` connect `Track/Player UI Components` to `Downloads & Storage Stats`, `Layout Nav & Permissions`?**
_High betweenness centrality (0.010) - this node is a cross-community bridge._
- **Why does `devDependencies` connect `Package Dev Dependencies` to `Runtime Package Dependencies`?**
_High betweenness centrality (0.008) - this node is a cross-community bridge._
- **What connects `30-runtime-config.sh script`, `name`, `version` to the rest of the system?**
_209 weakly-connected nodes found - possible documentation gaps or missing edges._
- **Should `Track/Player UI Components` be split into smaller, more focused modules?**
_Cohesion score 0.08095238095238096 - nodes in this community are weakly interconnected._
- **Should `Store Persistence & Local Library` be split into smaller, more focused modules?**
_Cohesion score 0.07127882599580712 - nodes in this community are weakly interconnected._
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "users_senko_work_mcma_compose_mcma_webui_dockerfiles_30_runtime_config_sh", "label": "30-runtime-config.sh", "file_type": "code", "source_file": "dockerfiles/30-runtime-config.sh", "source_location": "L1", "metadata": {"language": "bash", "kind": "file"}}, {"id": "users_senko_work_mcma_compose_mcma_webui_dockerfiles_30_runtime_config_sh__entry", "label": "30-runtime-config.sh script", "file_type": "code", "source_file": "dockerfiles/30-runtime-config.sh", "source_location": "L1", "metadata": {"language": "bash", "kind": "bash_entrypoint"}}], "edges": [{"source": "users_senko_work_mcma_compose_mcma_webui_dockerfiles_30_runtime_config_sh", "target": "users_senko_work_mcma_compose_mcma_webui_dockerfiles_30_runtime_config_sh__entry", "relation": "contains", "confidence": "EXTRACTED", "source_file": "dockerfiles/30-runtime-config.sh", "source_location": "L1", "weight": 1.0}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_json", "label": "tsconfig.json", "file_type": "code", "source_file": "tests/tsconfig.json", "source_location": "L1"}, {"id": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_extends", "label": "extends", "file_type": "code", "source_file": "tests/tsconfig.json", "source_location": "L2"}, {"id": "ref_tsconfig_json", "label": "../tsconfig.json", "file_type": "concept", "source_file": "tests/tsconfig.json", "source_location": "L2"}, {"id": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_compileroptions", "label": "compilerOptions", "file_type": "code", "source_file": "tests/tsconfig.json", "source_location": "L3"}, {"id": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_compileroptions_types", "label": "types", "file_type": "code", "source_file": "tests/tsconfig.json", "source_location": "L4"}, {"id": "ref_testing_library_jest_dom", "label": "@testing-library/jest-dom", "file_type": "concept", "source_file": "tests/tsconfig.json", "source_location": "L4"}, {"id": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_include", "label": "include", "file_type": "code", "source_file": "tests/tsconfig.json", "source_location": "L6"}, {"id": "ref", "label": "./", "file_type": "concept", "source_file": "tests/tsconfig.json", "source_location": "L6"}], "edges": [{"source": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_json", "target": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_extends", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tests/tsconfig.json", "source_location": "L2", "weight": 1.0}, {"source": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_json", "target": "ref_tsconfig_json", "relation": "extends", "confidence": "EXTRACTED", "source_file": "tests/tsconfig.json", "source_location": "L2", "weight": 1.0, "context": "import"}, {"source": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_json", "target": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_compileroptions", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tests/tsconfig.json", "source_location": "L3", "weight": 1.0}, {"source": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_compileroptions", "target": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_compileroptions_types", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tests/tsconfig.json", "source_location": "L4", "weight": 1.0}, {"source": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_compileroptions_types", "target": "ref_testing_library_jest_dom", "relation": "extends", "confidence": "EXTRACTED", "source_file": "tests/tsconfig.json", "source_location": "L4", "weight": 1.0, "context": "import"}, {"source": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_json", "target": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_include", "relation": "contains", "confidence": "EXTRACTED", "source_file": "tests/tsconfig.json", "source_location": "L6", "weight": 1.0}, {"source": "users_senko_work_mcma_compose_mcma_webui_tests_tsconfig_include", "target": "ref", "relation": "extends", "confidence": "EXTRACTED", "source_file": "tests/tsconfig.json", "source_location": "L6", "weight": 1.0, "context": "import"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_content_visibility", "label": "CSS content-visibility for Long Lists", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rendering_content_visibility", "target": "rendering_activity", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.55, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_cache_storage", "label": "Cache Storage API Calls", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-cache-storage.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_cache_storage", "target": "client_localstorage_schema", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-cache-storage.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_lazy_state_init", "label": "Use Lazy State Initialization", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rerender_lazy_state_init", "target": "rerender_functional_setstate", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.65, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_rsbuild_best_practices_skill", "label": "Rsbuild Best Practices Skill", "file_type": "document", "source_file": ".agents/skills/rsbuild-best-practices/SKILL.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_rsbuild_best_practices_skill", "target": "agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_rule", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.65, "source_file": ".agents/skills/rsbuild-best-practices/SKILL.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_serialization", "label": "Minimize Serialization at RSC Boundaries", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-serialization.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": [{"id": "hyperedge_rsc_data_fetching_serialization", "label": "RSC data-fetching and serialization patterns", "nodes": ["agents_skills_vercel_react_best_practices_rules_server_dedup_props", "agents_skills_vercel_react_best_practices_rules_server_serialization", "agents_skills_vercel_react_best_practices_rules_server_parallel_fetching", "agents_skills_vercel_react_best_practices_rules_server_parallel_nested_fetching"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.8, "source_file": ".agents/skills/vercel-react-best-practices/rules/server-serialization.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "public_favicon_png", "label": "favicon.png (cartoon mascot icon)", "file_type": "image", "source_file": "public/favicon.png", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "public_favicon_png", "target": "claude_md_mcma_control_center", "relation": "conceptually_related_to", "confidence": "AMBIGUOUS", "confidence_score": 0.2, "source_file": "public/favicon.png", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_hoist_jsx", "label": "Hoist Static JSX Elements", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "react_compiler", "label": "React Compiler (babel-plugin-react-compiler)", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rendering_hoist_jsx", "target": "react_compiler", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md", "source_location": null, "weight": 1.0}, {"source": "rendering_hoist_jsx", "target": "rerender_memo", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.65, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "react_compiler_obsoletes_manual_memoization", "label": "React Compiler Reduces Need for Manual Memoization", "nodes": ["react_compiler", "rendering_hoist_jsx", "rerender_memo", "rerender_functional_setstate"], "relation": "form", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_svg_precision", "label": "Optimize SVG Precision", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "svgo_tool", "label": "SVGO (SVG Optimizer)", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rendering_svg_precision", "target": "svgo_tool", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md", "source_location": null, "weight": 1.0}, {"source": "rendering_svg_precision", "target": "rendering_animate_svg_wrapper", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_async_parallel_rule", "label": "Promise.all() for Independent Operations", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/async-parallel.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_async_parallel_rule", "target": "agents_skills_vercel_react_best_practices_rules_async_dependencies_rule", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/async-parallel.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_index_maps", "label": "Build Index Maps for Repeated Lookups", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-index-maps.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_index_maps", "target": "js_set_map_lookups", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.9, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-index-maps.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_dedup_props", "label": "Avoid Duplicate Serialization in RSC Props", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-dedup-props.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_server_dedup_props", "target": "agents_skills_vercel_react_best_practices_rules_server_serialization", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.9, "source_file": ".agents/skills/vercel-react-best-practices/rules/server-dedup-props.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_cache_lru", "label": "Cross-Request LRU Caching", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-cache-lru.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_server_cache_lru", "target": "agents_skills_vercel_react_best_practices_rules_server_cache_react", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/server-cache-lru.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_rules_server_cache_lru", "target": "agents_skills_vercel_react_best_practices_rules_server_hoist_static_io", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.7, "source_file": ".agents/skills/vercel-react-best-practices/rules/server-cache-lru.md", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "hyperedge_server_caching_state_safety", "label": "Server-side caching and request-state-safety patterns", "nodes": ["agents_skills_vercel_react_best_practices_rules_server_cache_react", "agents_skills_vercel_react_best_practices_rules_server_cache_lru", "agents_skills_vercel_react_best_practices_rules_server_hoist_static_io", "agents_skills_vercel_react_best_practices_rules_server_no_shared_module_state"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.8, "source_file": ".agents/skills/vercel-react-best-practices/rules/server-cache-lru.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "client_swr_dedup", "label": "Use SWR for Automatic Deduplication", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_activity", "label": "Use Activity Component for Show/Hide", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-activity.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "react_activity_component", "label": "React Activity Component API", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-activity.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rendering_activity", "target": "react_activity_component", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-activity.md", "source_location": null, "weight": 1.0}, {"source": "rendering_activity", "target": "rerender_memo", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.65, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-activity.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_advanced_init_once_rule", "label": "Initialize App Once, Not Per Mount", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-init-once.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_tosorted_immutable", "label": "Use toSorted() Instead of sort() for Immutability", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_tosorted_immutable", "target": "js_min_max_loop", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.65, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_rerender_split_combined_hooks", "label": "Split Combined Hook Computations", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_rerender_split_combined_hooks", "target": "claude_md_react_compiler", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_rerender_use_ref_transient_values", "label": "Use useRef for Transient Values", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_cache_property_access", "label": "Cache Property Access in Loops", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_bundle_analyzable_paths_rule", "label": "Prefer Statically Analyzable Paths", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_bundle_analyzable_paths_rule", "target": "agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_rule", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_rule", "label": "Do Not Put Effect Events in Dependency Arrays", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_useeffectevent", "label": "useEffectEvent (React Hook)", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_rule", "target": "agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_useeffectevent", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "useeffectevent_pattern_group", "label": "useEffectEvent Stable-Callback Pattern Group", "nodes": ["agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_rule", "agents_skills_vercel_react_best_practices_rules_advanced_event_handler_refs_rule", "agents_skills_vercel_react_best_practices_rules_advanced_use_latest_rule", "agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_useeffectevent"], "relation": "implement", "confidence": "INFERRED", "confidence_score": 0.8, "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_memo_with_default_value", "label": "Extract Default Non-primitive Parameter Value from Memoized Component to Constant", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rerender_memo_with_default_value", "target": "rerender_memo", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_async_api_routes_rule", "label": "Prevent Waterfall Chains in API Routes", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/async-api-routes.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_async_api_routes_rule", "target": "agents_skills_vercel_react_best_practices_rules_async_dependencies_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/async-api-routes.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_rules_async_api_routes_rule", "target": "agents_skills_vercel_react_best_practices_rules_async_dependencies_betterall", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/async-api-routes.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_parallel_nested_fetching", "label": "Parallel Nested Data Fetching", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_async_dependencies_rule", "label": "Dependency-Based Parallelization", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/async-dependencies.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_skills_vercel_react_best_practices_rules_async_dependencies_betterall", "label": "better-all Library", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/async-dependencies.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_async_dependencies_rule", "target": "agents_skills_vercel_react_best_practices_rules_async_dependencies_betterall", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/async-dependencies.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_combine_iterations", "label": "Combine Multiple Array Iterations", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "gitea_workflows_docker_publish_yml", "label": "Docker Build & Publish Workflow (Gitea CI)", "file_type": "code", "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "gitea_workflows_docker_publish_yml_build_job", "label": "build job (docker image build)", "file_type": "concept", "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "gitea_workflows_docker_publish_yml_push_job", "label": "push job (registry push)", "file_type": "concept", "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "gitea_workflows_docker_publish_yml_cleanup_job", "label": "cleanup job (prune old image versions)", "file_type": "concept", "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "gitea_workflows_docker_publish_yml", "target": "gitea_workflows_docker_publish_yml_build_job", "relation": "conceptually_related_to", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "weight": 1.0}, {"source": "gitea_workflows_docker_publish_yml", "target": "gitea_workflows_docker_publish_yml_push_job", "relation": "conceptually_related_to", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "weight": 1.0}, {"source": "gitea_workflows_docker_publish_yml", "target": "gitea_workflows_docker_publish_yml_cleanup_job", "relation": "conceptually_related_to", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "weight": 1.0}, {"source": "gitea_workflows_docker_publish_yml_build_job", "target": "gitea_workflows_docker_publish_yml_push_job", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "weight": 1.0}, {"source": "gitea_workflows_docker_publish_yml_push_job", "target": "gitea_workflows_docker_publish_yml_cleanup_job", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "weight": 1.0}, {"source": "gitea_workflows_docker_publish_yml_build_job", "target": "claude_md_base_url_resolution", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".gitea/workflows/docker-publish.yml", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_memo", "label": "Extract to Memoized Components", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-memo.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rerender_memo", "target": "react_compiler", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-memo.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_async_defer_await_rule", "label": "Defer Await Until Needed", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/async-defer-await.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_async_defer_await_rule", "target": "agents_skills_vercel_react_best_practices_rules_async_cheap_condition_before_await_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/async-defer-await.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_parallel_fetching", "label": "Parallel Data Fetching with Component Composition", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_server_parallel_fetching", "target": "agents_skills_vercel_react_best_practices_rules_server_parallel_nested_fetching", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules__template", "label": "Rule File Template", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/rules/_template.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "readme_md", "label": "README.md (rsbuild scaffold readme)", "file_type": "document", "source_file": "README.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_readme", "label": "Vercel React Best Practices README", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/README.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_readme", "target": "agents_skills_vercel_react_best_practices_agents", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/README.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_readme", "target": "agents_skills_vercel_react_best_practices_rules__template", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/README.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_readme", "target": "agents_skills_vercel_react_best_practices_rules__sections", "relation": "references", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/README.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_advanced_use_latest_rule", "label": "useEffectEvent for Stable Callback Refs", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_advanced_use_latest_rule", "target": "agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_useeffectevent", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_rerender_simple_expression_in_memo", "label": "Avoid useMemo for Simple Primitive Expressions", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_rerender_simple_expression_in_memo", "target": "agents_skills_vercel_react_best_practices_rules_rerender_split_combined_hooks", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_hydration_no_flicker", "label": "Prevent Hydration Mismatch Without Flickering", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rendering_hydration_no_flicker", "target": "rendering_hydration_suppress_warning", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_flatmap_filter", "label": "Use flatMap to Map and Filter in One Pass", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_flatmap_filter", "target": "js_combine_iterations", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "hyperedge_array_iteration_optimization", "label": "Single-pass array iteration optimizations", "nodes": ["js_flatmap_filter", "js_combine_iterations", "js_index_maps", "js_set_map_lookups"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_usetransition_loading", "label": "Use useTransition Over Manual Loading States", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "react_usetransition_api", "label": "React useTransition API", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "react_usetransition_reference_doc", "label": "useTransition Reference (React docs)", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md", "source_location": null, "source_url": "https://react.dev/reference/react/useTransition", "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rendering_usetransition_loading", "target": "react_usetransition_api", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md", "source_location": null, "weight": 1.0}, {"source": "rendering_usetransition_loading", "target": "react_usetransition_reference_doc", "relation": "cites", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md", "source_location": null, "weight": 1.0}, {"source": "rendering_usetransition_loading", "target": "rerender_derived_state_no_effect", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.55, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_cache_function_results", "label": "Cache Repeated Function Calls", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_cache_function_results", "target": "js_cache_property_access", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md", "source_location": null, "weight": 1.0}, {"source": "js_cache_function_results", "target": "js_cache_storage", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.9, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "hyperedge_caching_patterns", "label": "In-memory caching of expensive computations/IO", "nodes": ["js_cache_function_results", "js_cache_property_access", "js_cache_storage"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_length_check_first", "label": "Early Length Check for Array Comparisons", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-length-check-first.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules__sections", "label": "Rule Sections Metadata", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/rules/_sections.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules__sections", "target": "agents_skills_vercel_react_best_practices_agents", "relation": "references", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/_sections.md", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "waterfall_elimination_rules", "label": "Eliminating Waterfalls Rule Group (Section 1, CRITICAL impact)", "nodes": ["agents_skills_vercel_react_best_practices_rules_async_cheap_condition_before_await_rule", "agents_skills_vercel_react_best_practices_rules_async_defer_await_rule", "agents_skills_vercel_react_best_practices_rules_async_dependencies_rule", "agents_skills_vercel_react_best_practices_rules_async_parallel_rule", "agents_skills_vercel_react_best_practices_rules_async_api_routes_rule", "agents_skills_vercel_react_best_practices_rules_async_suspense_boundaries_rule"], "relation": "participate_in", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/_sections.md"}, {"id": "bundle_size_optimization_rules", "label": "Bundle Size Optimization Rule Group (Section 2, CRITICAL impact)", "nodes": ["agents_skills_vercel_react_best_practices_rules_bundle_analyzable_paths_rule", "agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_rule", "agents_skills_vercel_react_best_practices_rules_bundle_conditional_rule", "agents_skills_vercel_react_best_practices_rules_bundle_defer_third_party_rule"], "relation": "participate_in", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/_sections.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "client_localstorage_schema", "label": "Version and Minimize localStorage Data", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "bundle_preload", "label": "Preload Based on User Intent", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-preload.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "bundle_preload", "target": "bundle_dynamic_imports", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-preload.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_functional_setstate", "label": "Use Functional setState Updates", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rerender_functional_setstate", "target": "react_compiler", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_request_idle_callback", "label": "Defer Non-Critical Work with requestIdleCallback", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-request-idle-callback.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_request_idle_callback", "target": "bundle_preload", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.65, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-request-idle-callback.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_conditional_render", "label": "Use Explicit Conditional Rendering", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_derived_state", "label": "Subscribe to Derived State", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_resource_hints", "label": "Use React DOM Resource Hints", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "react_dom_resource_preloading_apis_doc", "label": "React DOM Resource Preloading APIs (reference)", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md", "source_location": null, "source_url": "https://react.dev/reference/react-dom#resource-preloading-apis", "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rendering_resource_hints", "target": "react_dom_resource_preloading_apis_doc", "relation": "cites", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_rerender_use_deferred_value", "label": "Use useDeferredValue for Expensive Derived Renders", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_rerender_transitions", "target": "agents_skills_vercel_react_best_practices_rules_rerender_use_deferred_value", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.8, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_rules_rerender_use_deferred_value", "target": "agents_skills_vercel_react_best_practices_rules_rerender_simple_expression_in_memo", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.65, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_async_cheap_condition_before_await_rule", "label": "Check Cheap Conditions Before Async Flags", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_async_cheap_condition_before_await_rule", "target": "agents_skills_vercel_react_best_practices_rules_async_defer_await_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_rerender_transitions", "label": "Use Transitions for Non-Urgent Updates", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-transitions.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_rule", "label": "Avoid Barrel File Imports", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_barrelfile", "label": "Barrel File (bundling concept)", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_rule", "target": "agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_barrelfile", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_dependencies", "label": "Narrow Effect Dependencies", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_min_max_loop", "label": "Use Loop for Min/Max Instead of Sort", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_min_max_loop", "target": "js_length_check_first", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.65, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_rerender_no_inline_components", "label": "Don't Define Components Inside Components", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": [{"id": "hyperedge_rerender_optimization_patterns", "label": "React re-render optimization patterns", "nodes": ["agents_skills_vercel_react_best_practices_rules_rerender_no_inline_components", "agents_skills_vercel_react_best_practices_rules_rerender_simple_expression_in_memo", "agents_skills_vercel_react_best_practices_rules_rerender_split_combined_hooks", "agents_skills_vercel_react_best_practices_rules_rerender_use_ref_transient_values"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_agents", "label": "Vercel React Best Practices - AGENTS.md (Compiled Document)", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "source_url": null, "captured_at": null, "author": "Vercel Engineering", "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_async_cheap_condition_before_await_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_async_defer_await_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_async_dependencies_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_async_api_routes_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_async_parallel_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_async_suspense_boundaries_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_bundle_analyzable_paths_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_bundle_barrel_imports_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_bundle_conditional_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}, {"source": "agents_skills_vercel_react_best_practices_agents", "target": "agents_skills_vercel_react_best_practices_rules_bundle_defer_third_party_rule", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/AGENTS.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_defer_reads", "label": "Defer State Reads to Usage Point", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_early_exit", "label": "Early Return from Functions", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-early-exit.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_early_exit", "target": "js_length_check_first", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.8, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-early-exit.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_bundle_defer_third_party_rule", "label": "Defer Non-Critical Third-Party Libraries", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_set_map_lookups", "label": "Use Set/Map for O(1) Lookups", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_auth_actions", "label": "Authenticate Server Actions Like API Routes", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-auth-actions.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_server_auth_actions", "target": "agents_skills_vercel_react_best_practices_rules_server_no_shared_module_state", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.6, "source_file": ".agents/skills/vercel-react-best-practices/rules/server-auth-actions.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_batch_dom_css", "label": "Avoid Layout Thrashing", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_batch_dom_css", "target": "js_cache_property_access", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.55, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "bundle_dynamic_imports", "label": "Dynamic Imports for Heavy Components", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_move_effect_to_event", "label": "Put Interaction Logic in Event Handlers", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "react_removing_effect_dependencies_event_handler", "label": "Should this code move to an event handler? (React docs)", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md", "source_location": null, "source_url": "https://react.dev/learn/removing-effect-dependencies#should-this-code-move-to-an-event-handler", "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rerender_move_effect_to_event", "target": "react_removing_effect_dependencies_event_handler", "relation": "cites", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_no_shared_module_state", "label": "Avoid Shared Module State for Request Data", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-no-shared-module-state.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_server_no_shared_module_state", "target": "agents_skills_vercel_react_best_practices_rules_server_hoist_static_io", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/server-no-shared-module-state.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "js_hoist_regexp", "label": "Hoist RegExp Creation", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "js_hoist_regexp", "target": "js_cache_function_results", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_hoist_static_io", "label": "Hoist Static I/O to Module Level", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_hydration_suppress_warning", "label": "Suppress Expected Hydration Mismatches", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_cache_react", "label": "Per-Request Deduplication with React.cache()", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-cache-react.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "client_event_listeners", "label": "Deduplicate Global Event Listeners", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/client-event-listeners.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "client_event_listeners", "target": "client_swr_dedup", "relation": "shares_data_with", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/client-event-listeners.md", "source_location": null, "weight": 1.0}, {"source": "client_event_listeners", "target": "client_passive_event_listeners", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.85, "source_file": ".agents/skills/vercel-react-best-practices/rules/client-event-listeners.md", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "hyperedge_event_listener_best_practices", "label": "Event listener management and dedup patterns", "nodes": ["client_event_listeners", "client_passive_event_listeners", "client_swr_dedup"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.8, "source_file": ".agents/skills/vercel-react-best-practices/rules/client-event-listeners.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_md", "label": "AGENTS.md (agent instructions for rsbuild JS project)", "file_type": "document", "source_file": "AGENTS.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_md", "target": "readme_md", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": "AGENTS.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_script_defer_async", "label": "Use defer or async on Script Tags", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "mdn_script_element_defer_doc", "label": "MDN Script element defer/async reference", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md", "source_location": null, "source_url": "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#defer", "captured_at": null, "author": null, "contributor": null}, {"id": "nextjs_script_component", "label": "next/script Component", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rendering_script_defer_async", "target": "mdn_script_element_defer_doc", "relation": "cites", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md", "source_location": null, "weight": 1.0}, {"source": "rendering_script_defer_async", "target": "nextjs_script_component", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "client_passive_event_listeners", "label": "Use Passive Event Listeners for Scrolling Performance", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "rerender_derived_state_no_effect", "label": "Calculate Derived State During Rendering", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}, {"id": "react_you_might_not_need_an_effect", "label": "You Might Not Need an Effect (React docs)", "file_type": "document", "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md", "source_location": null, "source_url": "https://react.dev/learn/you-might-not-need-an-effect", "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "rerender_derived_state_no_effect", "target": "react_you_might_not_need_an_effect", "relation": "cites", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md", "source_location": null, "weight": 1.0}, {"source": "rerender_derived_state_no_effect", "target": "rerender_derived_state", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md", "source_location": null, "weight": 1.0}, {"source": "rerender_derived_state_no_effect", "target": "rerender_move_effect_to_event", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.7, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md", "source_location": null, "weight": 1.0}, {"source": "rerender_derived_state_no_effect", "target": "rerender_dependencies", "relation": "conceptually_related_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md", "source_location": null, "weight": 1.0}], "hyperedges": [{"id": "effect_avoidance_pattern", "label": "Minimizing useEffect Usage Pattern", "nodes": ["rerender_derived_state_no_effect", "rerender_move_effect_to_event", "rerender_dependencies"], "relation": "participate_in", "confidence": "INFERRED", "confidence_score": 0.8, "source_file": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md"}]}
@@ -0,0 +1 @@
{"nodes": [{"id": "rendering_animate_svg_wrapper", "label": "Animate SVG Wrapper Instead of SVG Element", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_server_after_nonblocking", "label": "Use after() for Non-Blocking Operations", "file_type": "concept", "source_file": ".agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_advanced_event_handler_refs_rule", "label": "Store Event Handlers in Refs", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_advanced_event_handler_refs_rule", "target": "agents_skills_vercel_react_best_practices_rules_advanced_effect_event_deps_useeffectevent", "relation": "references", "confidence": "EXTRACTED", "confidence_score": 1.0, "source_file": ".agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_bundle_conditional_rule", "label": "Conditional Module Loading", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-conditional.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [{"source": "agents_skills_vercel_react_best_practices_rules_bundle_conditional_rule", "target": "agents_skills_vercel_react_best_practices_rules_bundle_defer_third_party_rule", "relation": "semantically_similar_to", "confidence": "INFERRED", "confidence_score": 0.75, "source_file": ".agents/skills/vercel-react-best-practices/rules/bundle-conditional.md", "source_location": null, "weight": 1.0}], "hyperedges": []}
@@ -0,0 +1 @@
{"nodes": [{"id": "agents_skills_vercel_react_best_practices_rules_async_suspense_boundaries_rule", "label": "Strategic Suspense Boundaries", "file_type": "rationale", "source_file": ".agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md", "source_location": null, "source_url": null, "captured_at": null, "author": null, "contributor": null}], "edges": [], "hyperedges": []}
File diff suppressed because one or more lines are too long
+12
View File
@@ -0,0 +1,12 @@
{
"runs": [
{
"date": "2026-07-11T12:47:26.924630+00:00",
"input_tokens": 240902,
"output_tokens": 0,
"files": 182
}
],
"total_input_tokens": 240902,
"total_output_tokens": 0
}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+912
View File
@@ -0,0 +1,912 @@
{
".agents/skills/vercel-react-best-practices/metadata.json": {
"mtime": 1780740461.5277927,
"ast_hash": "5cd9ae4fc688353236c3b92e8f06dfcc",
"semantic_hash": "5cd9ae4fc688353236c3b92e8f06dfcc"
},
".claude/settings.local.json": {
"mtime": 1781361506.6796608,
"ast_hash": "8e8ce7192621df4ecb46df42b9a3b524",
"semantic_hash": "8e8ce7192621df4ecb46df42b9a3b524"
},
"dockerfiles/30-runtime-config.sh": {
"mtime": 1781089242.206189,
"ast_hash": "9ac88ae492e4feda9b17893765bf24fe",
"semantic_hash": "9ac88ae492e4feda9b17893765bf24fe"
},
"package.json": {
"mtime": 1781361508.5031557,
"ast_hash": "0c69f301bfe4e1d580075694eb844fca",
"semantic_hash": "0c69f301bfe4e1d580075694eb844fca"
},
"postcss.config.mjs": {
"mtime": 1780740461.5328195,
"ast_hash": "9a944fbda06979be39571bd9bd00b0d9",
"semantic_hash": "9a944fbda06979be39571bd9bd00b0d9"
},
"public/config.js": {
"mtime": 1780928353.984508,
"ast_hash": "5c5c2c8cec45f54040f7785f3d4b7d5a",
"semantic_hash": "5c5c2c8cec45f54040f7785f3d4b7d5a"
},
"public/sw-core.js": {
"mtime": 1780928353.9846263,
"ast_hash": "518771d725d68e8bfc4dd2ea9e5aa237",
"semantic_hash": "518771d725d68e8bfc4dd2ea9e5aa237"
},
"public/sw.js": {
"mtime": 1781433550.8761518,
"ast_hash": "560d219c5e6a22d76428e98a5e3c0e36",
"semantic_hash": "560d219c5e6a22d76428e98a5e3c0e36"
},
"rsbuild.config.ts": {
"mtime": 1781000163.845349,
"ast_hash": "46af4ba75b294ff78aa4d0a51d568d45",
"semantic_hash": "46af4ba75b294ff78aa4d0a51d568d45"
},
"rslint.config.ts": {
"mtime": 1780740461.5330274,
"ast_hash": "61ea3ac0d4dafae46af048936e99c890",
"semantic_hash": "61ea3ac0d4dafae46af048936e99c890"
},
"rstest.config.ts": {
"mtime": 1780740461.5330856,
"ast_hash": "bfc0d5a1917eb4d7020b91ef8ccef4fe",
"semantic_hash": "bfc0d5a1917eb4d7020b91ef8ccef4fe"
},
"skills-lock.json": {
"mtime": 1780740461.5331488,
"ast_hash": "ccb22d3970f750ba3cd1b774940ef349",
"semantic_hash": "ccb22d3970f750ba3cd1b774940ef349"
},
"src/api/baseQuery.ts": {
"mtime": 1780928353.9850338,
"ast_hash": "172535aaa1ae4e27c2ad80158aee5ca6",
"semantic_hash": "172535aaa1ae4e27c2ad80158aee5ca6"
},
"src/api/endpoints/admin.ts": {
"mtime": 1780928353.985141,
"ast_hash": "fc0666510d93c5a1c3e3c04fe4db6787",
"semantic_hash": "fc0666510d93c5a1c3e3c04fe4db6787"
},
"src/api/endpoints/auth.ts": {
"mtime": 1781089188.3254483,
"ast_hash": "7c5048f80ba8810f606b350a2e1cf795",
"semantic_hash": "7c5048f80ba8810f606b350a2e1cf795"
},
"src/api/endpoints/downloads.ts": {
"mtime": 1781433262.4855404,
"ast_hash": "fe353113e23f4b7a4f8e62708cfc24a0",
"semantic_hash": "fe353113e23f4b7a4f8e62708cfc24a0"
},
"src/api/endpoints/library.ts": {
"mtime": 1781389998.06688,
"ast_hash": "97c1d035a7c055dbc9aede85b8e8af32",
"semantic_hash": "97c1d035a7c055dbc9aede85b8e8af32"
},
"src/api/endpoints/likes.ts": {
"mtime": 1780928353.9855933,
"ast_hash": "740df79ae13d639a33ea1addf289e91d",
"semantic_hash": "740df79ae13d639a33ea1addf289e91d"
},
"src/api/endpoints/playlists.ts": {
"mtime": 1780928353.9856954,
"ast_hash": "c8bc74e3a786f258ba720feefaf195fd",
"semantic_hash": "c8bc74e3a786f258ba720feefaf195fd"
},
"src/api/endpoints/search.ts": {
"mtime": 1781433270.9613721,
"ast_hash": "9c7ccdaf91060381d8636762cf2872fe",
"semantic_hash": "9c7ccdaf91060381d8636762cf2872fe"
},
"src/api/endpoints/storage.ts": {
"mtime": 1781388542.493346,
"ast_hash": "306e35114360e347827217a7b89e98a9",
"semantic_hash": "306e35114360e347827217a7b89e98a9"
},
"src/api/endpoints/streaming.ts": {
"mtime": 1781392474.3629467,
"ast_hash": "3c9d97f8c567aaa85ca5286d32623780",
"semantic_hash": "3c9d97f8c567aaa85ca5286d32623780"
},
"src/api/endpoints/upload.ts": {
"mtime": 1780846419.4869378,
"ast_hash": "152274e4b12c025dfa705fd701e70ff2",
"semantic_hash": "152274e4b12c025dfa705fd701e70ff2"
},
"src/api/index.ts": {
"mtime": 1781435593.149487,
"ast_hash": "38df04765407b1cf9636a792cc641cb6",
"semantic_hash": "38df04765407b1cf9636a792cc641cb6"
},
"src/api/mappers.ts": {
"mtime": 1781433550.9270675,
"ast_hash": "9130c062413d59fddc22d1a59a1f326d",
"semantic_hash": "9130c062413d59fddc22d1a59a1f326d"
},
"src/api/rehydrate.ts": {
"mtime": 1781090734.1804643,
"ast_hash": "f57b05db15b88e21f4c25918e5075c86",
"semantic_hash": "f57b05db15b88e21f4c25918e5075c86"
},
"src/api/types.ts": {
"mtime": 1781433198.9059656,
"ast_hash": "2c0a12edfb918aefdd24fc47d3d1e807",
"semantic_hash": "2c0a12edfb918aefdd24fc47d3d1e807"
},
"src/components/common/ArtTile.tsx": {
"mtime": 1780742839.7201965,
"ast_hash": "89cd4e42fe9c230940c89bb18f3c2d4c",
"semantic_hash": "89cd4e42fe9c230940c89bb18f3c2d4c"
},
"src/components/common/ConnectionStatus.tsx": {
"mtime": 1780848354.9544237,
"ast_hash": "0807cccdea2c06610e733e41ae7495aa",
"semantic_hash": "0807cccdea2c06610e733e41ae7495aa"
},
"src/components/common/EmptyState.tsx": {
"mtime": 1780742839.7196033,
"ast_hash": "8e993f296e5199005fa33f12813b3939",
"semantic_hash": "8e993f296e5199005fa33f12813b3939"
},
"src/components/common/ErrorState.tsx": {
"mtime": 1780744239.301299,
"ast_hash": "80f9c368a8aa07d6c87cac2b437ca971",
"semantic_hash": "80f9c368a8aa07d6c87cac2b437ca971"
},
"src/components/common/Icon.tsx": {
"mtime": 1781362481.0724576,
"ast_hash": "e947b2aa8ad4fd51d68a17f5216370e1",
"semantic_hash": "e947b2aa8ad4fd51d68a17f5216370e1"
},
"src/components/common/LoadingSkeleton.tsx": {
"mtime": 1780742839.7190557,
"ast_hash": "9c5950c0393dcc18e456bdf17edacb5c",
"semantic_hash": "9c5950c0393dcc18e456bdf17edacb5c"
},
"src/components/common/Marquee.tsx": {
"mtime": 1781433550.9447904,
"ast_hash": "5cb6890513697484ab6323f6256b7a32",
"semantic_hash": "5cb6890513697484ab6323f6256b7a32"
},
"src/components/common/Placeholder.tsx": {
"mtime": 1780840127.8629725,
"ast_hash": "5a3b04d4c60e46f8061c4eaef96163ae",
"semantic_hash": "5a3b04d4c60e46f8061c4eaef96163ae"
},
"src/components/common/PlayingIndicator.tsx": {
"mtime": 1781360030.8541682,
"ast_hash": "4c3faf67a9a2c294dd408ec94ecdc154",
"semantic_hash": "4c3faf67a9a2c294dd408ec94ecdc154"
},
"src/components/common/SubNav.tsx": {
"mtime": 1780840176.6522932,
"ast_hash": "6734f934d591361aa9811d77f800b827",
"semantic_hash": "6734f934d591361aa9811d77f800b827"
},
"src/components/layout/AppShell.tsx": {
"mtime": 1781350701.573457,
"ast_hash": "c0eaa7ac149c999a21eee3a3ee191206",
"semantic_hash": "c0eaa7ac149c999a21eee3a3ee191206"
},
"src/components/layout/Sidebar.tsx": {
"mtime": 1781433550.9543304,
"ast_hash": "c42e427d9d847aa02bed7e9404619a2a",
"semantic_hash": "c42e427d9d847aa02bed7e9404619a2a"
},
"src/components/player/PersistentPlayer.tsx": {
"mtime": 1781363531.3984172,
"ast_hash": "3515a6388bc2d947a5fccd9b185e9214",
"semantic_hash": "3515a6388bc2d947a5fccd9b185e9214"
},
"src/components/player/QueuePanel.tsx": {
"mtime": 1781433550.9680245,
"ast_hash": "1395942b4bcfb3fb1ddf308502d7a8f6",
"semantic_hash": "1395942b4bcfb3fb1ddf308502d7a8f6"
},
"src/components/track/AvailabilityBadge.tsx": {
"mtime": 1781362698.541016,
"ast_hash": "9ddbe593f69fab7655f24ecce3a5785d",
"semantic_hash": "9ddbe593f69fab7655f24ecce3a5785d"
},
"src/components/track/MetadataStatusBadge.tsx": {
"mtime": 1781362703.9793344,
"ast_hash": "8a5d92baeb92cdca4e24a108d63c731c",
"semantic_hash": "8a5d92baeb92cdca4e24a108d63c731c"
},
"src/components/track/TrackContextMenu.tsx": {
"mtime": 1781350701.5742774,
"ast_hash": "16b3390b7a636355a65216c2f3ff49df",
"semantic_hash": "16b3390b7a636355a65216c2f3ff49df"
},
"src/components/track/TrackInfoDrawer.tsx": {
"mtime": 1781350701.5744607,
"ast_hash": "eefbf6535fdaa2e81282b3fe7c688838",
"semantic_hash": "eefbf6535fdaa2e81282b3fe7c688838"
},
"src/components/track/TrackRow.tsx": {
"mtime": 1781362726.8837554,
"ast_hash": "362f9199ea7a68a7a333fbc5e1a35b3f",
"semantic_hash": "362f9199ea7a68a7a333fbc5e1a35b3f"
},
"src/config/env.ts": {
"mtime": 1781089229.234595,
"ast_hash": "255749c27567fc4c4f21c2aababd6faf",
"semantic_hash": "255749c27567fc4c4f21c2aababd6faf"
},
"src/config/instances.ts": {
"mtime": 1781342201.2203667,
"ast_hash": "319d2771828bc8ed8fb6383504e5849a",
"semantic_hash": "319d2771828bc8ed8fb6383504e5849a"
},
"src/config/runtime-config.ts": {
"mtime": 1780742839.7051392,
"ast_hash": "e1909065e94221c77ed66947faa010d3",
"semantic_hash": "e1909065e94221c77ed66947faa010d3"
},
"src/env.d.ts": {
"mtime": 1781089221.6900594,
"ast_hash": "87ddb201366daf35733b75af45a13232",
"semantic_hash": "87ddb201366daf35733b75af45a13232"
},
"src/features/admin/AdminPage.tsx": {
"mtime": 1780840208.1682029,
"ast_hash": "02377143b2301db728ab1c473c200150",
"semantic_hash": "02377143b2301db728ab1c473c200150"
},
"src/features/admin/panels.tsx": {
"mtime": 1780840215.7528481,
"ast_hash": "7364b36ba1fb894dd5a0e7063291b41e",
"semantic_hash": "7364b36ba1fb894dd5a0e7063291b41e"
},
"src/features/album-detail/AlbumDetailPage.tsx": {
"mtime": 1781390834.0438523,
"ast_hash": "2889f02b289f59d0e2b36a6ff180e886",
"semantic_hash": "2889f02b289f59d0e2b36a6ff180e886"
},
"src/features/artist-detail/ArtistDetailPage.tsx": {
"mtime": 1781392507.2062988,
"ast_hash": "711c96dafa91cc72a2a22232b6899626",
"semantic_hash": "711c96dafa91cc72a2a22232b6899626"
},
"src/features/auth/LoginPage.tsx": {
"mtime": 1780840133.9210033,
"ast_hash": "c648cfdce2abb9a27440c5b43f68e26b",
"semantic_hash": "c648cfdce2abb9a27440c5b43f68e26b"
},
"src/features/connect/ConnectPage.tsx": {
"mtime": 1781344584.0354114,
"ast_hash": "6a19fd9cc4e60189b49da3af213c58e3",
"semantic_hash": "6a19fd9cc4e60189b49da3af213c58e3"
},
"src/features/downloads-manager/DownloadsManagerPage.tsx": {
"mtime": 1781433551.0477412,
"ast_hash": "00a41ce4b47f1cab8346beb0e856ceae",
"semantic_hash": "00a41ce4b47f1cab8346beb0e856ceae"
},
"src/features/library/LibraryPage.tsx": {
"mtime": 1781435365.4062083,
"ast_hash": "fbb3f1e63872a2f9545f7b1960d7a4f2",
"semantic_hash": "fbb3f1e63872a2f9545f7b1960d7a4f2"
},
"src/features/metadata-editor/MetadataEditorPage.tsx": {
"mtime": 1781433551.0746891,
"ast_hash": "dacb67348101f58dd1a16b8795ed3d02",
"semantic_hash": "dacb67348101f58dd1a16b8795ed3d02"
},
"src/features/not-found/NotFoundPage.tsx": {
"mtime": 1780840166.1056774,
"ast_hash": "09b39a683ecb7fda6b565134fc58136c",
"semantic_hash": "09b39a683ecb7fda6b565134fc58136c"
},
"src/features/playlist-detail/PlaylistDetailPage.tsx": {
"mtime": 1780744417.28553,
"ast_hash": "bcfab790914774618b17330545b0c0f2",
"semantic_hash": "bcfab790914774618b17330545b0c0f2"
},
"src/features/playlists/PlaylistsPage.tsx": {
"mtime": 1780840142.853842,
"ast_hash": "31b703075043bddd5981e10a8f1ddffc",
"semantic_hash": "31b703075043bddd5981e10a8f1ddffc"
},
"src/features/queue/QueuePage.tsx": {
"mtime": 1780840161.5585709,
"ast_hash": "507ae20653b6ca5d23ad7d1d755aeade",
"semantic_hash": "507ae20653b6ca5d23ad7d1d755aeade"
},
"src/features/search-download/SearchDownloadPage.tsx": {
"mtime": 1781433388.252379,
"ast_hash": "9afdde3660c182dfdb8c15c2266a1a9b",
"semantic_hash": "9afdde3660c182dfdb8c15c2266a1a9b"
},
"src/features/settings/SettingsPage.tsx": {
"mtime": 1780840190.3485467,
"ast_hash": "cca0656894cba16edbd61f1fa0c2d9b6",
"semantic_hash": "cca0656894cba16edbd61f1fa0c2d9b6"
},
"src/features/settings/panels.tsx": {
"mtime": 1781433551.1267753,
"ast_hash": "7c12484092cc2202ce440da97ca34eef",
"semantic_hash": "7c12484092cc2202ce440da97ca34eef"
},
"src/features/storage/StorageMaintenancePage.tsx": {
"mtime": 1780840156.6273057,
"ast_hash": "cbcfb070a469afedb58daf43bcebe02c",
"semantic_hash": "cbcfb070a469afedb58daf43bcebe02c"
},
"src/features/storage/StoragePage.tsx": {
"mtime": 1781433551.1520605,
"ast_hash": "533d4113a4c0664ebb2611fb14f5c83d",
"semantic_hash": "533d4113a4c0664ebb2611fb14f5c83d"
},
"src/features/upload/UploadPage.tsx": {
"mtime": 1781433551.1798227,
"ast_hash": "b799da4de3ffa08f26e6da2df91f88dd",
"semantic_hash": "b799da4de3ffa08f26e6da2df91f88dd"
},
"src/hooks/useAppDispatch.ts": {
"mtime": 1780742839.705766,
"ast_hash": "01b51fe3dcf8b7ef9f3ab71d652a6277",
"semantic_hash": "01b51fe3dcf8b7ef9f3ab71d652a6277"
},
"src/hooks/useAudioCacheStats.ts": {
"mtime": 1781391041.8071022,
"ast_hash": "a4d20a75f1709fc9eaa92f2547b1a31a",
"semantic_hash": "a4d20a75f1709fc9eaa92f2547b1a31a"
},
"src/hooks/useAudioPlayer.ts": {
"mtime": 1781363549.4061017,
"ast_hash": "f54ec87166b5c6905f6193d820e0ca09",
"semantic_hash": "f54ec87166b5c6905f6193d820e0ca09"
},
"src/hooks/useConnectionStatus.ts": {
"mtime": 1781362610.3297849,
"ast_hash": "ac96b7890c66b58102b1e61b9d57ec5a",
"semantic_hash": "ac96b7890c66b58102b1e61b9d57ec5a"
},
"src/hooks/usePermissions.ts": {
"mtime": 1780840239.2896512,
"ast_hash": "cb6b4fe5dfaf6ac97a506fd03dede6a2",
"semantic_hash": "cb6b4fe5dfaf6ac97a506fd03dede6a2"
},
"src/hooks/useResolvedQueueEntry.ts": {
"mtime": 1781363124.2042177,
"ast_hash": "8932c24652de1e417e43f720191dcde1",
"semantic_hash": "8932c24652de1e417e43f720191dcde1"
},
"src/hooks/useStreamCached.ts": {
"mtime": 1780849184.7098684,
"ast_hash": "0906f1ebda1f66fffdd5ea04281be6cd",
"semantic_hash": "0906f1ebda1f66fffdd5ea04281be6cd"
},
"src/i18n/index.ts": {
"mtime": 1780744225.4807925,
"ast_hash": "09623cf72109b5375c022a7292473e13",
"semantic_hash": "09623cf72109b5375c022a7292473e13"
},
"src/i18n/locales/en.ts": {
"mtime": 1781433551.223885,
"ast_hash": "d6a32b70b970986699f19da3d1b530f6",
"semantic_hash": "d6a32b70b970986699f19da3d1b530f6"
},
"src/i18n/locales/ru.ts": {
"mtime": 1781433537.109781,
"ast_hash": "7145f96bb8dc03d625dde777e686f592",
"semantic_hash": "7145f96bb8dc03d625dde777e686f592"
},
"src/index.tsx": {
"mtime": 1781433287.2843227,
"ast_hash": "c1d0c92110c1cd6ef402dd01207f5767",
"semantic_hash": "c1d0c92110c1cd6ef402dd01207f5767"
},
"src/lib/format.ts": {
"mtime": 1781388626.1215222,
"ast_hash": "c0155c5ab2a7a96d8a7c65c104091506",
"semantic_hash": "c0155c5ab2a7a96d8a7c65c104091506"
},
"src/lib/sw.ts": {
"mtime": 1780849392.1302223,
"ast_hash": "916cd2a816ff5211d5b3b1b82c1de6aa",
"semantic_hash": "916cd2a816ff5211d5b3b1b82c1de6aa"
},
"src/routes/ProtectedRoute.tsx": {
"mtime": 1780840232.9584267,
"ast_hash": "3bc21021d715b42380e9b0ce18fb0b43",
"semantic_hash": "3bc21021d715b42380e9b0ce18fb0b43"
},
"src/routes/index.tsx": {
"mtime": 1781433551.2662323,
"ast_hash": "e34c27ddae7d542ec08a67d855f4ec8a",
"semantic_hash": "e34c27ddae7d542ec08a67d855f4ec8a"
},
"src/store/index.ts": {
"mtime": 1781435611.149957,
"ast_hash": "c44bef4eea45292f198de7941a87b895",
"semantic_hash": "c44bef4eea45292f198de7941a87b895"
},
"src/store/persist.ts": {
"mtime": 1781363597.3444295,
"ast_hash": "87e431443d0ed2a50d580913018d4cf2",
"semantic_hash": "87e431443d0ed2a50d580913018d4cf2"
},
"src/store/rtkqPersist.ts": {
"mtime": 1781433551.2785244,
"ast_hash": "14b068de53293d00adf586f2e7f462df",
"semantic_hash": "14b068de53293d00adf586f2e7f462df"
},
"src/store/selectors/localLibrary.ts": {
"mtime": 1781390454.6929407,
"ast_hash": "7a2dadcb8f4619c53e809c0819fed852",
"semantic_hash": "7a2dadcb8f4619c53e809c0819fed852"
},
"src/store/slices/auth.ts": {
"mtime": 1780928353.9869554,
"ast_hash": "fea8f4acaafe4b07778ca4eb039d6abe",
"semantic_hash": "fea8f4acaafe4b07778ca4eb039d6abe"
},
"src/store/slices/connection.ts": {
"mtime": 1781362573.0296047,
"ast_hash": "8c969371d52301a742413f03ff960a20",
"semantic_hash": "8c969371d52301a742413f03ff960a20"
},
"src/store/slices/player.ts": {
"mtime": 1781363512.5178473,
"ast_hash": "6ec2c69affd8a207a8d415e687a95844",
"semantic_hash": "6ec2c69affd8a207a8d415e687a95844"
},
"src/store/slices/queue.ts": {
"mtime": 1781363498.45108,
"ast_hash": "dba3125d129f44a60c25dbfabee9ee3b",
"semantic_hash": "dba3125d129f44a60c25dbfabee9ee3b"
},
"src/store/slices/ui.ts": {
"mtime": 1781350701.576091,
"ast_hash": "c0b963a9a3faf57d1281a7e754750e5a",
"semantic_hash": "c0b963a9a3faf57d1281a7e754750e5a"
},
"tests/index.test.tsx": {
"mtime": 1780740461.5400229,
"ast_hash": "f43f07f852ccd126aa9e0c00fc651b73",
"semantic_hash": "f43f07f852ccd126aa9e0c00fc651b73"
},
"tests/localLibrary.test.ts": {
"mtime": 1781390654.28449,
"ast_hash": "6ca27a5af595b88a3e766b5e9cd90215",
"semantic_hash": "6ca27a5af595b88a3e766b5e9cd90215"
},
"tests/persist.test.ts": {
"mtime": 1780848156.6256914,
"ast_hash": "187909778a70beeac90847c4dedbbfd9",
"semantic_hash": "187909778a70beeac90847c4dedbbfd9"
},
"tests/rstest.setup.ts": {
"mtime": 1780740461.540069,
"ast_hash": "2198a0cc58ad237b620312de76d73885",
"semantic_hash": "2198a0cc58ad237b620312de76d73885"
},
"tests/rtkqPersist.test.ts": {
"mtime": 1781433551.3696778,
"ast_hash": "d6d0d1ba37e444c701ba707ac8613930",
"semantic_hash": "d6d0d1ba37e444c701ba707ac8613930"
},
"tests/sw-core.test.ts": {
"mtime": 1781433551.375921,
"ast_hash": "36a068e5a82fc98ef3c25d0d1b76539d",
"semantic_hash": "36a068e5a82fc98ef3c25d0d1b76539d"
},
"tests/tsconfig.json": {
"mtime": 1780740461.5401142,
"ast_hash": "b8e109114a44931d0562c4dff60a7f2e",
"semantic_hash": "b8e109114a44931d0562c4dff60a7f2e"
},
"tsconfig.json": {
"mtime": 1780740461.5401628,
"ast_hash": "812b31b8edae2e75dfe56eb1822ac09b",
"semantic_hash": "812b31b8edae2e75dfe56eb1822ac09b"
},
".agents/skills/rsbuild-best-practices/SKILL.md": {
"mtime": 1780740461.5272841,
"ast_hash": "295358a08c0371e49b880f531d56f809",
"semantic_hash": "295358a08c0371e49b880f531d56f809"
},
".agents/skills/vercel-react-best-practices/AGENTS.md": {
"mtime": 1780740461.5275803,
"ast_hash": "3f93774cb1920637a5fa65a62f484c0e",
"semantic_hash": "3f93774cb1920637a5fa65a62f484c0e"
},
".agents/skills/vercel-react-best-practices/README.md": {
"mtime": 1780740461.52767,
"ast_hash": "ab134f60d2472ba76e6ca04651d839d7",
"semantic_hash": "ab134f60d2472ba76e6ca04651d839d7"
},
".agents/skills/vercel-react-best-practices/SKILL.md": {
"mtime": 1780740461.52774,
"ast_hash": "e2c13e695d824979cf5ee29002cf47b5",
"semantic_hash": "e2c13e695d824979cf5ee29002cf47b5"
},
".agents/skills/vercel-react-best-practices/rules/_sections.md": {
"mtime": 1780740461.5278804,
"ast_hash": "b8c110b45145ded6919562772afe067c",
"semantic_hash": "b8c110b45145ded6919562772afe067c"
},
".agents/skills/vercel-react-best-practices/rules/_template.md": {
"mtime": 1780740461.527933,
"ast_hash": "ac0ea61ba765c4e9a0924625f594f95a",
"semantic_hash": "ac0ea61ba765c4e9a0924625f594f95a"
},
".agents/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md": {
"mtime": 1780740461.5279899,
"ast_hash": "bc4eba116a55f15398fc8e3c450de0c0",
"semantic_hash": "bc4eba116a55f15398fc8e3c450de0c0"
},
".agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md": {
"mtime": 1780740461.5280457,
"ast_hash": "82f932b2f8d9511e532d75ad39388883",
"semantic_hash": "82f932b2f8d9511e532d75ad39388883"
},
".agents/skills/vercel-react-best-practices/rules/advanced-init-once.md": {
"mtime": 1780740461.528102,
"ast_hash": "2edaa99e9be543cfd40356fa5f76317b",
"semantic_hash": "2edaa99e9be543cfd40356fa5f76317b"
},
".agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md": {
"mtime": 1780740461.5281532,
"ast_hash": "832e988ba07342d35529aae734eb246b",
"semantic_hash": "832e988ba07342d35529aae734eb246b"
},
".agents/skills/vercel-react-best-practices/rules/async-api-routes.md": {
"mtime": 1780740461.5282052,
"ast_hash": "caab96a1c2ae7ebe5dc649ed239e71c4",
"semantic_hash": "caab96a1c2ae7ebe5dc649ed239e71c4"
},
".agents/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md": {
"mtime": 1780740461.5282593,
"ast_hash": "8b8ea92ba516198c5ff3399ebac8bf23",
"semantic_hash": "8b8ea92ba516198c5ff3399ebac8bf23"
},
".agents/skills/vercel-react-best-practices/rules/async-defer-await.md": {
"mtime": 1780740461.5283144,
"ast_hash": "1f93c3b9aa12005993c8ec68fc405acd",
"semantic_hash": "1f93c3b9aa12005993c8ec68fc405acd"
},
".agents/skills/vercel-react-best-practices/rules/async-dependencies.md": {
"mtime": 1780740461.5283692,
"ast_hash": "0e0dd93e3a667910aea5b560a8eb7690",
"semantic_hash": "0e0dd93e3a667910aea5b560a8eb7690"
},
".agents/skills/vercel-react-best-practices/rules/async-parallel.md": {
"mtime": 1780740461.5284202,
"ast_hash": "38885405f093faecc11f7160ebca0a2b",
"semantic_hash": "38885405f093faecc11f7160ebca0a2b"
},
".agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md": {
"mtime": 1780740461.52847,
"ast_hash": "e690ced3af2a7b0f1fd810feac013123",
"semantic_hash": "e690ced3af2a7b0f1fd810feac013123"
},
".agents/skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md": {
"mtime": 1780740461.528522,
"ast_hash": "30aa6cf1b3e2d7bf7eb38c350d477194",
"semantic_hash": "30aa6cf1b3e2d7bf7eb38c350d477194"
},
".agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md": {
"mtime": 1780740461.5285776,
"ast_hash": "97672562bf8acdb9e17d1c2d761363dc",
"semantic_hash": "97672562bf8acdb9e17d1c2d761363dc"
},
".agents/skills/vercel-react-best-practices/rules/bundle-conditional.md": {
"mtime": 1780740461.5286324,
"ast_hash": "1bebc23825c873a4b54ef8a729720c6b",
"semantic_hash": "1bebc23825c873a4b54ef8a729720c6b"
},
".agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md": {
"mtime": 1780740461.5286818,
"ast_hash": "c414df99a61be1c89f4e0b7bc05c229f",
"semantic_hash": "c414df99a61be1c89f4e0b7bc05c229f"
},
".agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md": {
"mtime": 1780740461.5287342,
"ast_hash": "48bb315c7456e90d10cdb5eeb332659e",
"semantic_hash": "48bb315c7456e90d10cdb5eeb332659e"
},
".agents/skills/vercel-react-best-practices/rules/bundle-preload.md": {
"mtime": 1780740461.5287862,
"ast_hash": "ad1bc54e8a5ea07fb010e1a7ae9b8dce",
"semantic_hash": "ad1bc54e8a5ea07fb010e1a7ae9b8dce"
},
".agents/skills/vercel-react-best-practices/rules/client-event-listeners.md": {
"mtime": 1780740461.5288424,
"ast_hash": "af8fdb26e0e291b266bb294cd3587f7d",
"semantic_hash": "af8fdb26e0e291b266bb294cd3587f7d"
},
".agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md": {
"mtime": 1780740461.528895,
"ast_hash": "7868a754bc42cbff8ed8d3465d24050b",
"semantic_hash": "7868a754bc42cbff8ed8d3465d24050b"
},
".agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md": {
"mtime": 1780740461.5289454,
"ast_hash": "4fd2ad044b93dd1f669ce0406b320ca8",
"semantic_hash": "4fd2ad044b93dd1f669ce0406b320ca8"
},
".agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md": {
"mtime": 1780740461.5289955,
"ast_hash": "aa4aeb8bc2b309ef78e368e326fefa96",
"semantic_hash": "aa4aeb8bc2b309ef78e368e326fefa96"
},
".agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md": {
"mtime": 1780740461.5290527,
"ast_hash": "c1e78065ee6897ab78d4149e48915190",
"semantic_hash": "c1e78065ee6897ab78d4149e48915190"
},
".agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md": {
"mtime": 1780740461.529106,
"ast_hash": "4251d900efeb15295e26409b0c725ee9",
"semantic_hash": "4251d900efeb15295e26409b0c725ee9"
},
".agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md": {
"mtime": 1780740461.5291564,
"ast_hash": "5b3fe2fa28015b7ba1b43fb39fa7a550",
"semantic_hash": "5b3fe2fa28015b7ba1b43fb39fa7a550"
},
".agents/skills/vercel-react-best-practices/rules/js-cache-storage.md": {
"mtime": 1780740461.5292077,
"ast_hash": "0d7fde35f965aa8db78be230d4de0ef8",
"semantic_hash": "0d7fde35f965aa8db78be230d4de0ef8"
},
".agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md": {
"mtime": 1780740461.5292614,
"ast_hash": "f868963d9efd869de03d2078f5338b66",
"semantic_hash": "f868963d9efd869de03d2078f5338b66"
},
".agents/skills/vercel-react-best-practices/rules/js-early-exit.md": {
"mtime": 1780740461.5293126,
"ast_hash": "8d41edb70df7dbc5df339f1d7c1d9c4a",
"semantic_hash": "8d41edb70df7dbc5df339f1d7c1d9c4a"
},
".agents/skills/vercel-react-best-practices/rules/js-flatmap-filter.md": {
"mtime": 1780740461.529372,
"ast_hash": "167d42687f87a2309672b935d2d652d0",
"semantic_hash": "167d42687f87a2309672b935d2d652d0"
},
".agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md": {
"mtime": 1780740461.5294232,
"ast_hash": "d6a5b59ba77e299ec2dadf5485a2d982",
"semantic_hash": "d6a5b59ba77e299ec2dadf5485a2d982"
},
".agents/skills/vercel-react-best-practices/rules/js-index-maps.md": {
"mtime": 1780740461.5294714,
"ast_hash": "99bd5a72865b808077a6842b7c22d3f6",
"semantic_hash": "99bd5a72865b808077a6842b7c22d3f6"
},
".agents/skills/vercel-react-best-practices/rules/js-length-check-first.md": {
"mtime": 1780740461.5295289,
"ast_hash": "565de14e7d2bdf50583267312cfb6c25",
"semantic_hash": "565de14e7d2bdf50583267312cfb6c25"
},
".agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md": {
"mtime": 1780740461.5295827,
"ast_hash": "7f37e80bd122b4bc9346b247894a6214",
"semantic_hash": "7f37e80bd122b4bc9346b247894a6214"
},
".agents/skills/vercel-react-best-practices/rules/js-request-idle-callback.md": {
"mtime": 1780740461.529637,
"ast_hash": "08a60efc317a406845d45de398365740",
"semantic_hash": "08a60efc317a406845d45de398365740"
},
".agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md": {
"mtime": 1780740461.5296896,
"ast_hash": "59a278e21ecd322bff566ba4ad7f5a30",
"semantic_hash": "59a278e21ecd322bff566ba4ad7f5a30"
},
".agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md": {
"mtime": 1780740461.5297408,
"ast_hash": "2560982171602df0ba259d21e4f4b1dd",
"semantic_hash": "2560982171602df0ba259d21e4f4b1dd"
},
".agents/skills/vercel-react-best-practices/rules/rendering-activity.md": {
"mtime": 1780740461.5297914,
"ast_hash": "ff19f4a426c1b7c00fe581edd6a2bd21",
"semantic_hash": "ff19f4a426c1b7c00fe581edd6a2bd21"
},
".agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md": {
"mtime": 1780740461.5298462,
"ast_hash": "7ac842a5c4c6c80d4355fe2110d247d9",
"semantic_hash": "7ac842a5c4c6c80d4355fe2110d247d9"
},
".agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md": {
"mtime": 1780740461.5298955,
"ast_hash": "311d33cb3eb85bb893f58e6c98055fc0",
"semantic_hash": "311d33cb3eb85bb893f58e6c98055fc0"
},
".agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md": {
"mtime": 1780740461.529944,
"ast_hash": "335353568035b4ac5af9ed8074f8c8c6",
"semantic_hash": "335353568035b4ac5af9ed8074f8c8c6"
},
".agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md": {
"mtime": 1780740461.5299973,
"ast_hash": "5dfc5a123dd0261f4c24db07bf146235",
"semantic_hash": "5dfc5a123dd0261f4c24db07bf146235"
},
".agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md": {
"mtime": 1780740461.5300503,
"ast_hash": "88839ef89f5fc6aff046f6f1ad21f697",
"semantic_hash": "88839ef89f5fc6aff046f6f1ad21f697"
},
".agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md": {
"mtime": 1780740461.5301054,
"ast_hash": "eebd83589ee61f6ab8962d58ac38f916",
"semantic_hash": "eebd83589ee61f6ab8962d58ac38f916"
},
".agents/skills/vercel-react-best-practices/rules/rendering-resource-hints.md": {
"mtime": 1780740461.5301604,
"ast_hash": "92a96bf6ec53c3645d713984d5a39257",
"semantic_hash": "92a96bf6ec53c3645d713984d5a39257"
},
".agents/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md": {
"mtime": 1780740461.5302148,
"ast_hash": "c4783429dfbf91e4de0cb57f6714fc2e",
"semantic_hash": "c4783429dfbf91e4de0cb57f6714fc2e"
},
".agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md": {
"mtime": 1780740461.5302684,
"ast_hash": "1b880754ee449c52ccc725481f8b2e90",
"semantic_hash": "1b880754ee449c52ccc725481f8b2e90"
},
".agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md": {
"mtime": 1780740461.5303254,
"ast_hash": "fa96af4bfe8afef01e7663ca7937a367",
"semantic_hash": "fa96af4bfe8afef01e7663ca7937a367"
},
".agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md": {
"mtime": 1780740461.5303779,
"ast_hash": "38ff50416351805337e9acf15aedacb2",
"semantic_hash": "38ff50416351805337e9acf15aedacb2"
},
".agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md": {
"mtime": 1780740461.5304255,
"ast_hash": "9007f43373b0cfdfdcddc016e37f0f2c",
"semantic_hash": "9007f43373b0cfdfdcddc016e37f0f2c"
},
".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md": {
"mtime": 1780740461.5304766,
"ast_hash": "58a4c5e3fdd5e79d89606f05a1f4d708",
"semantic_hash": "58a4c5e3fdd5e79d89606f05a1f4d708"
},
".agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md": {
"mtime": 1780740461.5305269,
"ast_hash": "68cc11f5cd4076ca765de7223e5d14e8",
"semantic_hash": "68cc11f5cd4076ca765de7223e5d14e8"
},
".agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md": {
"mtime": 1780740461.530581,
"ast_hash": "3793531c8c782bb60e373bbefd00d61d",
"semantic_hash": "3793531c8c782bb60e373bbefd00d61d"
},
".agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md": {
"mtime": 1780740461.5306315,
"ast_hash": "67d9898513f6154b640334290aba6657",
"semantic_hash": "67d9898513f6154b640334290aba6657"
},
".agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md": {
"mtime": 1780740461.5306828,
"ast_hash": "5095f097d1023d89e5a5f0bab3fa6d06",
"semantic_hash": "5095f097d1023d89e5a5f0bab3fa6d06"
},
".agents/skills/vercel-react-best-practices/rules/rerender-memo.md": {
"mtime": 1780740461.530735,
"ast_hash": "fea28b1ed527b35da531068ac875e589",
"semantic_hash": "fea28b1ed527b35da531068ac875e589"
},
".agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md": {
"mtime": 1780740461.5307865,
"ast_hash": "1b5d4e53983e3cdd25c5b792e4756d14",
"semantic_hash": "1b5d4e53983e3cdd25c5b792e4756d14"
},
".agents/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md": {
"mtime": 1780740461.530839,
"ast_hash": "e27ab8ad9d063c72d328437efccfc85e",
"semantic_hash": "e27ab8ad9d063c72d328437efccfc85e"
},
".agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md": {
"mtime": 1780740461.5308893,
"ast_hash": "85d0163c5c8280b7fe1bf613c3387172",
"semantic_hash": "85d0163c5c8280b7fe1bf613c3387172"
},
".agents/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md": {
"mtime": 1780740461.530944,
"ast_hash": "421e30c6c28de9fa6dfc0b59f41ee644",
"semantic_hash": "421e30c6c28de9fa6dfc0b59f41ee644"
},
".agents/skills/vercel-react-best-practices/rules/rerender-transitions.md": {
"mtime": 1780740461.5309958,
"ast_hash": "67ae8a5c419121f554ffa965e03b43b7",
"semantic_hash": "67ae8a5c419121f554ffa965e03b43b7"
},
".agents/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md": {
"mtime": 1780740461.5310555,
"ast_hash": "3bae6bdc8c2ade4ba42cfa928abd2cfd",
"semantic_hash": "3bae6bdc8c2ade4ba42cfa928abd2cfd"
},
".agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md": {
"mtime": 1780740461.531113,
"ast_hash": "8dd6f94832748beb388520a0f0928ccc",
"semantic_hash": "8dd6f94832748beb388520a0f0928ccc"
},
".agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md": {
"mtime": 1780740461.531173,
"ast_hash": "228e10fd1ece87a4066aeffa552eb0d2",
"semantic_hash": "228e10fd1ece87a4066aeffa552eb0d2"
},
".agents/skills/vercel-react-best-practices/rules/server-auth-actions.md": {
"mtime": 1780740461.5312328,
"ast_hash": "019b0463634bfe055be734b13e0bfee7",
"semantic_hash": "019b0463634bfe055be734b13e0bfee7"
},
".agents/skills/vercel-react-best-practices/rules/server-cache-lru.md": {
"mtime": 1780740461.5312898,
"ast_hash": "5e0f52760cf7cbff72d5e687d6871467",
"semantic_hash": "5e0f52760cf7cbff72d5e687d6871467"
},
".agents/skills/vercel-react-best-practices/rules/server-cache-react.md": {
"mtime": 1780740461.5313435,
"ast_hash": "e7a5645f75212ad6f7cb84768b31fb47",
"semantic_hash": "e7a5645f75212ad6f7cb84768b31fb47"
},
".agents/skills/vercel-react-best-practices/rules/server-dedup-props.md": {
"mtime": 1780740461.5313966,
"ast_hash": "00bf8318431b2a60156ae3d50868f83f",
"semantic_hash": "00bf8318431b2a60156ae3d50868f83f"
},
".agents/skills/vercel-react-best-practices/rules/server-hoist-static-io.md": {
"mtime": 1780740461.5314653,
"ast_hash": "c38b0321fdeb522a17112da08238ab61",
"semantic_hash": "c38b0321fdeb522a17112da08238ab61"
},
".agents/skills/vercel-react-best-practices/rules/server-no-shared-module-state.md": {
"mtime": 1780740461.5315232,
"ast_hash": "e0f4144ba0064a960bd9d57ce73e8188",
"semantic_hash": "e0f4144ba0064a960bd9d57ce73e8188"
},
".agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md": {
"mtime": 1780740461.5315757,
"ast_hash": "e300bc3c962aed3a3ac9138323d036c1",
"semantic_hash": "e300bc3c962aed3a3ac9138323d036c1"
},
".agents/skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md": {
"mtime": 1780740461.531627,
"ast_hash": "4d9e89c30bbd2d96aa93b1ac82cb1a93",
"semantic_hash": "4d9e89c30bbd2d96aa93b1ac82cb1a93"
},
".agents/skills/vercel-react-best-practices/rules/server-serialization.md": {
"mtime": 1780740461.531783,
"ast_hash": "5b329f749544cf7e93c96b8e01ca0a39",
"semantic_hash": "5b329f749544cf7e93c96b8e01ca0a39"
},
".gitea/workflows/docker-publish.yml": {
"mtime": 1781433550.841841,
"ast_hash": "e558123d87f8a292c77ebe2cf036bda1",
"semantic_hash": "e558123d87f8a292c77ebe2cf036bda1"
},
"AGENTS.md": {
"mtime": 1780740461.532141,
"ast_hash": "314bb8b8e10fa99f4f21b1fff97f98d0",
"semantic_hash": "314bb8b8e10fa99f4f21b1fff97f98d0"
},
"CLAUDE.md": {
"mtime": 1780740461.5322187,
"ast_hash": "78b5cc73393e0c656f17ed627dddfad7",
"semantic_hash": "78b5cc73393e0c656f17ed627dddfad7"
},
"README.md": {
"mtime": 1780740461.5322802,
"ast_hash": "a738d2fe682269d45043ea6e5dedcc28",
"semantic_hash": "a738d2fe682269d45043ea6e5dedcc28"
},
"public/favicon.png": {
"mtime": 1780740461.5329168,
"ast_hash": "75387cbfcf23aabfb14aa6135d9683ec",
"semantic_hash": "75387cbfcf23aabfb14aa6135d9683ec"
}
}
+74 -5
View File
@@ -8,7 +8,10 @@
"name": "mcma-webui", "name": "mcma-webui",
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@olly/modern-sk": "^0.1.5", "@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@olly/modern-sk": "^0.1.6",
"@phosphor-icons/react": "^2.1.10", "@phosphor-icons/react": "^2.1.10",
"@reduxjs/toolkit": "^2.12.0", "@reduxjs/toolkit": "^2.12.0",
"i18next": "^26.3.1", "i18next": "^26.3.1",
@@ -16,7 +19,8 @@
"react-dom": "^19.2.6", "react-dom": "^19.2.6",
"react-i18next": "^17.0.8", "react-i18next": "^17.0.8",
"react-redux": "^9.3.0", "react-redux": "^9.3.0",
"react-router": "^7.16.0" "react-router": "^7.16.0",
"use-debounce": "^10.1.1"
}, },
"devDependencies": { "devDependencies": {
"@rsbuild/core": "^2.0.7", "@rsbuild/core": "^2.0.7",
@@ -551,6 +555,59 @@
"node": ">=6.9.0" "node": ">=6.9.0"
} }
}, },
"node_modules/@dnd-kit/accessibility": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
"integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
"license": "MIT",
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@dnd-kit/core": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
"integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
"license": "MIT",
"dependencies": {
"@dnd-kit/accessibility": "^3.1.1",
"@dnd-kit/utilities": "^3.2.2",
"tslib": "^2.0.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@dnd-kit/sortable": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/@dnd-kit/sortable/-/sortable-10.0.0.tgz",
"integrity": "sha512-+xqhmIIzvAYMGfBYYnbKuNicfSsk4RksY2XdmJhT+HAC01nix6fHCztU68jooFiMUB01Ky3F0FyOvhG/BZrWkg==",
"license": "MIT",
"dependencies": {
"@dnd-kit/utilities": "^3.2.2",
"tslib": "^2.0.0"
},
"peerDependencies": {
"@dnd-kit/core": "^6.3.0",
"react": ">=16.8.0"
}
},
"node_modules/@dnd-kit/utilities": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz",
"integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.0.0"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/@emnapi/core": { "node_modules/@emnapi/core": {
"version": "1.10.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
@@ -693,9 +750,9 @@
} }
}, },
"node_modules/@olly/modern-sk": { "node_modules/@olly/modern-sk": {
"version": "0.1.5", "version": "0.1.6",
"resolved": "https://git.ollyhearn.ru/api/packages/olly/npm/%40olly%2Fmodern-sk/-/0.1.5/modern-sk-0.1.5.tgz", "resolved": "https://git.ollyhearn.ru/api/packages/olly/npm/%40olly%2Fmodern-sk/-/0.1.6/modern-sk-0.1.6.tgz",
"integrity": "sha512-rhKp4U2IovSZkgdfg4oZqyhF0GgB8oR5TPlPXg0iYQEuEtff5zAgRXS+uY3dOPg2tStG3ysHUJaohD9YS2ADiA==", "integrity": "sha512-KDnIsi9wuAJu+hy4zHvuhKCRhUMLvN3+AYcmdayFKGYdYP1bSIwIQS3FZFtYeOzKW1FIKG7vEuhlyFwRA2/cdA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@phosphor-icons/react": "^2.1.10", "@phosphor-icons/react": "^2.1.10",
@@ -4469,6 +4526,18 @@
} }
} }
}, },
"node_modules/use-debounce": {
"version": "10.1.1",
"resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.1.1.tgz",
"integrity": "sha512-kvds8BHR2k28cFsxW8k3nc/tRga2rs1RHYCqmmGqb90MEeE++oALwzh2COiuBLO1/QXiOuShXoSN2ZpWnMmvuQ==",
"license": "MIT",
"engines": {
"node": ">= 16.0.0"
},
"peerDependencies": {
"react": "*"
}
},
"node_modules/use-sidecar": { "node_modules/use-sidecar": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
+6 -2
View File
@@ -13,7 +13,10 @@
"test:watch": "rstest --watch" "test:watch": "rstest --watch"
}, },
"dependencies": { "dependencies": {
"@olly/modern-sk": "^0.1.5", "@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@olly/modern-sk": "^0.1.6",
"@phosphor-icons/react": "^2.1.10", "@phosphor-icons/react": "^2.1.10",
"@reduxjs/toolkit": "^2.12.0", "@reduxjs/toolkit": "^2.12.0",
"i18next": "^26.3.1", "i18next": "^26.3.1",
@@ -21,7 +24,8 @@
"react-dom": "^19.2.6", "react-dom": "^19.2.6",
"react-i18next": "^17.0.8", "react-i18next": "^17.0.8",
"react-redux": "^9.3.0", "react-redux": "^9.3.0",
"react-router": "^7.16.0" "react-router": "^7.16.0",
"use-debounce": "^10.1.1"
}, },
"devDependencies": { "devDependencies": {
"@rsbuild/core": "^2.0.7", "@rsbuild/core": "^2.0.7",
+5 -2
View File
@@ -60,7 +60,9 @@ async function handleAudio(event) {
// 2) Cache miss → fetch the WHOLE file (strip Range) so we can store a // 2) Cache miss → fetch the WHOLE file (strip Range) so we can store a
// complete copy, then satisfy the original request (range-sliced if asked). // complete copy, then satisfy the original request (range-sliced if asked).
try { try {
const fullReq = new Request(req.url, { headers: withoutRange(req.headers) }); const fullReq = new Request(req.url, {
headers: withoutRange(req.headers),
});
const resp = await fetch(fullReq); const resp = await fetch(fullReq);
if (isCacheable(resp)) { if (isCacheable(resp)) {
event.waitUntil(storeInCache(key, resp.clone())); event.waitUntil(storeInCache(key, resp.clone()));
@@ -135,7 +137,8 @@ async function buildRangeResponse(response, rangeHeader) {
const buf = await response.clone().arrayBuffer(); const buf = await response.clone().arrayBuffer();
const size = buf.byteLength; const size = buf.byteLength;
const r = parseRangeHeader(rangeHeader, size); const r = parseRangeHeader(rangeHeader, size);
const type = response.headers.get('content-type') || 'application/octet-stream'; const type =
response.headers.get('content-type') || 'application/octet-stream';
if (!r) { if (!r) {
return new Response(buf, { return new Response(buf, {

Some files were not shown because too many files have changed in this diff Show More